C#怎么获取程序集的名称和版本_C#如何读取Assembly信息【代码】

尼克

尼克

2026-03-28

588人浏览

原创

Assembly.GetExecutingAssembly() 是获取当前程序集名称和版本最直接安全的方式,它不依赖路径,返回调用代码所在程序集,但需注意与 GetCallingAssembly() 区分,且其 Version 属性仅为四段数字,语义化版本需通过 AssemblyInformationalVersionAttribute 获取。

Assembly.GetExecutingAssembly() 获取当前程序集信息最直接

多数时候你只是想知道自己写的这个 dll 或 exe 叫什么、版本多少,assembly.getexecutingassembly() 是最轻量、最不容易出错的选择。它不依赖路径、不查文件系统,直接从运行时上下文拿元数据。

常见错误是误用 Assembly.GetCallingAssembly() —— 它返回的是调用栈上一层的程序集,比如你在 NuGet 包里封装了这个逻辑,那拿到的就不是你的主程序集。

  • 在控制台或 WinForms 主程序里,GetExecutingAssembly() 返回的就是 .exe 对应的程序集
  • 在类库(.dll)中调用,返回的是该 .dll 的程序集,不是引用它的宿主
  • 如果在 ASP.NET Core 中使用,注意中间件或控制器里调用仍有效,但别在静态构造函数里提前触发(可能引发初始化顺序问题)

示例:

var asm = Assembly.GetExecutingAssembly();
string name = asm.GetName().Name;        // 如 "MyApp"
string version = asm.GetName().Version.ToString(); // 如 "2.1.0.0"

AssemblyNameVersion 字段不是语义化版本

.NET 程序集版本号是 4 段纯数字(Major.Minor.Build.Revision),和你在 AssemblyInfo.cscsproj 里写的 Version 属性不是一回事。如果你设置了 <version>1.2.3-beta</version>,生成的程序集版本仍是自动计算的 4 段数字(除非显式设了 AssemblyVersion)。

这意味着:asm.GetName().Version 永远不会包含 -beta 这类后缀,也永远不会是 1.2.3 这样的三段格式。

  • 要读取语义化版本,得看 Assembly.GetCustomAttribute<assemblyinformationalversionattribute>()</assemblyinformationalversionattribute>
  • AssemblyVersion 控制强名称签名和绑定策略,改了可能导致 FileNotFoundException
  • AssemblyFileVersionAssemblyInformationalVersion 只影响文件属性和显示,不影响运行时加载

跨平台读取时注意 Assembly.Location 可能为空

在 .NET Core / .NET 5+ 上,尤其是发布为单文件(publish-self-contained true)或使用 ReadyToRun 时,asm.Location 常常是空字符串。这时候别指望靠它去解析路径再读取 Assembly.LoadFrom() —— 会直接抛 ArgumentException

C函数速查手册(CHM版)
C函数速查手册(CHM版)

C函数速查手册(CHM版)

下载

正确做法是:只要不需要动态加载别的程序集,就完全绕过 Location。所有元数据(名称、版本、特性)都可通过 GetName()GetCustomAttribute() 直接获取,不依赖磁盘路径。

  • 不要写 Assembly.LoadFrom(asm.Location) —— 多余且危险
  • 若真需从文件加载,优先用 AssemblyLoadContext.Default.LoadFromAssemblyPath(),并先检查 Location 是否非空
  • 在 Blazor WebAssembly 中,Location 总是空,这是设计使然,不是 bug

读取第三方程序集要用 AssemblyLoadContext 而非 Assembly.LoadFile

想读一个外部 DLL(比如插件)的名称和版本?别用已淘汰的 Assembly.LoadFile() —— 它会把程序集加载进默认上下文,可能引发类型冲突或无法卸载。.NET Core+ 推荐用 AssemblyLoadContext 隔离加载。

容易忽略的一点:即使只读元数据,LoadFromStream() 也会触发 JIT 编译部分类型,如果 DLL 依赖缺失的 native 库或特定运行时,仍可能失败。

  • AssemblyLoadContext.CreateDefault(isCollectible: true) 创建可卸载上下文
  • 配合 File.ReadAllBytes(path) + LoadFromStream(),避免文件锁
  • 读完立刻调用 context.Unload(),否则内存泄漏
  • 别对同一个 DLL 多次调用 LoadFromStream() —— 即使上下文不同,也可能因内部缓存导致重复加载警告

版本号本身不敏感,但程序集名称里的公钥令牌(PublicKeyToken)在强命名场景下会影响匹配逻辑,这点常被跳过验证。

相关专题

更多
c#是什么意思
c#是什么意思

C#是一种通用的面向对象编程语言,它在.NET框架上运行,可用于开发各种类型的应用程序。本专题为大家提供c#相关的各种文章、以及下载和课程。

2023.08.08

529

5

什么是c#
什么是c#

C#(读作C Sharp)是一种现代的、通用的、面向对象的编程语言。它由微软公司开发,于2000年首次发布,主要用于开发Windows桌面应用程序、Web应用程序、移动应用程序以及游戏开发等领域。C#是一种类型安全和托管的编程语言,它结合了C++的强大性能和C语言的简单易学特点,并引入了许多新的特性和概念,如委托、属性、泛型和异步编程等,以提高开发效率和代码可维护性。

2023.08.31

1181

3

C#中base关键字的用法
C#中base关键字的用法

在C#中,base关键字用于访问当前类的基类成员,这包括基类的字段、属性、方法、构造函数、索引器以及事件。想了解更多C#的相关内容,可以阅读本专题下面的文章。

2024.03.13

557

8

C#Task用法
C#Task用法

Task在C#中是用于表示异步操作的对象,它位于System.Threading.Tasks命名空间中。想了解更多C#中各种用法的相关内容,可以阅读本专题下面的文章。

2024.03.14

1053

11

C# 并发与异步编程
C# 并发与异步编程

本专题系统讲解 C# 异步编程与并发控制,重点介绍 async 和 await 关键字、Task 类、线程池管理、并发数据结构、死锁与线程安全问题。通过多个实战项目,帮助学习者掌握 如何在 C# 中编写高效的异步代码,提升应用的并发性能与响应速度。

2026.02.03

149

18

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

2026.02.06

203

20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

2026.03.11

526

24

C# Unity游戏开发与ECS架构实践
C# Unity游戏开发与ECS架构实践

本专题聚焦 C# 在 Unity 游戏开发中的应用,系统讲解 ECS(Entity-Component-System)架构设计、游戏对象管理、性能优化与内存控制策略。通过实际游戏案例,帮助开发者构建高性能、结构清晰的游戏系统,提高游戏开发效率与运行性能。

2026.04.13

139

20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
RabbitMQ 教程手册
RabbitMQ 教程手册

共0课时 | 0人学习

Linux man-pages 项目
Linux man-pages 项目

共0课时 | 0人学习

C# 教程
C# 教程

共94课时 | 20.2万人学习