MSbuild复制整个文件夹

Son*_*oul 37 .net msbuild visual-studio

试图复制整个文件夹,但是当我这样做时:

<Copy SourceFiles="$(TargetDir)\*.*" DestinationFolder="$(BuildOutput)\SomeDir" />
Run Code Online (Sandbox Code Playgroud)

副本尝试执行此操作:复制c:\ source\*.*c:\ destination\SomeDir\*.* 并失败并显示"非法字符"

Bri*_*ler 63

明确指定SourceFiles的ItemGroup.

<ItemGroup>
    <_CopyItems Include="$(TargetDir)\*.*" />
</ItemGroup>
<Copy
    SourceFiles="@(_CopyItems)"
    DestinationFolder="$(BuildOutput)\SomeDir"
    />
Run Code Online (Sandbox Code Playgroud)

请注意_CopyItems是一种项类型,因此使用'@'符号而不是'$'引用它.

  • 最好将"<InProject> false </ InProject>"添加到项目组,否则您将在解决方案资源管理器中看到所有bin文件夹内容.`<ItemGroup> <_CopyItems Include ="$(TargetDir)*.*"> <InProject> false </ InProject> </ _ CopyItems> </ ItemGroup> (10认同)

Sia*_*huk 31

可以使用以下代码片段来复制文件,该代码片段用于处理防病毒程序和子目录

  <ItemGroup>
        <SomeAppStuff Include="$(SolutionDir)\ProjectXXX\bins\**\*.*" />
  </ItemGroup>
  <Copy 
      SourceFiles="@(SomeAppStaff)" 
      DestinationFolder="$(OutputPath)\%(RecursiveDir)" 
      SkipUnchangedFiles="true"
      OverwriteReadOnlyFiles="true" 
      Retries="3"
      RetryDelayMilliseconds="300"/>
Run Code Online (Sandbox Code Playgroud)

指定$(OutputPath)\%(RecursiveDir)将要求复制任务遵守子文件夹,因此它会将源目录的子文件夹放在目标目录的子文件夹中.

SkipUnchangedFiles 将在具有足够内存的计算机上提高构建速度,因为当RAM足够时,Windows会优化常用文件的IO.

RetriesRetryDelayMilliseconds处理相关问题a)压缩的NTFS文件系统,当构建在很少情况下失败时b)带有SSD驱动器的防病毒软件.


小智 14

查看MSDN文档,我相信SourceFiles参数需要ITaskItem []值.请参阅MSDN MSBuild复制任务

上面链接的最后一个示例是从一个目录到另一个目录执行递归复制,维护文件夹结构.


小智 10

如果将文件夹放在c#项目的根目录中,则可以简单地将其放在csproj中。

<ItemGroup>
    <None Update="FolderToCopy\**\*.*">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)

我仅在2017年版的csproj中进行了测试,但我认为它是向后兼容的。虽然可能是错误的


Ric*_*ues 8

对我来说有效的是: - 保留文件夹结构 - 复制文件夹内的所有文件 - 适用于任何文件夹,不必位于项目或同一项目文件夹中

<ItemGroup>
    <_CopyItems Include="<path relative to project>\**\*.*" />
</ItemGroup>

<Target Name="AfterBuild">
  <Copy SourceFiles="@(_CopyItems)" DestinationFiles="@(_CopyItems->'$(OutDir)\<output folder>\%(RecursiveDir)%(Filename)%(Extension)')"/>
</Target>
Run Code Online (Sandbox Code Playgroud)

传奇:

  • <path relative to project>:这可以是任何路径,使用 ..\ 进入 proj 文件夹上方即可
  • <output folder>:您想要将整个文件结构放入其中的文件夹,不包括源文件夹。
  • $(OutDir)将是 bin\Debug 或您拥有的任何构建模式,如果您想要其他模式,请更改它。


Art*_*hur 7

成功完成了这样的任务

<Target Name="AfterBuild">
  <ItemGroup>
    <SomeDir Include="$(SolutionDir)\SomeOtherProject\SomeDir\**\*" />
  </ItemGroup>
  <Copy 
    SourceFiles="@(SomeDir)" 
    DestinationFiles="@(SomeDir->'$(OutDir)\SomeDir\%(RecursiveDir)%(Filename)%(Extension)')" 
    SkipUnchangedFiles="true" 
    OverwriteReadOnlyFiles="true" 
    Retries="3" 
    RetryDelayMilliseconds="300" />
Run Code Online (Sandbox Code Playgroud)