[英]MSBuild: copy whole folder
试图复制整个文件夹,但是当我这样做时:
<Copy SourceFiles="$(TargetDir)\*.*" DestinationFolder="$(BuildOutput)\SomeDir" />
该副本尝试执行此操作:复制 c:\source\ 。 c:\目的地\SomeDir\ 。 并因illegal characters
错误而失败
明确指定 SourceFiles 的 ItemGroup。
<ItemGroup>
<_CopyItems Include="$(TargetDir)\*.*" />
</ItemGroup>
<Copy
SourceFiles="@(_CopyItems)"
DestinationFolder="$(BuildOutput)\SomeDir"
/>
请注意,_CopyItems 是一种项目类型,因此使用“@”符号而不是“$”来引用它。
可以使用以下处理防病毒程序和子目录的代码片段来复制文件
<ItemGroup>
<SomeAppStuff Include="$(SolutionDir)\ProjectXXX\bins\**\*.*" />
</ItemGroup>
<Copy
SourceFiles="@(SomeAppStaff)"
DestinationFolder="$(OutputPath)\%(RecursiveDir)"
SkipUnchangedFiles="true"
OverwriteReadOnlyFiles="true"
Retries="3"
RetryDelayMilliseconds="300"/>
指定$(OutputPath)\\%(RecursiveDir)
将要求复制任务尊重子文件夹,因此它将源目录的子文件夹放置到目标目录的子文件夹中。
SkipUnchangedFiles
将在具有足够内存的计算机上提高构建速度,因为当有足够的 RAM 时,Windows 会优化常用文件的 IO。
Retries
和RetryDelayMilliseconds
处理相关问题 a) 压缩 NTFS 文件系统,当构建在RetryDelayMilliseconds
情况下失败 b) 带有 SSD 驱动器的防病毒软件。
如果您将该文件夹放在 c# 项目的根目录中,那么您可以简单地将它放在您的 csproj 中。
<ItemGroup>
<None Update="FolderToCopy\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
我只在 2017 版的 csproj 中进行了测试,但我认为它是向后兼容的。 虽然可能是错的
查看 MSDN 文档,我相信 SourceFiles 参数需要 ITaskItem[] 值。 请参阅MSDN MSBuild 复制任务
上面链接的最后一个例子是从一个目录到另一个目录进行递归复制,保持文件夹结构。
成功完成了这样的任务
<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" />
对我来说,有效的是: - 保留文件夹结构 - 复制文件夹中的所有文件 - 适用于任何文件夹,不必在项目或同一个项目文件夹中
<ItemGroup>
<_CopyItems Include="<path relative to project>\**\*.*" />
</ItemGroup>
<Target Name="AfterBuild">
<Copy SourceFiles="@(_CopyItems)" DestinationFiles="@(_CopyItems->'$(OutDir)\<output folder>\%(RecursiveDir)%(Filename)%(Extension)')"/>
</Target>
传奇:
<path relative to project>
:这可以是任何路径,使用 ..\\ 在 proj 文件夹上方工作<output folder>
:您希望将整个文件结构放入的文件夹,不包括源文件夹。$(OutDir)
将是 bin\\Debug 或您拥有的任何构建模式,如果您想要其他东西,请更改它。在 Visual Studio 15.4+ 中,有一个功能可以使这更容易——您可以设置LinkBase
或Link
来控制目标路径:
<ItemGroup>
<Content Include="FolderToCopy\**" LinkBase="FolderInOutput\" CopyToOutputDirectory="Always" />
</ItemGroup>
来源: https://github.com/do.net/msbuild/issues/2949#issuecomment-362823310
对我来说最好的解决方案是使用神奇的XCOPY
因为我必须复制所有文件和子目录
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<PropertyGroup>
<FilesSource>$(ProjectDir)\lib</FilesSource>
<FilesDestination Condition=" '$(SolutionName)' == 'any name a' ">$(ProjectDir)\..\..\Something\lib</FilesDestination>
<FilesDestination Condition=" '$(SolutionName)' == 'the top solution name' ">$(SolutionDir)\Something\lib</FilesDestination>
</PropertyGroup>
<Error Condition=" '$(FilesDestination)' == '' " Text="Lib not delivered. To disable this message, remove the 'Target' tag from the project file" />
<Exec Command="RD /S /Q "$(FilesDestination)"" />
<Exec Command="XCOPY "$(FilesSource)" "$(FilesDestination)" /E /I /H /R /K /Y" />
<Exec Command="RD /S /Q "$(FilesSource)"" />
</Target>
一旦构建成功,就会触发此构建事件,它会清除FilesDestination
文件夹,然后将具有目录结构的所有文件从FilesSource
到FilesDestination
,然后删除FilesSource
文件夹以保留所有内容“bien propre”:)
笔记
对于FilesDestination
,请确保使用Condition属性或将其删除以使复制过程结束
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.