csproj中的MSBuild更新属性

csproj中的MSBuild更新属性,msbuild,csproj,msbuild-task,Msbuild,Csproj,Msbuild Task,我一直在尝试更新csproj文件中的ApplicationVersion属性。witch工作正常;我添加了一个运行自定义任务的目标,以从我的assemblyinfo.cs中提取AssemblyFileVersion;这是可行的,这是毫无疑问的。 但是,当我想使用更新后的ApplicationVersion确定新构建文件的放置位置时,我会在属性中设置默认值 <PropertyGroup> ... <ApplicationVersion>1.0

我一直在尝试更新csproj文件中的ApplicationVersion属性。witch工作正常;我添加了一个运行自定义任务的目标,以从我的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>

...
1.0.0.0
...
任意CPU
真的
满的
假的
..\media converter BUILD\debug\$(应用程序版本)\
调试;痕迹
促使
4.
..\media converter BUILD\debug\$(应用程序版本)\media converter.XML
我的目标

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

$(ApplicationVersionModed)
GetAssemblyFileVersion.dll或多或少是从我在internet上找到的某个帖子中偷来的,只是再也找不到了,所以我无法添加链接,抱歉

我的理论是,PropertyGroup中的转换和参数是在InitailTagets和DefaultTargets运行之前呈现的。我的计划永远不会成功

但是,如果有人知道一种使它工作的方法,我将非常感谢它在这里

我关于为什么它不工作的理论是,PropertyGroup中的转换和参数在InitailTagets和DefaultTargets都运行之前呈现确实,这就是工作原理:msbuild在文件的第一个过程中计算全局属性,您定义了OutputPath,Microsoft.Common.CurrentVersion.targets文件使用它派生OutDir/BaseMediateOutputPath/。。。。然后在另一个过程中,您的目标运行并更新版本号,但没有另一个过程再次计算全局OutputPath属性

但是,您可以覆盖目标中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>

bin\$(配置)\$(应用程序版本)\
$(输出路径)

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

;你刚刚让我不用花一天的时间为我写一个工具。