MSBuild脚本默认属性最佳实践说明

时间:2014-05-08 14:35:35

标签: msbuild automation

在构建MSBuild脚本时,我需要定义一系列默认属性,但在运行脚本时可以重写。根据以下文章,您应该使用条件来默认属性:

http://msdn.microsoft.com/en-us/library/ee240983.aspx

Microsoft如何推荐:

<PropertyGroup>
    <MyProperty Condition="'$(MyProperty)' == '' ">Default Value</MyProperty>
</PropertyGroup>

然而,这表现完全相同:

<PropertyGroup>
    <MyProperty>Default Value Without Conditional</MyProperty>
</PropertyGroup>

所以,如果我有这个Target并使用上述任一方法调用它,它具有相同的行为:

<Target Name="DefaultsTest">
    <Message Text="$(MyProperty)"></Message>
</Target>

调用:

msbuild build.xml /t:DefaultsTest /p:MyProperty="Overridden value"

如果您只是默认可以从调用中覆盖的相同属性,请解释使用Condition属性的好处吗?

更新

这是一个完整的简单配置文件,用于演示:defaults.xml

<?xml version="1.0" encoding="utf-8" ?>
<Project DefaultTargets="DefaultsTest" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MyProperty Condition=" '$(MyProperty)' == '' ">MyProperty with Conditional</MyProperty>
        <MyOtherProperty>MyOtherProperty without Conditional</MyOtherProperty>
    </PropertyGroup>

    <Target Name="DefaultsTest">
        <Message Text="$(MyProperty)"></Message>
        <Message Text="$(MyOtherProperty)"></Message>
    </Target>
</Project>

这可以简单地作为msbuild defaults.xml

运行

msbuild defaults.xml /p:MyProperty="Changed Value" /p:MyOtherProperty="Changed as well"

1 个答案:

答案 0 :(得分:6)

您正确地注意到,您可以通过无条件分配财产来实现您想要的行为。在命令行上没有/ p:override时构建的以下项目将生成Default Value。使用命令msbuild myproj.proj /t:DefaultsTest /p:MyProperty=NewValue构建时,将生成NewValue

 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MyProperty>Default Value</MyProperty>
    </PropertyGroup>
    <Target Name="DefaultsTest">
        <Message Text="MyProperty=$(MyProperty)"></Message>
    </Target>
</Project>

这是因为在MSBuild命令行上指定或作为任务参数提供的任何属性都将被视为Global Properties。对于全局属性,任何有条件或无条件的赋值或修改都将被忽略 - 全局属性在项目执行的整个生命周期内将保持不变。

如果您使用TreatAsLocalProperty属性,条件分配和无条件之间行为的唯一区别就在于。

例如,请考虑以下项目:

 <Project TreatAsLocalProperty="Prop1;Prop2" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <Prop1>Prop1 Default Value</Prop1>
        <Prop2 Condition="$(Prop2) == ''">Prop2 Default Value</Prop2>
    </PropertyGroup>
    <Target Name="DefaultsTest">
        <Message Text="Prop1=$(Prop1)"></Message>
        <Message Text="Prop2=$(Prop2)"></Message>
    </Target>
</Project>

两个属性 - Prop1和Prop2都在Project元素中声明为local。 Prop1是无条件分配的,而Prop2是使用非空条件分配的。执行构建命令:

msbuild b.proj /t:DefaultsTest /p:Prop1=NewValue1 /p:Prop2=NewValue2

将产生输出:

Prop1=Prop1 Default Value
Prop2=NewValue2

这意味着在一般情况下(如果您不能绝对确定属性是全局的还是本地的),使用默认值的条件赋值会更安全,因为它始终有效。