.NET Core 6 WPF与类库版本管理新手求助:版本号及显示问题
一、三种版本号的核心区别
程序集版本(Assembly Version)
这是.NET识别程序集的唯一身份标识,格式为四段式x.x.x.x。如果你的类库是强命名程序集,这个版本号变化后,依赖它的WPF应用必须重新引用新的程序集,否则会出现绑定失败的错误。它主要作用于程序集的内部绑定逻辑,一般用户不需要关注。
文件版本(File Version)
这是Windows系统文件属性里显示的版本号,同样是四段式x.x.x.x,作用是给用户、运维人员看的,用来标识文件的具体迭代状态。它不影响.NET程序集的绑定,可以和程序集版本不一致,比如你修复了一个小bug但不想改变程序集版本,就可以只更新文件版本。
包版本(Package Version)
如果你的自定义类库MyLib是作为NuGet包发布的,这个就是NuGet仓库里的版本号,格式为三段式x.x.x(也可以加预发布标签,比如1.0.0-beta)。它用来管理包的发布、依赖更新,和程序集版本、文件版本是独立的,但通常会保持对应关系(比如包版本1.0.0对应程序集版本1.0.0.0)。
二、Visual Studio项目属性里的版本配置解释
你看到的$(VersionPrefix)是MSBuild的变量,默认定义在项目文件的<PropertyGroup>节点中(如果没找到,是因为SDK风格项目默认隐藏了部分配置),它的作用是统一管理版本前缀,包版本默认会使用这个变量的值,所以输入框显示$(VersionPrefix),下方是解析后的实际值1.0.0。
程序集版本和文件版本输入框为空,是因为SDK风格的WPF项目默认会自动基于VersionPrefix生成这两个版本:程序集版本默认是$(VersionPrefix).0,文件版本也是$(VersionPrefix).0。如果需要自定义,你可以手动在项目文件中添加以下配置:
<PropertyGroup> <VersionPrefix>1.0.0</VersionPrefix> <AssemblyVersion>1.0.0.0</AssemblyVersion> <FileVersion>1.0.0.1</FileVersion> <!-- 自定义文件版本 --> </PropertyGroup>
至于三段式和四段式的区别:程序集版本是.NET的强制要求(必须四段),而包版本遵循NuGet的规范,用三段式更简洁,同时支持预发布后缀扩展。
三、版本管理实践建议
1. 统一版本命名规则
采用语义化版本(SemVer)规则:主版本号.次版本号.修订号
- 主版本号:当有不兼容的API变更时升级(比如
1.0.0→2.0.0) - 次版本号:新增兼容性功能时升级(比如
1.0.0→1.1.0) - 修订号:修复bug、小改动时升级(比如
1.0.0→1.0.1)
预发布版本可以加后缀,比如1.1.0-beta1用于测试版本。
2. 统一管理版本配置
为了避免MyApp和MyLib版本不一致,建议在解决方案根目录创建Directory.Build.props文件,统一配置版本变量,所有项目都会自动继承:
<Project> <PropertyGroup> <VersionPrefix>1.0.0</VersionPrefix> <AssemblyVersion>$(VersionPrefix).0</AssemblyVersion> <FileVersion>$(VersionPrefix).$(BuildNumber)</FileVersion> <!-- 如果有CI构建号,可以替换$(BuildNumber) --> </PropertyGroup> </Project>
3. 在「关于」窗口显示版本与构建时间
获取应用和类库版本
// 获取WPF应用的程序集版本 var appAssemblyVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); // 获取WPF应用的文件版本 var appFileVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo( System.Reflection.Assembly.GetExecutingAssembly().Location ).FileVersion; // 获取MyLib的程序集版本(假设MyLib中有MyClass类) var libAssembly = System.Reflection.Assembly.GetAssembly(typeof(MyLib.MyClass)); var libAssemblyVersion = libAssembly.GetName().Version.ToString(); // 获取MyLib的文件版本 var libFileVersion = System.Diagnostics.FileVersionInfo.GetVersionInfo(libAssembly.Location).FileVersion;
获取构建时间
可以在构建时注入时间戳,在Directory.Build.props中添加:
<PropertyGroup> <BuildDateTime>$([System.DateTime]::UtcNow.ToString("yyyy-MM-dd HH:mm:ss UTC"))</BuildDateTime> </PropertyGroup>
然后在WPF项目的Resources.resx中添加一个字符串资源BuildTime,值设为$(BuildDateTime),最后在代码中读取:
var buildTime = Properties.Resources.BuildTime;
4. 迭代更新流程
- 每次发布前,统一更新
Directory.Build.props中的VersionPrefix,确保MyApp和MyLib版本匹配; - 如果
MyLib有API不兼容变更,升级主版本号,同时MyApp必须重新引用新的MyLib版本; - 发布时用Git标签记录版本,比如
git tag v1.0.0,方便后续回溯; - 若用安装包发布(如ClickOnce、Wix),确保安装包版本和应用版本一致。
内容的提问来源于stack exchange,提问作者patsy2k

