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

Kei*_*ris 5 msbuild automation

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

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

Microsoft如何建议:

<PropertyGroup>
    <MyProperty Condition="'$(MyProperty)' == '' ">Default Value</MyProperty>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

但是,这行为完全相同:

<PropertyGroup>
    <MyProperty>Default Value Without Conditional</MyProperty>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

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

<Target Name="DefaultsTest">
    <Message Text="$(MyProperty)"></Message>
</Target>
Run Code Online (Sandbox Code Playgroud)

调用:

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>
Run Code Online (Sandbox Code Playgroud)

这可以简单地运行 msbuild defaults.xml

要么

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

sev*_*tov 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>
Run Code Online (Sandbox Code Playgroud)

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

如果使用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>
Run Code Online (Sandbox Code Playgroud)

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

msbuild b.proj /t:DefaultsTest /p:Prop1=NewValue1 /p:Prop2=NewValue2
Run Code Online (Sandbox Code Playgroud)

会产生输出:

Prop1=Prop1 Default Value
Prop2=NewValue2
Run Code Online (Sandbox Code Playgroud)

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