AssemblyVersion, AssemblyFileVersion und der Autoinkrement

AssemblyVersion, AssemblyFileVersion und der Autoinkrement

Für AssemblyVersion bieten die MS-Compiler eine komfortable Möglichkeit, die Versions-, Build- usw. -nummer hochzuzählen. Daraus läßt sich mit ein wenig Magie sogar der Buildzeitpunkt wieder rekonstruieren. Das liegt daran, das die auf * gesetzten Werte nicht einfach hochzählen, sondern den aktuellen Zeitpunkt in Integer-Werte umwandeln.

Leider bietet eine sich ändernde AssemblyVersion auch Nachteile: so muß man z. B. abhängige Projekte immer wieder neu builden, oder zumindest die Option „Specific Version” in den Eigenschaften der Referenz ausschalten.

Etwas flexibler ist man mit der AssemblyFileVersion – diese bietet jedoch von Hause aus kein Auto-Inkrement.

So scheint die AssemblyFileVersion, die man sowohl programmatisch wie auch über den Windows-Explorer (Rechtsklick->Eigenschaften) auslesen kann, erst einmal keine Option zu sein.

Build-Zeit im Build-Event setzen

Mit ein wenig Build-Event-Magie läßt sich dies jedoch ändern.

Was, wenn wir eine Datei zur Compilezeit erzeugen (als Pre-Build-Event), dort die Eigenschaft AssemblyFileVersion setzen, und diese Datei dann in unser Projekt einbinden?

Muß es wirklich so kompliziert sein?

In den meisten Anwendungsfällen reicht es auch aus, sich das letzte Änderungsdatum der Assembly anzeigen zu lassen. Dieses ändert sich typischerweise nach dem Buildzeitpunkt nicht mehr und steht so ständig auf dem Zeitpunkt des Builds.

Sollte ein bestimmter Buildzeitpunkt später nachgewiesen werden müssen, oder man allgemein auch eine Versionsinformation benötigen (z. B., weil diese nachgehalten werden muß, Stichwort Nachvollziehbarkeit) bietet diese Lösung natürlich Vorteile.

Noch einfacher geht es, wenn wir ein Versionsverwaltungssystem verwenden wie z. B. Subversion, Mercurial oder GIT, die Revisionen mit jedem Checkin hochzählen, hier könnten wir uns direkt die aktuelle Revision (so wir denn immer aktuell builden) aus dem Repository holen und auf ähnliche Weise als Eigenschaft in eine Datei schreiben.

Am besten legt man so eine Datei direkt in das Properties-Unterverzeichnis, wo bereits die AssemblyInfo.cs wartet. Das Pre-Build-Event sieht dann so aus:

echo [assembly:System.Reflection.AssemblyFileVersion("%date:~-4,4%.%date:~-7,2%%date:~-10,2%.%time:~0,2%%time:~3,2%.%time:~-5,2%")] > $(ProjectDir)PropertiesVersionInfo.cs

Nachdem wir das Projekt einmal compiliert haben, existiert die neue Datei. Diese binden wir nun in das Projekt an die passende Stelle (Properties-Unterordner) ein. Von nun an werden die in der erzeugten .cs-Datei enthaltenen Informationen Teil unserer Assembly.

Auslesen lassen sich diese Werte auch wieder.

Build-Zeit später wieder auslesen

Hierzu benötigen wir die AssemblyFileVersion, die wir per FileVersionInfo.GetVersionInfo auslesen können. Der Übersicht halber lese ich zusätzlich noch die AssemblyVersion aus, und baue am Ende einen String, der Versionsinformation sowie Builddatum enthält. Die Rechenroutine ist wenig ausgefeilt – mit bloßem Auge kann man anhand der AssemblyFileVersion bereits das Datum sehen. Das soll auch so sein.

1
2
3
4
5
6
7
8
9
10
11
12
 public static String GetVersionString(Assembly assembly, bool withDate)
{
    var version = assembly.GetName().Version;
    var fileVersionString = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion;
    Version fileVersion = new Version(fileVersionString);
    int major = version.Major;
    int minor = version.Minor;
    int build = version.Build;
    var buildDateTime = new DateTime(fileVersion.Major, fileVersion.Minor / 100, fileVersion.Minor % 100, fileVersion.Build / 100, fileVersion.Build % 100, fileVersion.Revision);
    string date = buildDateTime.ToShortDateString() + " " + buildDateTime.ToShortTimeString();
    return major + "." + minor + "." + build + (withDate ? (" (" + date + ")") : "");
}

AssemblyVersion in Zeitpunkt umwandeln

Sollte man doch die vom Studio angebotene Notation der Version mit *.* benutzt haben, so läßt sich der Buildzeitpunkt übrigens folgendermaßen berechnen:

1
2
3
4
5
6
7
8
 public static String GetVersionString(Assembly assembly, bool withDate)
{
    var version = assembly.GetName().Version;
    var buildDateTime = new DateTime(2000, 1, 1).Add(new TimeSpan(TimeSpan.TicksPerDay * version.Build + // days since 1 January 2000
        TimeSpan.TicksPerSecond * 2 * version.Revision)); // seconds since midnight, (multiply by 2 to get original)
    string date = buildDateTime.ToShortDateString();
    return major + "." + minor + "." + build + (withDate ? (" (" + date + ")") : "");
}

siehe auch

One thought on “AssemblyVersion, AssemblyFileVersion und der Autoinkrement

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.