用MSBuild覆盖属性

用MSBuild覆盖属性,msbuild,Msbuild,我想在MSBuild文件中声明三个属性,并用另一个属性的值覆盖一个属性(取决于调用的目标),但不知道如何执行此操作。我的生成文件如下所示: <PropertyGroup> <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST> <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPa

我想在MSBuild文件中声明三个属性,并用另一个属性的值覆盖一个属性(取决于调用的目标),但不知道如何执行此操作。我的生成文件如下所示:

<PropertyGroup>
   <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST>
   <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPath_LIVE>
   <DeployPath></DeployPath>
</PropertyGroup>

<Target Name="Deploy-TEST">
   <PropertyGroup>
      <DeployPath>$(DeployPath_TEST)</DeployPath>
   </PropertyGroup>
   <CallTarget Targets="Deploy-Sub"/>
</Target>

<Target Name="Deploy-LIVE">
   <PropertyGroup>
      <DeployPath>$(DeployPath_TEST)</DeployPath>
   </PropertyGroup>
   <CallTarget Targets="Deploy-Sub"/>
</Target>

<Target Name="Deploy-Sub">
   <Message Text="Deploying to $(DeployPath)"/>
   <MSBuild Projects="MySolution.csproj" Targets="Rebuild" />

   <ItemGroup>
     <MyFiles Include="**\*"/>
   </ItemGroup>

   <Copy SourceFiles="@(MyFiles)" 
         DestinationFiles="@(MyFiles->'$(DeploymentPath)\%(RecursiveDir)%(FileName)%(Extension)')"/>

</Target>

\\测试服务器路径\websites\mysite
\\实时服务器路径\websites\mysite
$(部署路径测试)
$(部署路径测试)
目前,我正在尝试重新声明属性设置,并相应地设置其值,但这不起作用。

您可以使用task覆盖现有属性的值

<Target Name="Deploy-LIVE">   
  <CreateProperty Value="$(DeployPath_LIVE)">
    <Output PropertyName="DeployPath" TaskParameter="Value"/>
  </CreateProperty>
  <CallTarget Targets="Deploy-Sub"/>
</Target>

Mehmet在如何从另一个属性设置属性值方面是正确的,但MSBuild中存在一个错误/功能,这意味着如果在同一个目标中调用CreateProperty和CallTarget,则其他目标将无法全局使用新属性()

下面是问题的最终解决方案:

<PropertyGroup>
   <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST>
   <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPath_LIVE>
   <DeployPath></DeployPath>
</PropertyGroup>

<Target Name="SetDeployPath-TEST">
  <CreateProperty Value="$(DeployPath_TEST)">
    <Output TaskParameter="Value" PropertyName="DeployPath"/>
  </CreateProperty>
</Target>

<Target Name="Deploy-TEST">
   <CallTarget Targets="SetDeployPath-TEST"/>
   <CallTarget Targets="Deploy-Sub"/>
</Target>

<Target Name="Deploy-Sub">
  <Message Text="Deploying to $(DeployPath)"/>
  <MSBuild Projects="MySolution.csproj" Targets="Rebuild" />

  <ItemGroup>
    <MyFiles Include="**\*"/>
  </ItemGroup>

  <Copy SourceFiles="@(MyFiles)" 
     DestinationFiles="@(MyFiles->'$(DeploymentPath)\%(RecursiveDir)%(FileName)%(Extension)')"/>

</Target>

\\测试服务器路径\websites\mysite
\\实时服务器路径\websites\mysite

我通常会避免这项任务。更好的方法是使用目标依赖项。

此外,您可以使用以下方法:

<PropertyGroup>
   <DeployPath_TEST>\\test-server-path\websites\mysite</DeployPath_TEST>
   <DeployPath_LIVE>\\live-server-path\websites\mysite</DeployPath_LIVE>
   <DeployPath></DeployPath>
</PropertyGroup>

<Target Name="SetDeployPath-TEST">
  <CreateProperty Value="$(DeployPath_TEST)">
    <Output TaskParameter="Value" PropertyName="DeployPath"/>
  </CreateProperty>
</Target>

<Target Name="Deploy-Sub" DependsOnTargets="SetDeployPath-TEST">
  <Message Text="Deploying to $(DeployPath)"/>
  <MSBuild Projects="MySolution.csproj" Targets="Rebuild" />

  <ItemGroup>
    <MyFiles Include="**\*"/>
  </ItemGroup>

  <Copy SourceFiles="@(MyFiles)" 
     DestinationFiles="@(MyFiles->'$(DeploymentPath)\%(RecursiveDir)%(FileName)%(Extension)')"/>

</Target>

\\测试服务器路径\websites\mysite
\\实时服务器路径\websites\mysite

这似乎不适合我。我可以在CreateProperty块之后立即使用DeployPath属性的值,但是它在Deploy子目标中失去了它的值。Haa,刚刚发现这篇文章描述了CreateProperty任务的一个bug/特性。有趣的是,我不知道这个bug。我以前使用过CreateProperty,但显然不需要在重写的目标之外访问重写的属性。谢谢,谢谢,这很有用。我对批处理还是有点陌生,在我看来MS并没有很好地解释相关概念。再来一张。事实上,我没有创造一个全球性的财产;这会缩小上下文范围,以便更容易阅读代码:目标a调用目标B和C。B设置列表属性,C对该属性的值进行批处理。正如mdresser所指出的,在同一目标中设置属性不起作用。希望它能帮助别人;在我找到这篇文章之前,我已经花了3-4个小时试图理解这一点。还有一点,你说你收到通知说只有Cat已更改,你是否尝试保存更改?它有用吗?(我怀疑)你能详细说明一下吗?为什么这样对你更好?@HaymoKutschbach因为这个bug,我认为CallTarget违背了应该如何使用msbuild的心智模型。MSBuild是声明性的,CallTarget是非常必需的。尽管如此,在某些情况下还是有必要的,但是你应该在调用Target之前选择DependsOn。谢谢!我同意,而且msbuild团队似乎也鼓励DependsOn在导入的项目中全局设置属性。