Determine assembly version during a post-build eve

2020-01-25 04:41发布

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 AssemblyInfo.cs), but I don't want to have to do this manually.

I was hoping I could use a post-build event and feed the version number to a batch file like this:

call foo.bat $(AssemblyVersion)

However I can't find any suitable variable or macro to use.

Is there a way to achieve this that I've missed?

10条回答
迷人小祖宗
2楼-- · 2020-01-25 05:12

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"
查看更多
Animai°情兽
3楼-- · 2020-01-25 05:13

I needed exactly this for automatically putting the number in the readme file in the output folder. In the end, as Winston Smith showed, a small external tool is a very good solution for that, and it has the advantage you can format it however you want.

This app outputs the formatted version to the console. I used it in my post-build events to build the readme file by calling it with >> to redirect its output to the readme file.

public class GetVerNum
{
    static void Main(String[] args)
    {
        if (args.Length == 0)
            return;
        try
        {
            FileVersionInfo ver = FileVersionInfo.GetVersionInfo(args[0]);
            String version = "v" + ver.FileMajorPart.ToString() + "." + ver.FileMinorPart;
            if (ver.FileBuildPart > 0 || ver.FilePrivatePart > 0)
                version += "." + ver.FileBuildPart;
            if (ver.FilePrivatePart > 0)
                version += "." + ver.FilePrivatePart;
            Console.Write(version);
        }
        catch { }
    }
}

My post-build events:

<nul set /p dummyset=My Application > "$(ProjectDir)\Readme\readme-header.txt"
"$(ProjectDir)\Readme\GetVersionNumber.exe" "$(TargetPath)" >>"$(ProjectDir)\Readme\readme-header.txt"
echo  by Nyerguds>>"$(ProjectDir)\Readme\readme-header.txt"
echo Build date: %date% %time% >> "$(ProjectDir)\Readme\readme-header.txt"
echo.>>"$(ProjectDir)\Readme\readme-header.txt"
copy /b "$(ProjectDir)\Readme\readme-header.txt" + "$(ProjectDir)\Readme\readme-body.txt" "$(TargetDir)\$(ProjectName).txt"

I put all the readme generating related stuff in the \Readme\ folder of my project; the app containing the above code, and the "readme-body.txt" containing the actual readme stuff.

  • First line: create the "readme-header.txt" file in the \Readme\ folder of my project, and put the program name inside it. (The <nul set /p dummyset= is a trick I found here: Windows batch: echo without new line). You could also store this string in another text file and just copy that to "readme-header.txt" instead.
  • Second line: run the version number retrieving app with the freshly-generated exe file as parameter, and add its output to the header file.
  • Third line: add any other stuff (in this case, credits) to the header file. This also adds a line break to the end.

These three together give you a "readme-header.txt" file with "My Application v1.2.3 by Nyerguds", followed by a line break, in it. Then I add the build date and another open line, and copy the header file and the readme body file together to one file in the final build folder. Note that I specifically use binary copy, otherwise it gives odd results. You do have to make sure the body file contains no UTF-8 byte order mark at the start, or you get weird bytes in your final file.

查看更多
Root(大扎)
4楼-- · 2020-01-25 05:15

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

查看更多
祖国的老花朵
5楼-- · 2020-01-25 05:17

I've started adding a separate project that builds last and adding a post build event to that project that runs itself. Then I just perform my post build steps programmatically in there.

It makes it a lot easier to do stuff like this. Then you can just inspect the assembly attributes of whatever assembly you want. So far it's working pretty awesome.

查看更多
登录 后发表回答