csproj

时间:2017-07-26 07:22:36

标签: msbuild csproj msbuild-task

我一直在尝试更新csproj文件中的 ApplicationVersion 属性.witch工作正常;我添加了一个运行自定义任务的Target来从我的 assemblyinfo.cs 中提取 AssemblyFileVersion ;这项工作毫无疑问。 但是当我想使用我更新的 ApplicationVersion 来威慑我的新构建文件的位置时,我会在属性中设置默认值。

<PropertyGroup>
        ...
        <ApplicationVersion>1.0.0.0</ApplicationVersion>
        ...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
        <PlatformTarget>AnyCPU</PlatformTarget>
        <DebugSymbols>true</DebugSymbols>
        <DebugType>full</DebugType>
        <Optimize>false</Optimize>
        <OutputPath>..\media-converter-BUILD\debug\$(ApplicationVersion)\</OutputPath>
        <DefineConstants>DEBUG;TRACE</DefineConstants>
        <ErrorReport>prompt</ErrorReport>
        <WarningLevel>4</WarningLevel>
        <DocumentationFile>..\media-converter-BUILD\debug\$(ApplicationVersion)\MediaConverter.XML</DocumentationFile>
    </PropertyGroup>

我的目标

<UsingTask AssemblyFile="GetAssemblyFileVersion.dll" TaskName="GetAssemblyFileVersion.GetAssemblyFileVersion" />
    <Target Name="MainAfterCompile">
        <CallTarget Targets="AfterCompile" />
        <CallTarget Targets="VerifyParam" />
    </Target>
    <Target Name="AfterCompile">
        <GetAssemblyFileVersion strFilePathAssemblyInfo="Properties\AssemblyInfo.cs">
            <Output TaskParameter="strAssemblyFileVersion" PropertyName="ApplicationVersionModded" />
        </GetAssemblyFileVersion>
        <PropertyGroup>
            <ApplicationVersion>$(ApplicationVersionModded)</ApplicationVersion>
        </PropertyGroup>
    </Target>

    <Target Name="VerifyParam">
        <Message Text="New $(ApplicationVersionModded)" Importance="high"/>
        <Message Text="Old Updated $(ApplicationVersion)" Importance="high"/>
    </Target>
GetAssemblyFileVersion.dll 我或多或少从我在互联网上发现的一些帖子中偷走了,只是找不到它,所以我无法添加链接,抱歉。

我关于它为什么不起作用的理论是在运行InitailTagets和DefaultTargets之前渲染PropertyGroups中的变换和参数。我的计划永远不会工作

但如果有人知道如何使其发挥作用,我将在此感激

1 个答案:

答案 0 :(得分:1)

我关于它为什么不起作用的理论是PropertyGroups中的变换和参数在InitailTagets和DefaultTargets运行之前呈现,这就是evaluation order的工作方式:msbuild评估全局在文件的第一次传递中,您定义OutputPath,Microsoft.Common.CurrentVersion.targets文件使用它来派生OutDir / BaseIntermediateOutputPath / ....然后在另一次传递中,您的目标运行并更新版本号,但是没有另一个传递再次评估全局OutputPath属性。

但是,您可以覆盖Target中的OutputPath和派生路径的值,它将生效,您只需要在构建的早期就开始运行它,以便其他目标使用更新的版本。这就是诀窍:

<Target Name="GetApplicationVersion">
  <GetAssemblyFileVersion strFilePathAssemblyInfo="Properties\AssemblyInfo.cs">
    <Output TaskParameter="strAssemblyFileVersion" PropertyName="ApplicationVersion" />
  </GetAssemblyFileVersion>
</Target>
<Target Name="SetOutputPaths" DependsOnTargets="GetApplicationVersion"
        BeforeTargets="PrepareForBuild">
  <PropertyGroup>
    <OutputPath>bin\$(Configuration)\$(ApplicationVersion)\</OutputPath>
    <OutDir>$(OutputPath)</OutDir>
  </PropertyGroup>
  <Message Text="Set OutDir to $(OutDir)" Importance="high" />
</Target>

处理此问题的另一种方法是反过来做:将应用程序版本定义为全局msbuild属性,然后使用它来定义OutputPath并在编译之前更新AssemblyVersion.cs中的数字。