2012-07-11 59 views
9

我想获得一个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. 

唯一合理的相关命中我也碰到过在我的努力,在谷歌上搜索,这是Copy Task - Illegal characters in path,但我已经使用<ItemGroup><CreateItem>例子(改编)根本没有工作,提前中止说错误,说TaskParameter是未知的(对不起,我没有在我面前的确切的错误信息)。

作为一种临时措施,我可以从构建输出目录手动复制相关文件到我想要的位置,但我希望该过程能够自动化。

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

+0

我没有直接的答案,但我也遇到过这个问题。我最终编写了一个PowerShell脚本来完成它,并将其称为后构建操作。此外,这个问题+1,因为它是令人印象深刻的研究。我期待着发布正确答案! – allquixotic 2012-07-11 14:42:51

回答

20

基本上,**是单路径元件并且因此必须在Include指令相应反斜杠分隔:

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

注指定例如之间的差$(SourceRoot)\**\*.aspx而不是破碎的$(SourceRoot)**\*.aspx。如果$(SourceRoot)\结束,通配符扩展可能最初也会起作用。

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

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

随着这些变化,它似乎工作,就像我希望它:文件拷贝到预定的目标目录,并在源目录结构保存在目标位置。

2

另一种建议是,不要为每个文件类型添加Includes,而是很容易添加Excludes。

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

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

+0

任何一种方法都可以工作,这取决于您的需求。在我的具体情况中,列举我想要复制的内容并简单地排除其他所有内容就显得更加容易。 – 2013-01-10 18:52:13

相关问题