【问题标题】:Overwrite properties with MSBuild使用 MSBuild 覆盖属性
【发布时间】:2009-09-02 10:10:54
【问题描述】:

我想在我的 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>

目前我正在尝试重新声明属性设置它的值,但这不起作用。

【问题讨论】:

    标签: msbuild


    【解决方案1】:

    Mehmet 关于如何从另一个属性设置属性值是正确的,但是 MSBuild 中有一个错误/功能,这意味着 如果您在同一个目标中调用 CreateProperty 和 CallTarget,您的新属性将不会是全局的可用于其他目标 (described here)。

    所以这是问题的最终解决方案:

    <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>
    

    【讨论】:

    • 谢谢,这很有用。我对批处理还有些陌生,在我看来,MS 在解释相关概念方面做得不好。再来一注。实际上,我没有创建全局属性就逃脱了;这会稍微缩小上下文范围,以便更容易阅读代码:目标 A 调用目标 B 和 C。B 设置一个列表属性,C 对该属性的值进行批处理。正如 mdresser 指出的那样,在同一目标中设置属性不起作用。希望它可以帮助某人;在找到这篇文章之前,我花了 3-4 个小时试图理解这一点。
    • 还有一点,您说您收到通知说只有 Cat 已更改,您是否尝试保存更改?它有效吗? (我怀疑)
    【解决方案2】:

    您可以使用CreateProperty 任务覆盖现有属性的值。

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

    【讨论】:

    • 这似乎对我不起作用。我可以在 CreateProperty 块之后立即使用 DeployPath 属性的值,但它在 Deploy-Sub 目标中失去了它的值。
    • 哈哈,刚刚发现这篇文章 weblogs.asp.net/bhouse/archive/2006/03/20/440648.aspx 描述了 CreateProperty 任务的错误/功能。
    • 有趣我不知道这个错误。我以前使用过 CreateProperty,但显然不需要访问覆盖它的目标之外的覆盖属性。谢谢。
    【解决方案3】:

    我通常避免CallTarget 任务。更好的是使用目标依赖项。

    【讨论】:

    • 您能详细说明一下吗?为什么它对你更好?
    • @HaymoKutschbach 因为这个错误sedodream.com/… 而我认为 CallTarget 违背了应该如何使用 msbuild 的心理模型。 MSBuild 是声明性的,CallTarget 是非常必要的。话虽如此,在某些情况下需要它,但你应该在 CallTarget 之前更喜欢 DependsOn。
    • 谢谢!我同意,似乎 msbuild 团队也鼓励 DependsOn 以及在导入的项目中启用全局设置属性。
    【解决方案4】:

    此外,您还可以使用以下方式:

    <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>
    

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 2013-07-19
      • 1970-01-01
      相关资源
      最近更新 更多