我们可以给.NET Core应用定义版本号,但如何在程序运行时读取呢?有几种做法。
首先,我们来看看一个典型的带有版本号的.NET Core工程。我们可以定义在工程文件(.csproj)上定义AssemblyVersion, FileVersion 以及 Version。
AssemblyVersion 和 FileVersion 属性必须用这样的格式 "major[.minor[.build[.revision]]]" 不然你会得到一个编译错误 (CS7034).
Version 可以包含自定义字符串,比如"-xyz"
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AssemblyVersion>1.1.1.1</AssemblyVersion>
<FileVersion>2.2.2.2</FileVersion>
<Version>3.3.3.3-xyz</Version>
</PropertyGroup>
</Project>
在运行时,它会生成一个class文件
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("2.2.2.2")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("3.3.3.3-xyz")]
[assembly: System.Reflection.AssemblyProductAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyTitleAttribute("netcoreappver")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.1.1.1")]
// Generated by the MSBuild WriteCodeFragment class.
基于以上的定义,我们来看看程序运行时怎么获取这些信息
1. AssemblyVersion
取得AssemblyVersion有两种方法。
如果你不在一个static方法里获取版本号,可以用:
GetType().Assembly.GetName().Version.ToString()
但是如果你想要在static方法里使用,可能就得创建一个别的类型,就像这样:
class Foo
{
public string GetAssemblyVersion()
{
return GetType().Assembly.GetName().Version.ToString();
}
}
然后
new Foo().GetAssemblyVersion()
这样的代码明显很丑陋。其实读取AssemblyVersion还有另一个方法:
Assembly.GetEntryAssembly().GetName().Version
这个方法在static或非static方法里都可以使用,两者返回的结果都是:1.1.1.1
2. FileVersion
我们可以使用 GetCustomAttribute 拓展方法去获得 AssemblyFileVersionAttribute 并且读取 Version 属性。
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version
它返回的是:2.2.2.2
3. Version
和 FileVersion 类似,但是这次我们用的是 AssemblyInformationalVersionAttribute
Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion
它返回的是:3.3.3.3
4. 完整案例代码
using System;
using System.Reflection;
namespace netcoreappver
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"GetType().Assembly.GetName().Version: " +
$"{new Foo().GetAssemblyVersion()}");
Console.WriteLine($"Assembly.GetEntryAssembly().GetName().Version: " +
$"{Assembly.GetEntryAssembly().GetName().Version}");
Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version:" +
$"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyFileVersionAttribute>().Version}");
Console.WriteLine($"Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion:" +
$"{Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute> ().InformationalVersion}");
Console.ReadKey();
}
}
class Foo
{
public string GetAssemblyVersion()
{
return GetType().Assembly.GetName().Version.ToString();
}
}
}
5. 我该选择哪个版本号
根据这篇帖子 https://stackoverflow.com/questions/64602/what-are-differences-between-assemblyversion-assemblyfileversion-and-assemblyin
AssemblyVersion
引用你的程序集的其他程序集看到的版本。如果版本号改变,其他程序集必须更新引用。
AssemblyFileVersion
部署使用的版本号。你可以每次部署都增加版本号。这通常被安装程序使用。用它来标记相同AssemblyVersion但由不同build产生的程序集。
在Windows中,可以用文件属性对话框看到它。
如果可能的话,让MSBuild去自动生成它。AssemblyFileVersion是可选的,如果没有指定的话,会使用AssemblyVersion。
我使用这种格式: major.minor.revision.build, 这是我在部署中使用的修订版 (Alpha, Beta, RC and RTM), 服务包,和热修改。
AssemblyInformationalVersion
程序集所在的产品版本。这是你用来给用户显示的版本号。这可以是个字符串,比如'1.0 Release Candidate'。