10

我正在尝试让 MSBuild 脚本用于构建和提取以部署相当大的 Web 应用程序。(我们在这里谈论的是几十个目录中的几千个文件。它几乎是一个继承的遗留代码库,所以我无能为力。)构建本身运行良好,但我似乎无法复制文件到放置位置正常工作。

这是一个片段,显示了我在构建脚本中的内容:

<PropertyGroup Condition=" '$(UseBuildNumber)' == 'true' ">
  <ReleaseDirectory>$(ReleaseBaseDirectory)$(ReleaseName)\$(BuildNumber)</ReleaseDirectory>
</PropertyGroup>

<ItemGroup>
  <OutputFiles Include="
               $(SourceRoot)**\*.aspx;
               $(SourceRoot)**\*.dll;
               $(SourceRoot)**\*.gif;
               $(SourceRoot)**\*.ascx;
               " />
</ItemGroup>

<Message Text="Output files ==> @(OutputFiles)" />

<Copy
    SourceFiles="@(OutputFiles)"
    DestinationFolder="$(ReleaseDirectory)"
    SkipUnchangedFiles="false"
    />

我在那里放了一些额外<Message/>的东西来验证各个路径是否正确扩展,并且两者$(SourceRoot)确实$(ReleaseDirectory)都有正确的路径。但是,在输出中,我得到(为简洁起见省略了完整路径):

Task "Message"
  Output files ==> ...\Requirement1866**\*.aspx;...\Requirement1866**\*.dll;...\Requirement1866**\*.gif;...\Requirement1866**\*.ascx
Done executing task "Message".

显然,没有执行通配符扩展,Copy然后(可以预见)以下失败。我只包括一个;实际上,每个文件名通配符模式都会重复此操作(这又比我在上面的构建脚本片段中包含的要多得多)。

Using "Copy" task from assembly "Microsoft.Build.Tasks.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "Copy"
  Copying file from "*basedir*\Requirement1866**\*.aspx" to "*targetdir*\Requirement1866\*buildnumber*\*.aspx".
  Command:
  copy /y "*basedir*\Requirement1866**\*.aspx" "*targetdir*\Requirement1866\*buildnumber*\*.aspx"
d:\Builds\215\BuildType\TFSBuild.proj(120,5): error MSB3021: Unable to copy file "*basedir*\Requirement1866**\*.aspx" to "*targetdir*\Requirement1866\*buildnumber*\*.aspx". Illegal characters in path.

其次是:

  d:\Builds\215\BuildType\TFSBuild.proj(120,5): error MSB3021: Unable to copy file "*basedir*\Requirement1866**\*.aspx" to "*targetdir*\Requirement1866\*buildnumber*\*.aspx". Illegal characters in path.

我在谷歌搜索过程中遇到的唯一合理相关的打击是复制任务 - 路径中的非法字符,但我已经在使用<ItemGroup>,并且<CreateItem>示例(改编)根本不起作用,提前中止并出现错误说这TaskParameter是未知的(对不起,我面前没有确切的错误信息)。

作为权宜之计,我可以进入并手动将相关文件从构建输出目录复制到我想要的位置,但我希望该过程能够自动化。

那么,如何使用 MSBuild 将构建过程中创建的文件复制到输出目录中,同时保留相对目录结构,而不是一一列出?

4

2 回答 2

22

基本上,**是单个路径元素,因此必须在Include指令中相应地用反斜杠分隔:

<ItemGroup>
  <OutputFiles Include="
               $(SourceRoot)\**\*.aspx;
               $(SourceRoot)\**\*.dll;
               $(SourceRoot)\**\*.gif;
               $(SourceRoot)\**\*.ascx;
               " />
</ItemGroup>

$(SourceRoot)\**\*.aspx请注意指定 eg与指定 broken之间的区别$(SourceRoot)**\*.aspx。如果$(SourceRoot)\, 通配符扩展结束,一开始可能也会起作用。

其次,在 中<Copy/>,使用%(RecursiveDir)

<Copy
    SourceFiles="@(OutputFiles)"
    DestinationFolder="$(ReleaseDirectory)\%(RecursiveDir)"
    SkipUnchangedFiles="false"
    />

通过这些更改,它看起来就像我想要的那样工作:文件被复制到预期的目标目录,并且源目录结构保留在目标位置。

于 2012-07-12T09:58:56.780 回答
2

另一个建议,不是为每个文件类型添加包含,而是很容易添加排除。

<ItemGroup>
  <OutputFiles Include="$(SourceRoot)**\*.*" Exclude="$(SourceRoot)**\*.cs;$(SourceRoot)**\*.resx" " />
</ItemGroup>

这样,输出将包括任何所需的 JS、HTML、DHTML 和其他文件类型。

于 2013-01-10T15:58:04.827 回答