.NET 程序集文件格式.NET assembly file format

.NET 定义用于充分描述和包含 .NET 程序的二进制文件格式 - 程序集。.NET defines a binary file format, assembly, that is used to fully describe and contain .NET programs. 程序集用于程序本身以及所有依赖库。Assemblies are used for the programs themselves as well as any dependent libraries. .NET 程序可作为一个或多个程序集运行,除了相应的 .NET 实现外,无需其他任何项目。A .NET program can be executed as one or more assemblies, with no other required artifacts, beyond the appropriate .NET implementation. 本机依赖项(包括操作系统 API)是一个需要单独考虑的问题,虽然有时会使用 .NET 程序集格式来描述它们,但并未将其包含在此格式内(例如,WinRT)。Native dependencies, including operating system APIs, are a separate concern and are not contained within the .NET assembly format, although they are sometimes described with this format (for example, WinRT).

每个 CLI 组件都带有特定于该组件、用于声明、实现和引用的元数据。Each CLI component carries the metadata for declarations, implementations, and references specific to that component. 因此,特定于组件的元数据被称为组件元数据,并且自 ECMA 335 I.9.1 生成的组件被认为是自描述组件和程序集。Therefore, the component-specific metadata is referred to as component metadata, and the resulting component is said to be self-describing – from ECMA 335 I.9.1, Components and assemblies.

该格式完全被指定并标准化为 ECMA 335The format is fully specified and standardized as ECMA 335. 所有 .NET 编译器和运行时都使用此格式。All .NET compilers and runtimes use this format. 已编入文档、偶尔更新的二进制格式的出现对于互操作性而言是一个主要优势(也可以说是要求)。The presence of a documented and infrequently updated binary format has been a major benefit (arguably a requirement) for interoperability. 该格式上一次进行实质更新是在 2005 年 (.NET Framework 2.0),目的是为了容纳泛型和处理器体系结构。The format was last updated in a substantive way in 2005 (.NET Framework 2.0) to accommodate generics and processor architecture.

格式为 CPU 和 OS 不可知。The format is CPU- and OS-agnostic. 它被用作针对许多芯片和 CPU 的 .NET 实现的一部分。It has been used as part of .NET implementations that target many chips and CPUs. 虽然格式本身继承了 Windows,但它可用于所有操作系统。While the format itself has Windows heritage, it is implementable on any operating system. 对于 OS 互操作性,这可以说是一项最重大的选择,因为大部分值存储在 Little-endian 格式中。Its arguably most significant choice for OS interoperability is that most values are stored in little-endian format. 它与计算机的指针大小没有特定关联(例如,32 位、64 位)。It doesn’t have a specific affinity to machine pointer size (for example, 32-bit, 64-bit).

.NET 程序集格式也详细介绍了给定程序和库的结构。The .NET assembly format is also very descriptive about the structure of a given program or library. 它介绍了程序集的内部组件,特别是定义的程序集引用和类型及其内部结构。It describes the internal components of an assembly, specifically assembly references and types defined and their internal structure. 工具或 API 可读取和处理此信息以进行显示或做出程序化决策。Tools or APIs can read and process this information for display or to make programmatic decisions.


.NET 二进制格式以 Windows PE 文件格式为基础。The .NET binary format is based on the Windows PE file format. 实际上,.NET 类库符合 Windows PE,咋看之下会显示为 Windows 动态链接库 (DLL) 或应用程序可执行文件 (EXE)。In fact, .NET class libraries are conformant Windows PEs, and appear on first glance to be Windows dynamic link libraries (DLLs) or application executables (EXEs). 此特性在 Windows 上十分有用,它们可以伪装成本地可执行二进制文件,并获得相同的处理方式(例如,OS 加载,PE 工具)。This is a very useful characteristic on Windows, where they can masquerade as native executable binaries and get some of the same treatment (for example, OS load, PE tools).


来自 ECMA 335 II.25.1 的程序集头,运行时文件格式结构。Assembly Headers from ECMA 335 II.25.1, Structure of the runtime file format.

处理程序集Process the assemblies

可以编写工具或 API 来处理程序集。It is possible to write tools or APIs to process assemblies. 程序集信息能够在运行时做出程序化决策、重新编写程序集、在编辑器中提供 API IntelliSense 以及生成文档。Assembly information enables making programmatic decisions at run time, re-writing assemblies, providing API IntelliSense in an editor and generating documentation. System.ReflectionSystem.Reflection.MetadataLoadContextMono.Cecil 是常用于此目的的典型工具。System.Reflection, System.Reflection.MetadataLoadContext, and Mono.Cecil are good examples of tools that are frequently used for this purpose.