我试图通过对ILDASM进行往返,然后在C#可执行文件上进行ILASM来重新生成exe。据我所知,ILDASM生成的.il文件足以生成.exe文件。
我很好奇为什么.NET框架被设计为使用exe文件进行部署而不是将.il文件部署到用户。 c#编译器无法生成.il文件,JIT编译器直接使用.il文件作为输入吗?是因为操作系统需要.exe扩展来调用加载器,还是因为文件大小或性能方面的考虑?
PS:这个问题没有实际意义。我问这个问题是为了让我的概念更清晰,因为我确信我缺乏很多。答案 0 :(得分:16)
添加其他类型的扩展只是为了迎合.NET是没有任何意义的。
.NET可执行文件是PE文件,它们提供最少量的本机代码来引导正确版本的CLR并将IL拉入内存并交给CLR。
Windows本身知道如何处理PE文件,并且使用EXE中内置的间接机制,Windows也不需要了解.NET。
使用.il
文件,您需要在Windows中注册扩展名,然后确保加载了正确版本的CLR - 据我所知,您只能将扩展名与一个可执行文件相关联。 / p>
为了支持CLR的多个版本,您需要某种中介,然后检查您的.il
文件以确定要加载哪个CLR ......之后事情会变得复杂和脆弱。
将所有这些包装在PE中可以整齐而优雅地解决这些问题。
虽然这是一篇较旧的文章,但在当前的.NET框架中原则仍然相同:
An In-Depth Look into the Win32 Portable Executable File Format, Part 2
关键部分“The .NET Header”解释了这是如何工作的:
为Microsoft制作的可执行文件 .NET环境是第一位的 最重要的PE文件。但是,大多数情况下 在.NET中使用普通代码和数据 文件很少。主要目的 .NET可执行文件的目的是获取 特定于.NET的信息,例如 元数据和中间语言 (IL)进入记忆。另外,一个.NET 针对MSCOREE.DLL的可执行链接。 这个DLL是一个起点 .NET进程。当一个.NET可执行文件 加载,它的入口点通常是 微小的代码存根。那个存根只是 跳转到导出的函数 MSCOREE.DLL(_CorExeMain或 _CorDllMain)。从那里,MSCOREE负责,并开始使用 来自可执行文件的元数据和IL 文件。此设置类似于方式 Visual Basic中的应用程序(.NET之前) 使用MSVBVM60.DLL。出发点 对于.NET信息是 IMAGE_COR20_HEADER结构, 目前在CorHDR.H中定义 .NET Framework SDK和更新版本 WINNT.H的版本。该 指向IMAGE_COR20_HEADER 该 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR DataDirectory中的条目。图10 显示一个字段 IMAGE_COR20_HEADER。格式 元数据,方法IL和其他东西 由IMAGE_COR20_HEADER指出 将在随后描述 制品
答案 1 :(得分:4)
.exe
个文件较小
它们还遵循现有的标准PE格式,使Windows集成更简单。
Java需要在单个JRE的路径中注册.jar
扩展名并将其与java.exe
相关联。
相比之下,由于.Net程序集也是普通的Windows可执行文件,.Net不需要注册任何文件关联。相反,.Net EXE包含定位运行时的正确版本并调用它来执行EXE的代码
这允许运行时的多个版本在同一台机器上共存,而不需要单独的加载器来打开.il
文件,找出它是什么版本,然后使用正确的版本运行它。
另外,解析很慢; .il
文件执行速度会更慢,因为运行时需要解析IL。
答案 2 :(得分:2)
早期版本的Windows对.net没有操作系统级支持。这导致了一些替代方案:
通过内置的操作系统支持,可以避免单独文件格式的大多数问题。选择1)超过2)是可以理解的,但我不知道为什么他们没有选择3.我的猜测是他们喜欢让所有(现代)可执行文件具有相同的文件扩展名。
答案 3 :(得分:0)
.Net运行时/ JIT使用IL的字节代码表示。这类似于编译成机器代码的程序集。与尝试将IL维护为“可执行”代码相比,它可以减少影响并且更容易验证二进制数据的完整性。它还会使文件更大。