Determine assembly version during a post-build event

后端 未结 10 1438
故里飘歌
故里飘歌 2020-11-27 11:58

Let\'s say I wanted to create a static text file which ships with each release. I want the file to be updated with the version number of the release (as specified in A

相关标签:
10条回答
  • 2020-11-27 12:23

    If you prefer scripting these methods might also work for you:

    If you are using the post-build event, you can use the filever.exe tool to grab it out of the already built assembly:

    for /F "tokens=4" %%F in ('filever.exe /B /A /D bin\debug\myapp.exe') do (
      set VERSION=%%F
    )
    echo The version is %VERSION%
    

    Get filever.exe from here: http://support.microsoft.com/kb/913111

    If you are using the pre-build event, you can take it out of the AssemblyInfo.cs file as follows:

    set ASMINFO=Properties\AssemblyInfo.cs
    FINDSTR /C:"[assembly: AssemblyVersion(" %ASMINFO% | sed.exe "s/\[assembly: AssemblyVersion(\"/SET CURRENT_VERSION=/g;s/\")\]//g;s/\.\*//g" >SetCurrVer.cmd
    CALL SetCurrVer.cmd
    DEL SetCurrVer.cmd
    echo Current version is %CURRENT_VERSION%
    

    This uses the unix command line tool sed, which you can download from many places, such as here: http://unxutils.sourceforge.net/ - iirc that one works ok.

    0 讨论(0)
  • 2020-11-27 12:30

    I looked for the same feature and i found the solution on MSDN. https://social.msdn.microsoft.com/Forums/vstudio/de-DE/e9485c92-98e7-4874-9310-720957fea677/assembly-version-in-post-build-event?forum=msbuild

    $(ApplicationVersion) did the Job for me.

    Edit:

    Okay I just saw the Problem $(ApplicationVersion) is not from AssemblyInfo.cs, its the PublishVersion defined in the project Properties. It still does the job for me in a simple way. So maybe someone needs it too.

    Another Solution:

    You can call a PowerShell script on PostBuild, here you can read the AssemblyVersion directly from your Assembly. I call the script with the TargetDir as Parameter

    PostBuild Command:

    PowerShell -ExecutionPolicy Unrestricted $(ProjectDir)\somescript.ps1 -TargetDir $(TargetDir)
    

    PowerShell Script:

    param(
        [string]$TargetDir
    )
    
    $Version = (Get-Command ${TargetDir}Example.exe).FileVersionInfo.FileVersion
    

    This way you will get the Version from the AssemblyInfo.cs

    0 讨论(0)
  • 2020-11-27 12:32

    As a workaround I've written a managed console application which takes the target as a parameter, and returns the version number.

    I'm still interested to hear a simpler solution - but I'm posting this in case anyone else finds it useful.

    using System;
    using System.IO;
    using System.Diagnostics;
    using System.Reflection;
    
    namespace Version
    {
        class GetVersion
        {
            static void Main(string[] args)
            {
                if (args.Length == 0 || args.Length > 1) { ShowUsage(); return; }
    
                string target = args[0];
    
                string path = Path.IsPathRooted(target) 
                                    ? target 
                                    : Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName) + Path.DirectorySeparatorChar + target;
    
                Console.Write( Assembly.LoadFile(path).GetName().Version.ToString(2) );
            }
    
            static void ShowUsage()
            {
                Console.WriteLine("Usage: version.exe <target>");
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-27 12:33

    This answer is a minor modification of the answer of Brent Arias. His PostBuildMacro worked quite well for me until a version update of Nuget.exe.

    In the recent releases, Nuget trims non significant parts of the package version number in order to obtain a semantic version like "1.2.3". For example, the assembly version "1.2.3.0" is formatted by Nuget.exe "1.2.3". And "1.2.3.1" is formatted "1.2.3.1" as expected.

    As I need to infer the exact package filename generated by Nuget.exe, I use now this adaptated macro (tested in VS2015):

    <Target Name="PostBuildMacros">
      <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
        <Output TaskParameter="Assemblies" ItemName="Targets" />
      </GetAssemblyIdentity>
      <ItemGroup>
        <VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace(&quot;%(Targets.Version)&quot;, &quot;^(.+?)(\.0+)$&quot;, &quot;$1&quot;))" />
      </ItemGroup>
    </Target>
    <PropertyGroup>
      <PostBuildEventDependsOn>
        $(PostBuildEventDependsOn);
        PostBuildMacros;
      </PostBuildEventDependsOn>    
      <PostBuildEvent>echo HELLO, THE ASSEMBLY VERSION IS: @(VersionNumber)</PostBuildEvent>
    </PropertyGroup>
    

    UPDATE 2017-05-24: I corrected the regex in this way: "1.2.0.0" will be translated to "1.2.0" and not "1.2" as previously coded.


    And to answer to a comment of Ehryk Apr, you can adapt the regex to keep only some part of the version number. As an example to keep "Major.Minor", replace:

    <VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace(&quot;%(Targets.Version)&quot;, &quot;^(.+?)(\.0+)$&quot;, &quot;$1&quot;))" />
    

    By

    <VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace(&quot;%(Targets.Version)&quot;, &quot;^([^\.]+)\.([^\.]+)(.*)$&quot;, &quot;$1.$2&quot;))" />
    
    0 讨论(0)
  • 2020-11-27 12:37

    If (1) you don't want to download or create a custom executable that retrieves the assembly version and (2) you don't mind editing the Visual Studio project file, then there is a simple solution that allows you to use a macro which looks like this:

    @(Targets->'%(Version)')

    @(VersionNumber)
    

    To accomplish this, unload your project. If the project somewhere defines a <PostBuildEvent> property, cut it from the project and save it elsewhere temporarily (notepad?). Then at the very end of the project, just before the end-tag, place this:

    <Target Name="PostBuildMacros">
      <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
        <Output TaskParameter="Assemblies" ItemName="Targets" />
      </GetAssemblyIdentity>
      <ItemGroup>
        <VersionNumber Include="@(Targets->'%(Version)')"/>
      </ItemGroup>
    </Target>
    <PropertyGroup>
      <PostBuildEventDependsOn>
        $(PostBuildEventDependsOn);
        PostBuildMacros;
      </PostBuildEventDependsOn>    
      <PostBuildEvent>echo HELLO, THE ASSEMBLY VERSION IS: @(VersionNumber)</PostBuildEvent>
    </PropertyGroup>
    

    This snippet has an example <PostBuildEvent> already in it. No worries, you can reset it to your real post-build event after you have re-loaded the project.

    Now as promised, the assembly version is available to your post build event with this macro:

    @(VersionNumber)
    

    Done!

    0 讨论(0)
  • 2020-11-27 12:37

    From that what I understand...

    You need a generator for post build events.

    1. Step: Writing a Generator

    /*
    * Author: Amen RA
    * # Timestamp: 2013.01.24_02:08:03-UTC-ANKH
    * Licence: General Public License
    */
    using System;
    using System.IO;
    
    namespace AppCast
    {
        class Program
        {
            public static void Main(string[] args)
            {
                // We are using two parameters.
    
                // The first one is the path of a build exe, i.e.: C:\pathto\nin\release\myapp.exe
                string exePath = args[0];
    
                // The second one is for a file we are going to generate with that information
                string castPath = args[1];
    
                // Now we use the methods below
                WriteAppCastFile(castPath, VersionInfo(exePath));
            }
    
    
            public static string VersionInfo(string filePath)
            {
                System.Diagnostics.FileVersionInfo myFileVersionInfo = System.Diagnostics.FileVersionInfo.GetVersionInfo(filePath);
                return myFileVersionInfo.FileVersion;
            }
    
    
            public static void WriteAppCastFile(string castPath, string exeVersion)
            {
                TextWriter tw = new StreamWriter(castPath);
                tw.WriteLine(@"<?xml version=""1.0"" encoding=""utf-8""?>");
                tw.WriteLine(@"<item>");
                tw.WriteLine(@"<title>MyApp - New version! Release " + exeVersion + " is available.</title>");
                tw.WriteLine(@"<version>" + exeVersion + "</version>");
                tw.WriteLine(@"<url>http://www.example.com/pathto/updates/MyApp.exe</url>");
                tw.WriteLine(@"<changelog>http://www.example.com/pathto/updates/MyApp_release_notes.html</changelog>");
                tw.WriteLine(@"</item>");
                tw.Close();
            }
        }
    }
    

    2. Step: Using it as a post build command in our IDE

    After the application is running satisfyingly for you:

    In your development IDE, use the following command line for post build events.

    C:\Projects\pathto\bin\Release\AppCast.exe "C:\Projects\pathto\bin\Release\MyApp.exe" "c:\pathto\www.example.com\root\pathto\updates\AppCast.xml"
    
    0 讨论(0)
提交回复
热议问题