在MSBuild中使用复制任务和解压缩任务

3
在下面的msbuild脚本中,第一次运行csproject时,按照以下顺序执行以下目标:
1) UnzipDLL 2) DeleteExtraneousDirs
如果我第二次运行csproject,则按照以下顺序执行以下目标:
1) UnzipDLL 2) CopyFiles 3) DeleteExtraneousDirs
我不确定为什么“CopyFiles”目标第一次没有运行。我还尝试通过添加“BeforeTargets”,“AfterTargets”和/或“DependsOnTargets”来指定目标顺序,但这并没有在UnzipDLL目标之后运行CopyFiles目标。
此外,如果我将DefaultTargets仅指定为“UnzipDLL”和“CopyFiles”,则第一次运行csproject时只会运行“UnzipDLL”任务,并且第二次运行csporjects时将同时运行“UnzipDLL”和“CopyFiles”任务。
以下是msbuild脚本。感谢您的帮助!
<Project ToolsVersion="14.0" DefaultTargets="UnzipDLL;CopyFiles;DeleteExtraneousDirs" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
  <PropertyGroup>
    <ReleasePath>..\..\..\..\..\TDS</ReleasePath>
    <RelDirectory>$(ReleasePath)\exe\dll\_rels</RelDirectory>
    <LibDirectory>$(ReleasePath)\exe\dll\lib</LibDirectory>
  </PropertyGroup>
  <ItemGroup>
    <LibFiles Include="$(ReleasePath)\exe\dll\lib\**\*.*;$(ReleasePath)\exe\dll\lib\*.*" />
  </ItemGroup>
  <Target Name="UnzipDLL"> 
     <Unzip ZipFileName="$(ReleasePath)\exe\utils\TDS.Packages.1.0.0.nupkg" 
        TargetDirectory="$(ReleasePath)\exe\dll\" /> 
  </Target>
  <Target Name="CopyFiles">
     <Copy SourceFiles="@(LibFiles)" DestinationFolder="$(ReleasePath)\exe\dll\%(RecursiveDir)" />
  </Target>
  <Target Name="DeleteExtraneousDirs">
     <Delete Files="@(LibFiles)" />
     <RemoveDir Directories="$(RelDirectory);$(LibDirectory)" />
  </Target>
</Project>

更新
根据SergeyL的观点,CopyFiles目标确实会被执行。但是,Copy任务不会将文件从exe/dll/lib文件夹复制到exe/dll文件夹。我通过在Copy任务之前和之后添加Message任务来发现这一点。


你怎么知道CopyFiles目标没有被执行?你有构建日志吗?你可以使用<Message..>来显式记录一个目标是否被执行。 - Sergey L
很好。我不知道我可以使用Message来做到这一点。我会找出如何做到这一点。我知道两种方法:1)Lib文件没有复制到dll文件夹中;2)我在msbuild命令窗口中看不到复制输出。 - rds80
1个回答

2

我不确定为什么第一次运行“CopyFiles”目标时会出问题...但这并没有在UnzipDLL目标之后运行CopyFiles目标。

问题出在ItemGroup上。它需要写在Copy目标内部。

msbuild脚本应该是:

  <Target Name="CopyFiles">
    <ItemGroup>
      <LibFiles Include="$(ReleasePath)\exe\dll\lib\**\*.*;$(ReleasePath)\exe\dll\lib\*.*" />
    </ItemGroup>
    <Copy SourceFiles="@(LibFiles)" DestinationFolder="$(ReleasePath)\exe\dll\%(RecursiveDir)" />   
  </Target>

当我们使用ItemGroup处理批量文件的目标时,MSBuild将对这些文件进行预处理。当我们执行MSBuild脚本时,目标unzipCopy会在非常短的时间内完成,但是,实际解压缩的完成会有几秒钟的延迟。因此,CopyFiles目标实际上被执行了。但是复制任务不会复制文件(因为解压缩还没有完成)。这就是为什么复制任务第一次没有执行而第二次执行的原因。
因此,要解决这个问题,只需要在复制目标中写入ItemGroup即可。

现在可以工作了。谢谢。我曾考虑使用Sleep或Thread任务,但这个方法更好。你知道有没有一个链接可以解释在目标中使用ItemGroup的概念吗?我不太清楚将<ItemGroup>添加到Copy目标中如何强制延迟。 - rds80
在回答这个问题之前,我已经尝试查找有关目标内部和外部的ItemGroup之间差异的相关文档,但不幸的是,我没有找到说明这个问题的文档。如果我以后找到了相关文档,我会告诉你的。 - Leo Liu
文件没有被复制,因为没有要复制的文件。在第一个目标执行之前,Target外部的ItemGroup将被评估,此时没有文件可供复制。这是由于执行顺序引起的。 - Alin Mircea

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接