2011-03-30 99 views
20

我試圖通過執行ILDASM和ILASM在C#可執行文件上的往返來重新生成一個exe文件。據我所知,由ILDASM生成的.il文件足以生成.exe。爲什麼IL代碼打包到C#應用程序中的exe文件中?

我很好奇,爲什麼.NET框架被設計爲使用EXE文件進行部署,而不是將.il文件部署到用戶。無法c#編譯器生成.il文件,並且JIT編譯器直接將.il文件用作輸入?是因爲操作系統需要.exe擴展名來調用加載程序,還是因爲文件大小或性能考慮?

PS:這個問題沒有實際意義。我問這個問題讓我的概念更清楚,因爲我相信我缺乏很多。

+0

+1好問題。爲了比較,這將更接近於Java部署的工作原理 - 對嗎? '.jar'文件在運行之前必須轉換爲字節碼(據我瞭解),這會影響其啓動時間。我是Java新手,所以Java大師,請糾正任何錯誤陳述。 – harpo 2011-03-30 17:29:40

+0

你在問關於文件內容還是擴展名? – SLaks 2011-03-30 17:35:37

+0

Slaks - 我想知道兩者。更多的信息更好.. – paseena 2011-03-30 17:38:11

回答

4

.exe文件較小。
它們也遵循現有的標準PE格式,使得Windows集成更簡單。

Java需要註冊.jar擴展名,並將其與java.exe關聯在單個JRE的路徑中。

相比之下,由於.Net程序集也是正常的Windows可執行文件,.Net不需要註冊任何文件關聯。相反,.Net EXE包含的代碼定位了運行時的正確版本,並調用它來執行EXE。
這允許運行時的多個版本在同一臺機器上共存,而不需要單獨的裝載程序來打開.il文件,找出它的版本,然後使用正確的版本運行它。

此外,解析速度慢; .il文件將執行得更慢,因爲運行時需要解析IL。

+1

更不用說'.exe'是一個比'.il'更好的已知格式。 「嘿,這是一個程序!」 – BoltClock 2011-03-30 17:24:27

+1

@Bolt:這並沒有阻止Java。 – SLaks 2011-03-30 17:25:30

+0

除非NGen'd它仍然是IL包裹在需要被JIT'DE EXE所以實際上沒有任何速度上的差異。 – Kev 2011-03-30 17:26:09

0

.Net運行時/ JIT使用IL的字節碼錶示。這與編譯成機器代碼的程序集類似。與僅僅試圖將IL保持爲「可執行」代碼相比,它的影響更小,更容易驗證二進制數據的完整性。它也會使文件變大。

15

爲了迎合.NET,添加其他類型的擴展是沒有任何意義的。

.NET可執行文件是PE文件,它們提供最少量的本機代碼來引導正確版本的CLR並將IL拉入內存並交給CLR。

Windows本身就知道如何處理PE文件以及內置在EXE中的間接機制Windows也不需要了解.NET。

使用.il文件,您需要在Windows中註冊擴展名,然後確保加載了正確版本的CLR - 據我所知,您只能將擴展名與一個可執行文件相關聯。

要支持CLR的多個版本,您需要某種中介,然後檢查您的.il文件以確定要加載哪個CLR ....並且事情在此之後變得複雜而脆弱。

在PE中打包所有這些問題整潔而優雅地解決了這些問題。

雖然這是一篇較舊的文章,但其原理在當前保持不變。NET框架:

An In-Depth Look into the Win32 Portable Executable File Format, Part 2

的關鍵部分 「的.NET頭」 解釋了這是如何工作:針對Microsoft .NET 環境下生產

可執行文件是第一和最重要的 PE文件。但是,在大多數情況下,在.NET 文件中的正常代碼和數據是最小的。 .NET可執行的主要目的是 得到.NET特定 信息,例如元數據 和中間語言 (IL)到存儲器中。另外,一個針對MSCOREE.DLL的.NET 可執行鏈接。 這個DLL是一個 .NET進程的起點。當加載一個.NET可執行文件 時,其入口點通常是一個 微小的代碼段。這存根只是 跳轉到 MSCOREE.DLL(_CorExeMain或 _CorDllMain)導出函數。從那裏,MSCOREE負責並開始使用 元數據和來自可執行文件 的IL。此設置與使用MSVBVM60.DLL的Visual Basic(.NET之前) 中的應用程序的 類似。 .NET信息的起始點 是 IMAGE_COR20_HEADER結構, 當前在CorHDR.H中從 .NET Framework SDK和更新的 版本的WINNT.H中定義。在DataDirectory中, IMAGE_COR20_HEADER被 IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 條目指向。圖10 顯示了一個 IMAGE_COR20_HEADER的字段。所述 元數據的格式,方法IL,和其他東西 通過 將在隨後的 文章描述IMAGE_COR20_HEADER指向。窗戶

+2

值得注意的是,從XP開始,CLR引導代碼就不再使用了。它必須在那裏,因爲這就是.NET exes如何被指定的,但OS加載器知道如何加載.NET可執行文件。 – 2011-03-31 12:43:22

+2

@damien - 你有這個信息的鏈接? – Kev 2011-03-31 13:01:56

2

早期版本有.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的問題。

有了內置的操作系統支持,就可以避免大部分單獨文件格式的問題。選擇1)超過2)是可以理解的,但我不知道他們爲什麼不選擇3.我的猜測是他們喜歡讓所有(現代)可執行文件具有相同的文件擴展名。

相關問題