MSBuild: Ensure a target is run before any other build steps

别等时光非礼了梦想. 提交于 2019-12-13 12:04:19

问题


I am trying to have the AssemblyInfo.cs file updated to reflect the next Publish version of the project BEFORE any other build steps occur.

in my project file i added before the end:

<Import Project="$(ProjectDir)Properties\PublishVersion.proj" />

PublishVersion.proj looks like this:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<Target Name="BeforeBuild">
    <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
        <Output TaskParameter="OutputVersion" PropertyName="SetVersion" />
    </FormatVersion>
    <FileUpdate Files="$(ProjectDir)Properties\AssemblyInfo.cs"
       Regex="\d+\.\d+\.\d+\.\d+"
       ReplacementText="$(SetVersion)" />
</Target>
</Project>

Now it does execute somewhere before building completes but definitely not before it starts, because when i look at the generated exe it has a file version that was in AssemblyInfo.cs BEFORE build started but the .application file and manifest file have various references to the new version.

resulting manifest file(1.0.0.0 before build start, 1.0.0.4 after build):

<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly ...>
  <asmv1:assemblyIdentity name="BHTechSupport.exe" version="1.0.0.4" ... />
  ...
  <entryPoint>
    <assemblyIdentity name="BHTechSupport" version="1.0.0.0" ... />
    ...
  </entryPoint>
  ...
  <dependency>
    <dependentAssembly ... codebase="BHTechSupport.exe" ...>
      <assemblyIdentity name="BHTechSupport" version="1.0.0.0" ... />
      ...
    </dependentAssembly>
  </dependency>
  ...
</asmv1:assembly>

so how do i ensure that my target gets executed before EVERYTHING else?

making changes to PublishVersion.proj sometimes seem to not take effect and i need to clean the solution and restart visual studio before effecting.


回答1:


Maybe you have to use BeforeBuild target.

so how do i ensure that my target gets executed before EVERYTHING else?

To check your target execution, you can change the MSBuild project build output verbosity to Diagnostic. Find it under the Tools > Options > Projects and Solutions > Build and Run. Then build the project and find your target in the output window.

making changes to PublishVersion.proj sometimes seem to not take effect and i need to clean the solution and restart visual studio before effecting.

AFAIK, the Visual Studio loads target files once, so you have to reload your project to see the result.

Update I don't know your versioning system, whereas it's not important. Anyway, I tried to provide a simple example for you.

using System;
using System.IO;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;

namespace Foo.Build.Tasks {

    public sealed class GenerateVersion : Task {

        [Output]
        public ITaskItem[] GeneratedFiles { get; private set; }

        public override bool Execute() {
            string objPath = Path.Combine(Path.GetDirectoryName(this.BuildEngine3.ProjectFileOfTaskNode), "obj");
            string path = Path.Combine(objPath, "VersionInfo.cs");

            File.WriteAllText(path, @"using System.Reflection;
[assembly: AssemblyVersion(""2.0.0"")]");

            GeneratedFiles = new[] { new TaskItem(path) };

            return true;
        }

    }

}

The preceding task generates a file that contains AssemblyVersion metadata or everything you want.

At last, you have to change your project file as follows:

<UsingTask TaskName="Foo.Build.Tasks.GenerateVersion" AssemblyFile="Foo.Build.Tasks.dll" />

<Target Name="BeforeBuild">
  <GenerateVersion>
    <Output TaskParameter="GeneratedFiles" ItemName="Compile" />
  </GenerateVersion>
</Target>



回答2:


If you want a target to run at the beginning of every build regardless of what end-goal target is called (Clean, Restore, Build, Publish) you can use the InitialTargets attribute of the Project element.



来源:https://stackoverflow.com/questions/8067654/msbuild-ensure-a-target-is-run-before-any-other-build-steps

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!