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

时间:2008-09-23 05:20:03

标签: scripting msbuild build-process build

只是想知道是否有人可以帮我解决一些我想写的msbuild脚本。我想要做的是使用msbuild将文件夹中的所有文件和子文件夹复制到另一个文件夹。

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

我需要做的是将tools文件夹中的所有文件和子文件夹复制到应用程序的调试文件夹中。这是我到目前为止的代码。

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

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

构建脚本运行但不复制任何文件或文件夹。

由于

10 个答案:

答案 0 :(得分:105)

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

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

以递归方式将名为antlrcs的文件夹的内容复制到$(TargetDir)

答案 1 :(得分:69)

我认为问题可能在于您如何创建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>

答案 2 :(得分:35)

我是MSBuild的新手,但我觉得EXEC Task适用于这样的情况。我在我的项目中遇到了同样的挑战,这对我有用,而且更简单。有人请告诉我这是不是一个好习惯。

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

答案 3 :(得分:10)

<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帮助将所有文件放在相应的文件夹中......

答案 4 :(得分:4)

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

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

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

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

对我来说很奇怪。脚本看起来很好,因此问题可能出在$(ApplicationDirectory)$(OutputPath)

的值中

编辑:

这是一篇可能有用的博文:

How To: Recursively Copy Files Using the Task

答案 5 :(得分:2)

这是有效的例子:

<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

答案 6 :(得分:1)

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

http://sdctasks.codeplex.com/

答案 7 :(得分:1)

这是我在我自己的项目中使用的复制任务,它非常适合我将子文件夹的文件夹成功复制到目的地:

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

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

在我的情况下,我将项目的发布文件夹复制到另一个目标文件夹,我认为它与您的案例类似。

答案 8 :(得分:0)

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

<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)/%(RecuriveDir)/%(Filename)% 
(Extension)')" />
</Target>

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

答案 9 :(得分:0)

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

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

除了简单之外,这是一个不错的方法,因为CopyFilesToFolders任务将生成适当的输入,输出甚至TLog files,因此请确保仅在输入文件之一更改或其中一个更改时复制操作才会运行输出文件丢失。借助TLog,Visual Studio还将正确识别项目是否为“最新”(为此它使用了单独的U2DCheck机制)。