【问题标题】:Build target used by Visual Studio to do Incremental Build via msbuild command lineVisual Studio 用于通过 msbuild 命令行进行增量构建的构建目标
【发布时间】:2019-05-22 22:09:49
【问题描述】:

我在我们的 C# 项目中创建了一个任务,以便在项目在发布模式下构建(进行更改)时自动版本化项目。版本控制部分完美运行。但是,无论从命令行完成时项目是否实际更改,所有项目都在构建中。这会导致不必要地对项目进行版本控制。在 Visual Studio 中构建有效,未构建未更改的项目,但是我们制作了一个使用 msbuild.exe 进行自动构建的工具,并在我们使用 Bamboo 时将其用作临时修复,并且该方法总是进行盲构建,即使存在项目没有变化。我需要能够确定是否对项目进行了更改。

类似

'$(wasSourceUpdated)' == 'true' 或在我的自定义版本控制目标上使用的某种目标条件。

这是我在项目中的版本控制任务示例

<Import Project="..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets" Condition="Exists('..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets') And '$(Configuration)|$(Platform)' == 'Release|AnyCPU' And '$(DeployOnBuild)' != 'true'" />

我还查看了thisthis 的文章,但无济于事。

编辑

我需要在实际执行构建之前运行该任务,以便用新版本标记生成的程序集

编辑 2

我真正想要的是在我检测到程序集已更新时运行 CoreCompile 或再次运行 CoreCompile 的条件

到目前为止我已经尝试过:

<Project>
<PropertyGroup>
    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup>
    <_AssemblyTimestampBeforeCompile>%(IntermediateAssembly.ModifiedTime)</_AssemblyTimestampBeforeCompile>
</PropertyGroup>
<PropertyGroup>
    <_AssemblyTimestampAfterCompile>%(IntermediateAssembly.ModifiedTime)</_AssemblyTimestampAfterCompile>
</PropertyGroup>
<PropertyGroup>
    <_ProjectVersioned Condition="'$(_ProjectVersioned)'==''">false</_ProjectVersioned>
</PropertyGroup>
<Target Name="IncrementVersionBeforeBuild" AfterTargets="CoreCompile" Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)' and '$(_ProjectVersioned)' == 'false'">
 <Message Text="Before $(_AssemblyTimestampBeforeCompile) After $(_AssemblyTimestampAfterCompile)" Importance="High"/>
    <IncrementVersion
  ProjectPath="$(MSBuildProjectFullPath)"
    VersionRule="3.3.0.+"
    FileName="Properties\AssemblyInfo.cs">
    </IncrementVersion>
</Target>
<PropertyGroup>
    <TaskPath>$(MSBuildThisFileDirectory)..\Tasks\AutoVersionTask\AutoVersionTask\bin\Debug</TaskPath>
</PropertyGroup>
<!-- Sample import for projects
<Import Project="..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets" Condition="Exists('..\..\DXT.BuildTasks\Targets\DXTAutoIncrementVersion.targets') And '$(Configuration)|$(Platform)' == 'Release|AnyCPU' And '$(DeployOnBuild)' != 'true'" />
-->
<UsingTask AssemblyFile="$(TaskPath)\AutoVersionTask.dll" TaskName="AutoVersionTask.IncrementVersion" />

<PropertyGroup>
    <_ProjectVersioned>true</_ProjectVersioned>
</PropertyGroup>

提前致谢

【问题讨论】:

  • 您是否使用过构建后事件以及何时执行自动版本任务?在构建之后和发布之前?
  • 自动版本任务在构建之前运行。发布被跳过,因为它可能导致自动版本任务在发布时运行两次

标签: c# visual-studio msbuild


【解决方案1】:

非常感谢 Lance 让我了解 MSBuild,使我更好地理解了这个问题。

经过长时间研究默认任务后,我遇到了this 问题,该问题完美解决了我的问题。应用修复后,版本控制任务现在仅在对 msbuild 代码进行更改时运行。

输入和输出与 CoreCompile 目标相同,并确保仅在源发生更改时才运行任务

这是我运行的有效目标:

<?xml version="1.0" encoding="utf-8"?>
<Project>
    <PropertyGroup>
        <CoreCompileDependsOn>
        $(CoreCompileDependsOn);
        IncrementVersionBeforeBuild
        </CoreCompileDependsOn>
    </PropertyGroup>
    <Target Name="IncrementVersionBeforeBuild"
            Inputs="$(MSBuildAllProjects);
            @(Compile);                               
            @(_CoreCompileResourceInputs);
            $(ApplicationIcon);
            $(AssemblyOriginatorKeyFile);
            @(ReferencePath);
            @(CompiledLicenseFile);
            @(EmbeddedDocumentation); 
            $(Win32Resource);
            $(Win32Manifest);
            @(CustomAdditionalCompileInputs)"
            Outputs="@(DocFileItem);
             @(IntermediateAssembly);
             @(_DebugSymbolsIntermediatePath);                 
             $(NonExistentFile);
             @(CustomAdditionalCompileOutputs)"
    >
        <Message Text="Version Task running" Importance="High"/>
        <IncrementVersion
      ProjectPath="$(MSBuildProjectFullPath)"
        VersionRule="3.3.0.+"
        FileName="Properties\AssemblyInfo.cs">
        </IncrementVersion>
    </Target>
    <PropertyGroup>
        <TaskPath>$(MSBuildThisFileDirectory)..\Tasks\AutoVersionTask\AutoVersionTask\bin\Debug</TaskPath>
    </PropertyGroup>
    <UsingTask AssemblyFile="$(TaskPath)\AutoVersionTask.dll" TaskName="AutoVersionTask.IncrementVersion" />

    <PropertyGroup>
        <_ProjectVersioned>true</_ProjectVersioned>
    </PropertyGroup>
</Project>

【讨论】:

  • 您好,朋友,感谢您在这里分享您的解决方案。您可以考虑将其标记为答案,以便其他有类似问题的成员轻松找到解决方案!
  • 上次没让我做,之前又忘记标记了。感谢您的帮助兰斯
【解决方案2】:

一般情况下,我们可以将下面的脚本添加到 .csproj 文件中:

  <PropertyGroup>
    <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
  </PropertyGroup>
  <Target Name="AutoVersionWhenBuild" AfterTargets="CoreBuild"
          Condition="'$(_AssemblyTimestampBeforeCompile)'!='$(_AssemblyTimestampAfterCompile)'">
    <Message Importance="high" Text="Auto-version begins when changes are made!"/>
    <!--<AutoVersionTask>Do your auto-version task here.</AutoVersionTask>-->
  </Target>

它将在构建期间真正对项目进行更改时调用。看到这个similar issue

至于你的情况:

您的任务和目标似乎来自目标文件DXTAutoIncrementVersion.targets,您可以打开该文件并将其中的目标更改为上述格式。

另外:请检查taskstargets.targets文件之间的关系。

1.MSBuild 使用任务来执行这些操作。

2.Target 将任务分组在一起。

3.MSBuild 包含多个 .targets 文件,其中包含常见场景的项目、属性、目标和任务。

所以您可以modify your auto-version target in the xx.targets fileuse the script above, and call the auto-version task in the AutoVersionWhenBuild target。希望对你有帮助:)

【讨论】:

  • 嗨兰斯,感谢您的回答!我会尝试一下并更新这个问题。我确实制作了自定义目标,因为我们在多个项目文件中使用它。
  • 嗨 Lance,似乎有一个误解,任务需要在构建之前运行,而不是之后。我们需要在创建的二进制文件上更新版本。
  • @Kaizer69 抱歉造成误会,我正在研究这个。也许需要一些时间:(
  • 谢谢 Lance,别担心我也在研究它,但我只是在寻求帮助
最近更新 更多