为什么IL代码打包到C#应用程序的exe中?

时间:2011-03-30 17:18:45

标签: c# .net clr

我试图通过对ILDASM进行往返,然后在C#可执行文件上进行ILASM来重新生成exe。据我所知,ILDASM生成的.il文件足以生成.exe文件。

我很好奇为什么.NET框架被设计为使用exe文件进行部署而不是将.il文件部署到用户。 c#编译器无法生成.il文件,JIT编译器直接使用.il文件作为输入吗?是因为操作系统需要.exe扩展来调用加载器,还是因为文件大小或性能方面的考虑?

PS:这个问题没有实际意义。我问这个问题是为了让我的概念更清晰,因为我确信我缺乏很多。

4 个答案:

答案 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. 一个exe文件,它加载.net CLR然后使用它来运行IL。缺点是您无法区分包含.net IL和本机exe的exe。如果您想以降低的.net权限运行它,这是相关的 该程序与原生程序无法区分,一目了然可能会导致更高的接受度 它还允许用.net程序替换本机程序,而无需更改调用它的所有代码。
  2. 包含二进制IL的新文件格式。类似于java的jar文件。双击时,它们将与相关程序一起打开。像“rundotnet.exe myprogram.net”之类的东西 这导致程序在程序可执行程序和逻辑程序之间采用一对一映射的问题。这包括防火墙和任务栏分组功能。在任务管理器中,您看不到您看到的多个“rundotnet.exe”对应的内容,...
    此解决方案也无法使用本机和.net代码组合的程序集 这样做的一大优点是程序代码可以在执行之前由.net运行时验证。
  3. 具有新文件扩展名的PE文件。那是我最喜欢的一个。在旧版本的Windows中,您只需添加一个注册表项即可作为正常程序运行,在新版本中,您可以为其提供特殊处理。这避免了2和3的问题。
  4. 通过内置的操作系统支持,可以避免单独文件格式的大多数问题。选择1)超过2)是可以理解的,但我不知道为什么他们没有选择3.我的猜测是他们喜欢让所有(现代)可执行文件具有相同的文件扩展名。

答案 3 :(得分:0)

.Net运行时/ JIT使用IL的字节代码表示。这类似于编译成机器代码的程序集。与尝试将IL维护为“可执行”代码相比,它可以减少影响并且更容易验证二进制数据的完整性。它还会使文件更大。