如何选择要在msbuild中复制的文件并保留目录结构?

如何选择要在msbuild中复制的文件并保留目录结构?,msbuild,Msbuild,我有一个web应用程序,我正在使用steal编译,然后我只想从中复制生产使用所需的文件,但我需要保留目录结构。例如,在运行steal的构建(将js/css编译成production.js/css文件)后,目录如下所示: 因此,我只想将几个特定文件复制到相同的目录结构: \artifacts\staging\www\index.html \artifacts\staging\www\app\img\a.png \artifacts\staging\www\app\img\b.png \artif

我有一个web应用程序,我正在使用steal编译,然后我只想从中复制生产使用所需的文件,但我需要保留目录结构。例如,在运行steal的构建(将js/css编译成production.js/css文件)后,目录如下所示:

因此,我只想将几个特定文件复制到相同的目录结构:

\artifacts\staging\www\index.html
\artifacts\staging\www\app\img\a.png 
\artifacts\staging\www\app\img\b.png
\artifacts\staging\www\app\production.js
\artifacts\staging\www\app\production.css
\artifacts\staging\www\steal\steal.js

理想情况下,我会有这样的东西:

<PropertyGroup>
  <WorkingDir>WebApp\</WorkingDir> 
  <OutputDir>artifacts\staging\www\</OutputDir>
</PropertyGroup>

...

<ItemGroup>
  <CopyFiles Remove="@(CopyFiles)" /> <!-- clean existing items -->
  <CopyFiles Condition="'$(Configuration)'=='Debug'"
        Include="$(WorkingDir)\**\*.*" 
        Exclude="$(WorkingDir)\**\.svn\**" />
  <CopyFiles Condition="'$(Configuration)'=='Release'"
        Include="$(WorkingDir)\index.html;$(WorkingDir)\app\img\**\*.*;$(WorkingDir)\app\production.*;$(WorkingDir)\steal\steal.js;" 
        Exclude="$(WorkingDir)\**\.svn\**" />
</ItemGroup>

<Copy SourceFiles="@(CopyFiles)" 
    DestinationFolder="@(CopyFiles->'$(OutputDir)\%(RecursiveDir)%(Filename)%(Extension)')" />

您能否稍微颠倒一下逻辑,使用
**
包含所有内容,然后排除不需要的文件:

  <CopyFiles Condition="'$(Configuration)'=='Debug'"
        Include="$(WorkingDir)\**\*.*" 
        Exclude="$(WorkingDir)\**\.svn\**" />
  <CopyFiles Condition="'$(Configuration)'=='Release'"
        Include="$(WorkingDir)\**\*.*" 
        Exclude="$(WorkingDir)\**\.svn\**;$(WorkingDir)\app\css\*.*;$(WorkingDir)\app\js\*.*;$(WorkingDir)\steal\README.md;$(WorkingDir)\steal\build\*.*" />


然后您可以使用
$(RecursiveDir)
属性。

我也遇到了同样的问题,经过一番努力,我终于做到了。关键是在“**”之后指定要包括的文件夹


...
因此,输出目录将包含包含所有“img”子目录的应用程序文件夹,以及所有名为“production”的文件


请注意,带有“RecursiveDir”的部分保持不变。

只是为了添加到pot中

您还可以使用“排除某些文件”策略

下面将获得所有*.txt和*.doc文件…但也排除特定名称的文件

问题是……您是否对包含某些文件更感兴趣……还是……排除某些文件更感兴趣

这两个“把戏”都是时不时需要的

<ItemGroup>
    <MyExcludeFiles Include="$(WorkingDir)\**\SuperSecretStuff.txt" />
    <MyExcludeFiles Include="$(WorkingDir)\**\SuperSecretStuff.doc" />
</ItemGroup>

<ItemGroup>
    <MyIncludeFiles Include="$(WorkingDir)\**\*.txt" Exclude="@(MyExcludeFiles)"/>
    <MyIncludeFiles Include="$(WorkingDir)\**\*.doc" Exclude="@(MyExcludeFiles)"/>
</ItemGroup>        


<Copy
SourceFiles="@(MyIncludeFiles)"
DestinationFiles="@(MyIncludeFiles->'$(OutputDir)\%(RecursiveDir)%(Filename)%(Extension)')"
/>  

正确。通过向上移动“**”到较早的位置,递归目录最终将是正确的。很好的警告!为了将来的可读性,我更喜欢“逐行”定义,而不是分号分隔的列表。
  <CopyFiles Condition="'$(Configuration)'=='Debug'"
        Include="$(WorkingDir)\**\*.*" 
        Exclude="$(WorkingDir)\**\.svn\**" />
  <CopyFiles Condition="'$(Configuration)'=='Release'"
        Include="$(WorkingDir)\**\*.*" 
        Exclude="$(WorkingDir)\**\.svn\**;$(WorkingDir)\app\css\*.*;$(WorkingDir)\app\js\*.*;$(WorkingDir)\steal\README.md;$(WorkingDir)\steal\build\*.*" />
<ItemGroup>
    <CopyFiles Include="$(WorkingDir)\index.html" />
    <CopyFiles Include="$(WorkingDir)\**\app\img\**\*.*" />
    <CopyFiles Include="$(WorkingDir)\**\app\production.*" />
    ...
</ItemGroup>
<ItemGroup>
    <MyExcludeFiles Include="$(WorkingDir)\**\SuperSecretStuff.txt" />
    <MyExcludeFiles Include="$(WorkingDir)\**\SuperSecretStuff.doc" />
</ItemGroup>

<ItemGroup>
    <MyIncludeFiles Include="$(WorkingDir)\**\*.txt" Exclude="@(MyExcludeFiles)"/>
    <MyIncludeFiles Include="$(WorkingDir)\**\*.doc" Exclude="@(MyExcludeFiles)"/>
</ItemGroup>        


<Copy
SourceFiles="@(MyIncludeFiles)"
DestinationFiles="@(MyIncludeFiles->'$(OutputDir)\%(RecursiveDir)%(Filename)%(Extension)')"
/>