如何在导入之前计算MSBuild属性

时间:2012-08-13 18:24:12

标签: visual-studio msbuild

考虑这两个MSBuild文件。首先build-script.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- build-script.xml -->
<Project
    ToolsVersion="4.0"
    DefaultTargets="Build"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <OutputName>OutputName</OutputName>
    </PropertyGroup>

    <Import Project="build-script-to-import.xml"/>
</Project>

然后build-script-to-import.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- build-script-to-import.xml -->
<Project
    ToolsVersion="4.0"
    DefaultTargets="Build"
    xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <OutputPath>Path\$(OutputName)</OutputPath>
    </PropertyGroup>

    <Target Name="Build">
        <Message Text="$(OutputPath)" />
    </Target>
</Project>

这两个文件代表一个引用公共目标文件(build-script.xml)的非常简化的C#项目文件(build-script-to-import.xml)。这意味着不能更改build-script-to-import.xml文件。问题是计算OutputName,我需要在导入build-script-to-import.xml文件之前将其设置为此计算值。你知道我怎么能做到这一点吗?


注1:计算出的值实际上是一个汇编版本,我可以使用GetAssemblyIdentity MSBuild task从汇编文件中获取。我看到的问题是在导入发生之前我可能不会调用目标。我想借助OutputName MSBuild任务设置属性GetAssemblyIdentity的值。

注意2:构建将由Visual Studio触发,因此我可能不会使用批处理文件并将属性作为命令行参数发送到MSBuild。

2 个答案:

答案 0 :(得分:0)

在“Build”目标中移动$(OutputPath)的声明。使用“计算”​​属性的唯一方法是在目标内部评估它们。在任何目标运行之前,始终会评估全局声明的“静态”属性,并且可能需要运行目标来计算$(OutputName)的值。只需确保您的名字计算目标在“构建”目标之前运行。

答案 1 :(得分:0)

如果导入项目中的对应目标允许修改DependsOnTargets

<Target Name="Build" DependsOnTargets="@(BuildDependsOn)" />

您可以修改项目并添加目标,以准备所需的属性。

如果不可能,你可以编写包装器来自己调用底层目标/目标(构建/重建/清理)(不导入build-script-to-import.xml):

build-script.xml

 <Target Name="Build" DependsOn="PrepareProperties">
      <MSBuild Projects="build-script-to-import.xml"  
               Targets="Build"            
               Properties="OutputName=$(OutputName);$(OtherProperties)"/>
 </Target>

<强>建议

取决于您动态更改OutputName的要求,可能会有更简单的解决方案。只是不要这样做。编写自己的自定义构建步骤以从固定输出目录复制到目标位置(使用您的规则计算)相当简单。

例如,我更喜欢练习,当我有一个名为最新的目录,其中包含固定路径和每个产品版本的目录。每个人都可以从该文件夹中获取最新版本。