使用 msbuild 复制所有文件和文件夹

只是想知道是否有人可以帮助我写一些我正在尝试编写的 MSbuild 脚本。我想做的是复制所有的文件和子文件夹从一个文件夹到另一个文件夹使用 msbuild。

{ProjectName}
|----->Source
|----->Tools
|----->Viewer
|-----{about 5 sub dirs}

我需要能够做的是复制所有的文件和子文件夹从工具文件夹到应用程序的调试文件夹。这是我目前掌握的密码。

<ItemGroup>
<Viewer Include="..\$(ApplicationDirectory)\Tools\viewer\**\*.*" />
</ItemGroup>


<Target Name="BeforeBuild">
<Copy SourceFiles="@(Viewer)" DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" />
</Target>

生成脚本运行,但不复制任何文件或文件夹。

谢谢

111780 次浏览

是否尝试指定具体的目标目录而不是

DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" ?

我不太熟悉高级 MSBuild 语法,但是

@(Viewer->'$(OutputPath)\\Tools')

脚本看起来不错,所以问题可能出在 $(ApplicationDirectory)$(OutputPath)的值上

下面是一篇可能有用的博客文章:

如何: 使用 < 复制 > 任务递归复制文件

我认为问题可能在于如何创建 ItemGroup 并调用 Copy 任务。看看这是否合理:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory>
<YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory>
</PropertyGroup>


<Target Name="BeforeBuild">
<CreateItem Include="$(YourSourceDirectory)\**\*.*">
<Output TaskParameter="Include" ItemName="YourFilesToCopy" />
</CreateItem>


<Copy SourceFiles="@(YourFilesToCopy)"
DestinationFiles="@(YourFilesToCopy->'$(YourDestinationDirectory)\%(RecursiveDir)%(Filename)%(Extension)')" />
</Target>
</Project>

我有点新的 MSBuild,但我发现 EXEC 任务方便的情况下喜欢这些。我在我的项目中遇到了同样的挑战,这对我来说很有效,而且简单得多。如果练习不好请告诉我。

<Target Name="CopyToDeployFolder" DependsOnTargets="CompileWebSite">
<Exec Command="xcopy.exe  $(OutputDirectory) $(DeploymentDirectory) /e" WorkingDirectory="C:\Windows\" />
</Target>

就我个人而言,我已经使用了 CopyFolder,它是 SDC 任务库的一部分。

Http://sdctasks.codeplex.com/

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<YourDestinationDirectory>..\SomeDestinationDirectory</YourDestinationDirectory>
<YourSourceDirectory>..\SomeSourceDirectory</YourSourceDirectory>
</PropertyGroup>


<Target Name="BeforeBuild">
<CreateItem Include="$(YourSourceDirectory)\**\*.*">
<Output TaskParameter="Include" ItemName="YourFilesToCopy" />
</CreateItem>


<Copy SourceFiles="@(YourFilesToCopy)"
DestinationFiles="$(YourFilesToCopy)\%(RecursiveDir)" />
</Target>
</Project>

\**\*.*帮助从所有文件夹中获取文件。 RecursiveDir 帮助将所有文件放在相应的文件夹中..。

我也在寻求帮助。这花了我一段时间,但这是我所做的,工作真的很好。

<Target Name="AfterBuild">
<ItemGroup>
<ANTLR Include="..\Data\antlrcs\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(ANTLR)" DestinationFolder="$(TargetDir)\%(RecursiveDir)" SkipUnchangedFiles="true" />
</Target>

这会递归地将名为 antlrcs的文件夹的内容复制到 $(TargetDir)

This is the example that worked:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">


<ItemGroup>
<MySourceFiles Include="c:\MySourceTree\**\*.*"/>
</ItemGroup>


<Target Name="CopyFiles">
<Copy
SourceFiles="@(MySourceFiles)"
DestinationFiles="@(MySourceFiles->'c:\MyDestinationTree\%(RecursiveDir)%(Filename)%(Extension)')"
/>
</Target>


</Project>

来源: https://msdn.microsoft.com/en-us/library/3e54c37h.aspx

这是我在我自己的项目中使用的复制任务,对我来说,将子文件夹的文件夹复制到目的地是完美的:

<ItemGroup >
<MyProjectSource Include="$(OutputRoot)/MySource/**/*.*" />
</ItemGroup>


<Target Name="AfterCopy" AfterTargets="WebPublish">
<Copy SourceFiles="@(MyProjectSource)"
OverwriteReadOnlyFiles="true" DestinationFolder="$(PublishFolder)api/% (RecursiveDir)"/>

在我的情况下,我复制了一个项目的发布文件夹到另一个目标文件夹,我认为这是类似的情况下。

使用 MSBuild 将文件从一个目录递归复制到另一个目录的最佳方法是使用将 SourceFiles 和 DestinationFiles 作为参数的 Copy 任务。例如-将所有文件从生成目录复制到备份目录将是

<PropertyGroup>
<BuildDirectory Condition="'$(BuildDirectory)' == ''">Build</BuildDirectory>
<BackupDirectory Condition="'$(BackupDiretory)' == ''">Backup</BackupDirectory>
</PropertyGroup>


<ItemGroup>
<AllFiles Include="$(MSBuildProjectDirectory)/$(BuildDirectory)/**/*.*" />
</ItemGroup>


<Target Name="Backup">
<Exec Command="if not exist $(BackupDirectory) md $(BackupDirectory)" />
<Copy SourceFiles="@(AllFiles)" DestinationFiles="@(AllFiles->
'$(MSBuildProjectDirectory)/$(BackupDirectory)/%(RecursiveDir)/%(Filename)%
(Extension)')" />
</Target>

现在,在上面的“复制”命令中,将遍历所有源目录,并将文件复制到目标目录。

如果使用的是典型的 C + + 工具链,另一种方法是将文件添加到标准 CopyFileToFolders 列表中

<ItemGroup>
<CopyFileToFolders Include="materials\**\*">
<DestinationFolders>$(MainOutputDirectory)\Resources\materials\%(RecursiveDir)</DestinationFolders>
</CopyFileToFolders>
</ItemGroup>

除了简单之外,这是一个很好的方法,因为 CopyFilesToFolders 任务将生成适当的输入、输出,甚至是 TLog files,因此确保只有当一个输入文件已经更改或一个输出文件丢失时,复制操作才会运行。使用 TLog,Visual Studio 也能正确地识别项目是否是“最新的”(它使用了一个单独的 U2DCheck 机制)。