C#文件版本信息获取 C#如何读取exe或dll的版本号

来源:这里教程网 时间:2026-02-21 17:42:59 作者:

FileVersionInfo.GetVersionInfo
读取文件版本信息

最直接可靠的方式是调用

FileVersionInfo.GetVersionInfo
,它能解析 Windows PE 文件(.exe、.dll)中嵌入的版本资源,不依赖文件名或扩展名,也不要求程序正在运行。

注意:该方法读取的是文件的 文件版本(File Version),不是程序集版本(Assembly Version),二者可能不同。

传入完整路径,如
"C:\MyApp\app.exe"
;相对路径需确保当前工作目录正确
若文件无版本资源(如未在项目属性中设置“程序集信息”或未嵌入版本块),会返回默认值(如 0.0.0.0)且不抛异常 支持 .NET Framework 和 .NET Core / .NET 5+,但 .NET Core 3.1+ 中需引用
System.Diagnostics.FileVersionInfo
命名空间(已内置,无需额外 NuGet)

FileVersionInfo.FileVersion
ProductVersion
的区别

同一个文件里常有两个关键字符串版本字段:

FileVersion
(文件版本)和
ProductVersion
(产品版本),它们在 Visual Studio 的“程序集信息”对话框中分别对应“文件版本”和“产品版本”输入框。

常见误区是只读

FileVersion
,但有些发布流程(如 MSBuild 自动递增)实际更新的是
ProductVersion
,而
FileVersion
被固定为 1.0.0.0。

fileVersionInfo.FileVersion
→ 对应
VS_VERSIONINFO.dwFileVersionMS/dwFileVersionLS
fileVersionInfo.ProductVersion
→ 对应
VS_VERSIONINFO.dwProductVersionMS/dwProductVersionLS
两者都是字符串形式(如
"2.1.3.0"
),不是
Version
类型,需手动
Version.Parse()
才能比较

读取程序集版本(
AssemblyVersion
)要换方式

如果你真正想获取的是 C# 编译时写死的

[assembly: AssemblyVersion("1.2.3.4")]
,那
FileVersionInfo
不管用——它读不到 IL 元数据,只能读资源段。

此时必须加载程序集(注意:会触发 JIT 加载,有副作用),再查

AssemblyName.Version

try
{
    var asm = Assembly.LoadFrom(@"C:MyApplib.dll");
    var version = asm.GetName().Version; // 这才是 AssemblyVersion
}
catch (BadImageFormatException)
{
    // 非托管 DLL、架构不匹配(x86/x64)、.NET 版本不兼容时抛此异常
}
Assembly.LoadFrom
会执行静态构造函数、触发类型初始化,慎用于生产环境读取第三方 DLL
若只需元数据不执行代码,可用
AssemblyLoadContext.Default.LoadFromAssemblyPath
(.NET 5+)或
Assembly.ReflectionOnlyLoadFrom
(旧版,仅限检查,不能调用)
对于当前正在运行的程序集,直接用
typeof(Program).Assembly.GetName().Version
更安全

常见错误:路径不存在、权限不足、UAC 虚拟化干扰

调用

FileVersionInfo.GetVersionInfo
时突然报
FileNotFoundException
或返回空版本,大概率不是代码问题,而是路径或权限卡点。

检查路径是否含中文、空格、特殊符号;用
Path.GetFullPath
规范化后再传入
Windows 应用商店应用(UWP)或受限制沙盒中无法访问任意磁盘路径,会静默失败 32 位进程尝试读取
C:Program Files
下的 64 位程序时,可能被文件系统重定向到
Program Files (x86)
,或因 UAC 虚拟化把路径映射到用户配置目录
某些杀毒软件或 EDR 会 hook 文件读取 API,导致
GetVersionInfo
返回空或异常——可先用
File.Exists
确认文件可访问

版本信息本身不加密也不校验,读出来就是资源节里存的字符串。真要防篡改,得靠签名验证(

Assembly.GetName().GetPublicKeyToken()
或 Authenticode)。

相关推荐

热文推荐