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

Nat*_*n W 82 msbuild scripting build-process build

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

{ProjectName}
      |----->Source
      |----->Tools
              |----->Viewer
                       |-----{about 5 sub dirs}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

谢谢

Rod*_*ber 114

我也在寻找这方面的帮助.我花了一段时间,但这是我做的非常好的工作.

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

这个递归复制命名的文件夹中的内容antlrcs$(TargetDir).

  • 诀窍似乎是将'%(RecursiveDir)`添加到目标文件夹将重新创建目录结构.否则输出是平坦的.这是最佳答案. (14认同)
  • 是的,这是最好的答案.与msdn博客上推荐的相同:http://blogs.msdn.com/b/msbuild/archive/2005/11/07/490068.aspx (4认同)
  • 工作正常 - 谢谢!我想知道为什么其他更复杂的答案有更多的赞成?! (2认同)

bro*_*lum 70

我认为问题可能在于您如何创建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>
Run Code Online (Sandbox Code Playgroud)


小智 35

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

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

  • 我不敢反过来问这个问题.是否有任何理由使用日志填充msbuild复制任务? (8认同)
  • 潜在的.如果您有一个构建服务器场(Jenkins,TeamCity等),则代理服务可能在路径中没有xcopy的其他帐户下运行.您可以在路径中尝试%windir%\ system32之类的内容,但即使这样也不会有效. (4认同)
  • 我知道这个问题不常出现,但我使用`Copy`任务而不是命令的主要原因是兼容性.我之前使用Mono构建Linux,显然`xcopy`在那里不起作用. (4认同)

小智 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>
Run Code Online (Sandbox Code Playgroud)

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

  • 目标文件引用1个项目,源文件引用33个项目.它们必须具有相同数量的项目.呃.. msbuild可能很棒,但有时候记录得如此糟糕. (2认同)

PBo*_*PBo 5

这是有效的示例:

<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>
Run Code Online (Sandbox Code Playgroud)

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


nzr*_*tmn 5

这是我在自己的项目中使用的复制任务,它对我来说工作得很好,成功地将带有子文件夹的文件夹复制到目的地:

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

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

就我而言,我将项目的发布文件夹复制到另一个目标文件夹,我认为这与您的情况类似。

  • 其他答案都不能在 Sdk 类型项目上开箱即用,因为不会调用“AfterBuild”。像您一样设置“AfterTargets”依赖项是让目标在“现代”msbuild 中的另一个目标之后触发的适当方法。就我而言,我使用 AfterTargets="Build" 将一些 dll 复制到另一个文件夹。 (2认同)

aku*_*aku 3

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

DestinationFolder="@(Viewer->'$(OutputPath)\\Tools')" ? 
Run Code Online (Sandbox Code Playgroud)

我不太精通高级 MSBuild 语法,但是

@(Viewer->'$(OutputPath)\\Tools') 
Run Code Online (Sandbox Code Playgroud)

我觉得很奇怪。脚本看起来不错,所以问题可能出在$(ApplicationDirectory)和的值上$(OutputPath)

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

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