MSBUILD:构建包含额外文件的软件包

10

最近一周,我一直在尝试实现这个解决方案:http://blog.samstephens.co.nz/2010-10-18/msbuild-including-extra-files-multiple-builds/。这个解决方案是基于Sayed的实现:http://sedodream.com/CommentView,guid,803d77d7-a220-4cee-a803-f6291cd4ba71.aspx(这个实现完美运行),然而我需要来自多个位置的文件,而Sayed的解决方案并没有考虑到这种情况。

理论上,Sam的解决方案正好满足我的需求,但是我无法构建它(即使仅复制并粘贴他的解决方案,并修改路径以反映我的环境)。 我已经因为以下错误头痛了几天:

[15:31:30]: [CopyPipelineFiles] C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852, 5): error MSB4018: The "CopyPipelineFiles" task failed unexpectedly.  
System.ArgumentException: Illegal characters in path.  
at System.IO.Path.CheckInvalidPathChars(String path) at System.IO.Path.Combine(String path1, String path2)  
at Microsoft.Web.Publishing.Tasks.CopyPipelineFiles.CopyPipelineFilesToFolder(TaskLoggingHelper log, ITaskItem[] allpipeLineItems, String sourceFolderName, String targetFolderName, ItemMetadataFilter itemMetadataSkipFilter, Boolean fUpdateItemSpec, Boolean deleteItemsMarkAsExcludeTrue, List`1 updatedPipeLineItems, List`1 failedPipeLineItems)  
at Microsoft.Web.Publishing.Tasks.CopyPipelineFiles.Execute()  
at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() 
at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult)    
[15:31:31]: Process exited with code 1  
[15:31:31]: MSBuild output:  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: The "CopyPipelineFiles" task failed unexpectedly. [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: System.ArgumentException: Illegal characters in path. [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at System.IO.Path.CheckInvalidPathChars(String path) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at System.IO.Path.Combine(String path1, String path2) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Web.Publishing.Tasks.CopyPipelineFiles.CopyPipelineFilesToFolder(TaskLoggingHelper log, ITaskItem[] allpipeLineItems, String sourceFolderName, String targetFolderName, ItemMetadataFilter itemMetadataSkipFilter, Boolean fUpdateItemSpec, Boolean deleteItemsMarkAsExcludeTrue, List`1 updatedPipeLineItems, List`1 failedPipeLineItems) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Web.Publishing.Tasks.CopyPipelineFiles.Execute() [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: Done Building Project "<PATH_TO>\MYPROJ.csproj" (Package target(s)) -- FAILED.  
[15:31:31]: Done Building Project "C:\buildAgent\work\8aa6ae640d0f858b\main\scripts\MYPROJ.csproj" (BatchCopyPackage target(s)) -- FAILED.  
[15:31:31]: Build FAILED.  
[15:31:31]: "C:\buildAgent\work\8aa6ae640d0f858b\main\scripts\MYPROJ.csproj" (BatchCopyPackage target) (1) ->  
[15:31:31]: "<PATH_TO>\MYPROJ.csproj" (Package target) (2) ->  
[15:31:31]: (CopyAllFilesToSingleFolderForPackage target) ->  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: The "CopyPipelineFiles" task failed unexpectedly. [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: System.ArgumentException: Illegal characters in path. [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at System.IO.Path.CheckInvalidPathChars(String path) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at System.IO.Path.Combine(String path1, String path2) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Web.Publishing.Tasks.CopyPipelineFiles.CopyPipelineFilesToFolder(TaskLoggingHelper log, ITaskItem[] allpipeLineItems, String sourceFolderName, String targetFolderName, ItemMetadataFilter itemMetadataSkipFilter, Boolean fUpdateItemSpec, Boolean deleteItemsMarkAsExcludeTrue, List`1 updatedPipeLineItems, List`1 failedPipeLineItems) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Web.Publishing.Tasks.CopyPipelineFiles.Execute() [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult) [<PATH_TO>\MYPROJ.csproj]  
[15:31:31]: 0 Warning(s)  
[15:31:31]: 1 Error(s)  
[15:31:31]: Time Elapsed 00:00:23.00  

这是我对Sam的目标的实现:

<Target Name="DefineCustomFiles">
    <ItemGroup>
      <CustomFilesToInclude Include="$(workingDir)\main\img\**\*">
        <Dir>img</Dir>
      </CustomFilesToInclude>
      <CustomFilesToInclude Include="$(workingDir)\main\Service References\**\*">
        <Dir>ServiceReferences</Dir>
      </CustomFilesToInclude>
    </ItemGroup>
</Target>

<Target Name="CustomCollectFiles">
  <Message Text="Here is a file list: %(CustomFilesToInclude.Identity)" />
    <ItemGroup>
      <FilesForPackagingFromProject Include="@(CustomFilesToInclude)">
        <DestinationRelativePath>
          %(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)
        </DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
</Target>

我认为这可能与空格(或通配符)有关,所以这是我尝试过的:

  • 使用“详细”和“诊断”日志记录级别检查日志

  • 混合使用双引号和单引号的各种表现形式

  • 注释掉“服务引用”节点。(包含图像的路径没有空格)

  • 指向绝对路径的单个文件。因此消除了通配符和由路径包含空格而导致的错误。我确信这将解决问题,但它失败并出现了以上相同的错误。

在第3个问题之后,我完全不知所措。它似乎不喜欢传递给它的任何文件。

任何见解将非常感谢。提前致谢。

这是我的目标当前的外观和相应的错误消息:

<Target Name="DefineCustomFiles">
    <ItemGroup>
      <CustomFilesToInclude Include="$(workingDir)\main\img\file.gif">
        <Dir>img</Dir>
      </CustomFilesToInclude>
    </ItemGroup>
</Target>

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets(1852, 5): error MSB4018: The "CopyPipelineFiles" task failed unexpectedly.  
System.ArgumentException: Illegal characters in path.

2
您可以在打开诊断日志的情况下调用msbuild,然后检查它构建ItemGroup中文件列表的位置周围的日志。这可能会指向问题所在。 - seva titov
嗨Seva,谢谢。我可能应该在我的帖子中包含一些诊断详细信息。(我已经相应地编辑了帖子)。不幸的是,诊断日志没有揭示任何澄清,除了详细日志已经暴露的内容。 - Padawan Learner
在您的日志中,我看到<PATH_TO>作为您项目的一部分。如果这不是手动编辑,我确信<和>不允许用于完整路径到项目。 - Alois Kraus
是的。"<PATH_TO>" 是故意手动编辑的。在实际文件中,路径是合法的。 - Padawan Learner
4个回答

7
我找到了您的问题,恐怕是我的错。问题在于在FilesForPackagingFromProjectDestinationRelativePath元素中,空格是有意义的。我在博客文章中添加了空格,以使XML更易于阅读,但没有意识到这会导致代码失败。

因此,如果您尝试

<Target Name="CustomCollectFiles">
  <Message Text="Here is a file list: %(CustomFilesToInclude.Identity)" />
    <ItemGroup>
      <FilesForPackagingFromProject Include="@(CustomFilesToInclude)">
        <DestinationRelativePath>%(CustomFilesToInclude.Dir)\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
      </FilesForPackagingFromProject>
    </ItemGroup>
</Target>

您的问题应该已经解决了。我更新了博客文章,删除了有问题的空格。

请注意,正如Scott Stafford在下面的评论中指出的那样,在Visual Studio 2012中,CopyAllFilesToSingleFolderForPackageDependsOn已更名为CopyAllFilesToSingleFolderForMsdeployDependsOn。


Sam,这立刻解决了问题。非常感谢你,谢谢,再次感谢你!你是救星! - Padawan Learner
1
注意:在VS2012中,关键目标是CopyAllFilesToSingleFolderForMsdeployDependsOn。 - Scott Stafford

3
我遇到了一个类似这样的问题,目标类似于 Saustrup 回答中的建议。
在我的情况下,问题实际上是我的目标过晚运行,所以在应用程序构建、打包和部署之后才创建文件。这是因为我使用 BeforeTargets="Build" 运行我的目标。我在回答一个更相关的问题时详细介绍了这个问题(在解决问题之后才找到)这里

3

这个在Visual Studio 2013 for Web中有效:

<Target Name="BeforeBuild">
  <ItemGroup>
    <Content Include="bin\**" Exclude="**/.git*" />
    <Content Include=".\Global.asax" />
    <Content Include=".\umbraco\**" />
    <Content Include=".\usercontrols\**" />
    <Content Include=".\umbraco_client\**" />
    <Content Include=".\App_Code\**" />
    <Content Include=".\App_Plugins\**" />
    <Content Include=".\App_Data\*-*-*-*-*\**" />
    <Content Include=".\App_Data\packages\**" />
    <Content Include=".\App_Data\access.*" />
    <Content Include=".\Views\**" />
    <Content Include=".\App_Browsers\**" />
    <Content Include=".\uSync\**" />
    <Content Include=".\media\**" />
  </ItemGroup>
</Target>

这个具体的例子是来自一个Umbraco 4项目。

0

正如您所指出的那样,MSBuild确实存在空格问题。您尝试过添加双斜杠吗:

"$(workingDir)\\main\\Service References\\**\\*"

嗨,本,谢谢。我还没有尝试过那个。我刚刚尝试了一下,不幸的是它在同样的错误上失败了。请记住,此时我引用的是一个绝对路径,我确定它没有空格。 - Padawan Learner
嗯,你有没有看到Alois在之前的回答中关于"<PATH_TO>\MYPROJ.csproj"路径的评论? - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接