将属性组值从一个MsBuild任务传递到另一个任务

将属性组值从一个MsBuild任务传递到另一个任务,msbuild,msbuild-propertygroup,Msbuild,Msbuild Propertygroup,如何使一个构建目标中定义的值在另一个目标中保持活动状态?如果PropertyGroup不是我应该在这里使用的write MsBuild实体,那么它是什么?ReleaseDir在“Package”目标中打印正常,但在“DoPackage”中为空 c:\tmp ... 有一个包含属性和CallTarget任务的对话框。您应该改用DependsOnTargets <Target Name="Package"> <PropertyGroup> &

如何使一个构建目标中定义的值在另一个目标中保持活动状态?如果PropertyGroup不是我应该在这里使用的write MsBuild实体,那么它是什么?ReleaseDir在“Package”目标中打印正常,但在“DoPackage”中为空


c:\tmp
...
有一个包含属性和CallTarget任务的对话框。您应该改用DependsOnTargets

<Target Name="Package">
  <PropertyGroup>
    <ReleasesDir>c:\tmp</ReleasesDir>
  </PropertyGroup>
  <Message Text="$(ReleasesDir)"/>
</Target>

<Target Name="PrePackage" DependsOnTargets="Package">
  <CallTarget Targets="DoPackage" Condition="!Exists('$(ReleasesDir)')"/>
</Target>

<!-- Do the actual packaging -->
<Target Name="DoPackage" DependsOnTargets="Package">
  <Message Text="Creating package in '$(ReleasesDir)'"/>
  <Error Condition="'$(ReleasesDir)' == ''" Text="No ReleaseDir defined"/>
  <MakeDir Directories="$(ReleasesDir)"/>
</Target>

c:\tmp

如果要将属性传递给目标,MSBuild任务可能很有用。这是使用不同属性值多次调用目标的唯一方法,但不允许传入项或项组。在Julien链接到的线程中可以看到这一点

…[C]再次将所有MSBuild目标传递给它,这次传递所需的属性。这绕过了增量构建…,但有许多限制,即您不能传入项,并且必须指定需要传入的属性

以下是使用MSBuild任务时代码段的外观:

<Target Name="Package">
  <PropertyGroup>
    <ReleasesDir>c:\tmp</ReleasesDir>
  </PropertyGroup>
  <Message Text="$(ReleaseDir)"/>
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="DoPackage" Properties="ReleaseDir=$(ReleaseDir)" /> 
</Target>

<!-- Do the acutal packaging -->
<Target Name="DoPackage">
  <Message Text="Creating package in '$(ReleaseDir)'"/>
  <Error Condition="'$(ReleaseDir)' == ''" Text="No ReleaseDir defined"/>
  <MakeDir Directories="$(ReleaseDir)"/>
  ...
</Target>

c:\tmp
...

如果希望将目标用作子例程,则此技术非常有用,您可以使用不同的参数值多次调用该子例程。例如,调用多个产品配置的构建过程

这可能不是解决这个问题的最干净的方法,但是如果有人仍然想在构建文件上使用CallTarget,他/她必须在另一个目标中定义PropertyGroup,下面是这个奇怪问题的解决方案

<Target Name="DebugBuild" DependsOnTargets="DebugBuildProp">
  <CallTarget Targets="CompileSolution"/>
</Target>
<Target Name="DebugBuildProp">
  <PropertyGroup>
    <Configuration>Debug</Configuration>
  </PropertyGroup>
</Target>
<Target Name="CompileSolution">
   <Message Text="$(Configuration)" />
</Target>

调试

我希望DoPackage仅在ReleaseDir存在时运行(我使用CallTarget中的条件来实现这一点)。我可以使用DependsOnTarget实现这一点吗?现在我已经阅读了您发布的链接,解决方案很简单-我编写了一个名为“DefineProperties”的单独任务,完成后属性是。。。定义谢谢。我觉得直到任务完成后才定义属性的原因是因为并行执行。MsBuild不保证任何中间目标,因为这样它可以并行执行子目标。在本例中,DoPackage目标不需要DependsOnTargets=“Package”,因为预打包目标已具有DependsOnTargets=“Package”。如果生成文件需要使用不同的ReleasesDir值运行DoPackage,那么删除这个额外的DependsOnTargets=“Package”可能会很有用。与此类似:c:\tmp2如果
DeugBuild
更新了
配置的值,则
编译解决方案仍然不会使用新值。@Al-Muhandis它实际上使用,我不知道为什么,但是如果在依赖目标上定义属性,那么使用CallTarget调用的所有其他目标都将具有该值。你自己试试看
<Target Name="DebugBuild" DependsOnTargets="DebugBuildProp">
  <CallTarget Targets="CompileSolution"/>
</Target>
<Target Name="DebugBuildProp">
  <PropertyGroup>
    <Configuration>Debug</Configuration>
  </PropertyGroup>
</Target>
<Target Name="CompileSolution">
   <Message Text="$(Configuration)" />
</Target>