Assembly.GetExecutingAssembly().GetName().Version 获取的是编译时固定的 AssemblyVersion,修改 AssemblyInfo.cs 无效;SDK 风格项目中版本由 .csproj 的 <Version> 或 <AssemblyVersion> 决定,修改后必须重新生成。

Assembly.GetExecutingAssembly().GetName().Version 拿到的是编译时版本,不是你改过的 AssemblyInfo.cs
很多人改了 AssemblyVersion 或 AssemblyFileVersion 后,用 Assembly.GetExecutingAssembly().GetName().Version 读出来还是旧值,以为代码没生效。其实它只读 AssemblyVersion,而且这个值一旦编译进 DLL/EXE 就固定了——哪怕你后来手动改了源码、没重新编译,它也不会变。
-
AssemblyVersion控制强命名和绑定重定向,必须在编译前定死;改了就得重新编译整个程序集 -
AssemblyFileVersion和AssemblyInformationalVersion是纯元数据,运行时可读,但要用对应属性取:FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion - 如果项目用 SDK 风格(.csproj 里有
<Sdk>Microsoft.NET.Sdk</Sdk>),AssemblyVersion默认由<Version>或<AssemblyVersion>MSBuild 属性生成,不是靠AssemblyInfo.cs文件
SDK 风格项目里,版本号实际来自 .csproj,不是 AssemblyInfo.cs
新建的 .NET 5+ 或较新 .NET Framework SDK 项目,Properties/AssemblyInfo.cs 往往是空的或被删了。所有版本相关属性都挪到了 .csproj 文件里。这时候改 AssemblyInfo.cs 完全无效。
- 查当前生效的
AssemblyVersion:看.csproj中有没有<AssemblyVersion>1.2.3.4</AssemblyVersion>;没写的话,默认取<Version>1.2.3</Version>的主副次三位补零(比如1.2.3→1.2.3.0) -
AssemblyFileVersion默认也继承<Version>,但可单独设:<FileVersion>1.2.3.42</FileVersion> - 修改后必须重新生成(build),而不是仅保存文件——MSBuild 在编译阶段才把它们注入到程序集元数据中
想读“用户看到的版本号”,优先用 AssemblyInformationalVersion
Windows 资源管理器“属性→详细信息”里显示的“产品版本”,或者安装包、发布说明里写的那个带字母的版本(如 2.1.0-beta),对应的是 AssemblyInformationalVersion。它不参与绑定,但最贴近业务语义。
- 获取方式:
Assembly.GetExecutingAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion - 它在 SDK 项目中默认等于
<Version>,但可以显式覆盖:<AssemblyInformationalVersion>2.1.0-rc.1</AssemblyInformationalVersion> - 注意:这个值是字符串,不能直接当
Version对象解析;含非数字字符(如-beta)时,new Version(str)会抛ArgumentException
调试时发现版本号没更新?先确认是不是在读错程序集
常见误操作是调用了 Assembly.GetCallingAssembly() 或硬编码了某个类型(比如 typeof(Program).Assembly),结果读的是引用库的版本,不是当前执行项目的。
- 最稳妥的是
Assembly.GetExecutingAssembly()—— 它返回当前正在执行的那行代码所在的程序集 - 如果在类库中封装了版本读取逻辑,又希望返回宿主应用的版本,那就得靠调用方传入
Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly() - ASP.NET Core 应用中,
GetEntryAssembly()可能为 null(因为入口点是托管进程),此时应 fallback 到Assembly.GetCallingAssembly()或明确指定主程序集类型
版本号不是写在哪就从哪读的,关键看编译时谁写了元数据、运行时你找的是哪个程序集。最容易漏掉的其实是:改完 .csproj 没 rebuild,或者在多层引用里拿错了 Assembly 实例。