Почему код IL упакован в exe в приложении С#?
Я пытался регенерировать exe, совершив обратный путь ILDASM, а затем ILASM в исполняемом файле С#. Насколько я понимаю, файл .il, созданный ILDASM, достаточен для генерации .exe назад.
Мне любопытно, почему .NET framework предназначен для использования exe файла для развертывания вместо развертывания файла .il для пользователей. Не мог ли С# компилятор сгенерировать файл .il, а компилятор JIT использовал .IL файл напрямую как вход? Это просто потому, что операционной системе требуется расширение .exe для вызова загрузчика, или это из-за размера файла или соображений производительности?
PS: Вопрос не имеет практического значения. Я задаю этот вопрос, чтобы сделать мои понятия более ясными, поскольку я уверен, что мне не хватает много.
Ответы
Ответ 1
Не было бы смысла добавлять другой тип расширения только для поддержки .NET.
Исполняемые файлы .NET - это файлы PE, и они обеспечивают минимальный объем нативного кода для загрузки правильной версии CLR и переноса IL в память и передачи в CLR.
Windows изначально знает, что делать с файлами PE и с механизмом косвенности, встроенным в EXE Windows, также не нужно знать о .NET.
С файлом .il
вам нужно будет зарегистрировать расширение с помощью Windows, затем убедитесь, что загружена правильная версия CLR - насколько я знаю, вы можете связать только расширение с одним исполняемым файлом.
Чтобы поддерживать несколько версий CLR, вам понадобится какой-то посредник, который затем проверяет ваш файл .il
, чтобы определить, какая среда CLR будет загружаться... и после этого вещи просто становятся запутанными и хрупкими.
Упаковка всего этого в PE решает эти проблемы аккуратно и элегантно.
Хотя это более старая статья, принципы остаются неизменными в текущих .NET Framework:
Взгляд в глубину Посмотрите в формате исполняемого файла Win32 Portable, Part 2
В главном разделе "Заголовок .NET" объясняется, как это работает:
Исполняемые файлы, выпущенные для Microsoft Среда .NET - это первая и прежде всего PE файлов. Однако в большинстве случаях обычный код и данные в .NET. файл минимальны. Основная цель исполняемого файла .NET - это получить Специфическая для .NET информация, такая как метаданные и промежуточный язык (IL) в память. Кроме того,.NET. исполняемые ссылки на MSCOREE.DLL. Эта DLL является отправной точкой для .NET. Когда исполняемый файл .NET нагрузки, ее точка входа, как правило, крошечный заглушка кода. Эта заглушка просто Переход к экспортируемой функции в MSCOREE.DLL(_CorExeMain или _CorDllMain). Оттуда MSCOREE берет на себя ответственность и начинает использовать метаданные и ИЛ из исполняемого файла файл. Эта настройка аналогична приложения в 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 будет описано в следующем статья.
Ответ 2
.exe
файлы меньше.
Они также соответствуют существующему стандарту формата PE, что упрощает интеграцию Windows.
Java необходимо зарегистрировать расширение .jar
и связать его с java.exe
на пути к одной JRE.
В отличие от того, что .Net-сборки также являются обычными исполняемыми файлами Windows,.NET не требует регистрации каких-либо ассоциаций файлов. Вместо этого .NET EXE содержит код, который определяет правильную версию среды выполнения и вызывает ее для выполнения EXE.
Это позволяет нескольким версиям среды выполнения сосуществовать на одном компьютере, не требуя отдельного загрузчика, который откроет файл .il
, определит, какую версию он, а затем запустил с правильной версией.
Кроме того, синтаксический анализ медленный; .il
файлы будут выполняться медленнее, потому что время выполнения должно будет анализировать IL.
Ответ 3
В ранних версиях окон не было поддержки уровня операционной системы для .net. Это приводит к некоторым альтернативам:
- Файл exe, который загружает CLR.net, затем использует его для запуска ИЛ. Недостатком этого является то, что вы не можете отличить exe, содержащий .net IL и native exe. Это актуально, если вы хотите запустить его с ограниченными привилегиями .net.
То, что программа неотличима от родной программы с первого взгляда, может привести к более высокому принятию.
Он также позволяет заменять собственную программу программой .net, не требуя изменения всего кода, который ее вызывает.
- Новый формат файла, содержащий бинарный IL. Подобно java файлам jar. При двойном щелчке они будут открываться с помощью связанной программы. Что-то вроде "rundotnet.exe myprogram.net".
Это приводит к проблемам с программами, которые предполагают сопоставление между собой между исполняемыми программами и логическими программами. Это включает в себя брандмауэры и функцию группировки панели задач. В диспетчере задач вы не видите, что несколько "rundotnet.exe", которые вы видите, соответствуют,...
И сборки, которые сочетают родной и .net-код, с этим решением тоже невозможны.
Большим преимуществом этого является то, что программный код может быть проверен временем выполнения .net перед выполнением.
- Файл PE с новым расширением файла. Это мой любимый. В старых версиях Windows вы можете просто добавить запись в реестр для запуска, как обычную программу, а в новых версиях вы можете дать ей специальное обращение. Это позволяет избежать проблем как 2, так и 3.
Благодаря встроенной поддержке ОС можно избежать большинства проблем отдельного формата файла. Выбор 1) более 2) понятен, но я не знаю, почему они не выбирали 3. Я предполагаю, что им нравилось иметь все (современные) исполняемые файлы с тем же расширением файла.
Ответ 4
.Net runtime/JIT использует представление байтового кода IL. Это похоже на сборку, скомпилированную в машинный код. Это требует меньшего влияния и проще проверить целостность двоичных данных, чем если бы вы пытались поддерживать IL как "исполняемый" код. Это также сделает файлы более крупными.