Почему .NET Core и .NET 5 создают исполняемый файл?

У меня есть вопрос, который меня очень смущает. Я понимаю .NET так:

  • Приложение C # (исходный код) ->
  • csc.exe (компилятор) ->
  • Приложение .NET (которое находится в MSIL)

Если да, то почему создание приложения .NET является исполняемым файлом Windows? Я думал, что вся идея заключается в том, что ваш исходный код компилируется в MSIL, который нацелен на локально установленную среду CLR. Однако и .NET Core, и .NET 5 создают исполняемый файл Windows, который запускается поверх операционной системы, а не на виртуальной машине.

Это не похоже на Java, которая компилируется в файл байт-кода .class (не .exe), и эти файлы действительно запускаются на виртуальной машине (или, позже, вы можете упаковать все файлы классов в .jar) .

Я пытаюсь спросить: почему компилятор C # не создает файл приложения определенного типа, работающий поверх .NET? Например, файл .net, связанный со средой CLR?

Я предполагаю, что созданный .exe Windows является не, на самом деле, исполняемым файлом Windows, а вместо этого является своего рода исполняемым файлом .NET. Но в таком случае почему он не может работать на какой-либо платформе с .NET Core? Linux не знает, что такое .exe файл.


person Lauren 835    schedule 05.06.2020    source источник
comment
Хороший вопрос! Многие новые разработчики просто принимают это как должное и принимают тот факт, что это просто работает, не разбираясь в действительности, почему это работает, несмотря на необходимость в JIT-компиляторе.   -  person Jeremy Caney    schedule 06.06.2020
comment
Также добро пожаловать в разработку .NET! Вы учитесь в захватывающее время, поскольку на данный момент модель разработки действительно достаточно зрелая, с унифицированным опытом разработки для всех платформ и фреймворков.   -  person Jeremy Caney    schedule 06.06.2020
comment
.NETCore действительно работает именно так. Эквивалент .jar - .dll, эквивалент java.exe - dotnet.exe. Но после 18 лет, когда программисты привыкли к запуску .exe, .NETCore и VS не пытаются слишком сильно расстроить корзину с яблоками. .Exe, который вы запускаете, является хостом, его задача - реализовать виртуальную машину. Рано или поздно программисты привыкнут распространять только .dll, это, вероятно, займет некоторое время.   -  person Hans Passant    schedule 06.06.2020


Ответы (3)


Это обычный исполняемый файл, но единственный собственный код, который он содержит, - это небольшая заглушка, которая будет вызывать среду выполнения .NET. Затем среда выполнения проверит MSIL, встроенный в этот файл, и сделает все остальное.

person Theodoros Chatzigiannakis    schedule 05.06.2020

Как уже были даны ответы на другие ответы, по умолчанию в Windows в настоящее время создается исполняемый файл небольшого хоста, который загружает среду выполнения .NET и загружает соответствующую сборку MSIL.

Интересным фактом является то, что сборка MSIL упакована в том же формате времени выполнения (PE - переносимый исполняемый файл), что и все файлы Windows .exe или .dll ..

Более ранняя версия нового .NET (.NET Core, теперь .NET 5+) создавала только файл .dll, который мог работать на всех платформах, и требовал, чтобы пользователи использовали dotnet theapp.dll для запуска приложения.

Хотя это работает, .NET Core 3.0 и более поздние версии также перешли к созданию сборки узла приложения в качестве альтернативной точки входа. Код, сгенерированный dotnet publish, по-прежнему является кроссплатформенным, но дополнительная генерация исполняемого файла имеет несколько преимуществ:

  • Для переноса классических проектов .NET Framework в .NET Core требуется меньше изменений в более крупных проектах с конвейерами CI / CD или инструментами, ожидающими файлов .exe.
  • Пользователям легче найти нужную программу в проводнике задач / ps - как и найти правильный процесс java.exe, наличие сотен dotnet.exe процессов немного затруднительно для задач ops.
  • Путь к dotnet.exe или dotnet (linux / macOS) может быть неудобным для поиска или настройки. Используя исполняемый файл, он может искать среду выполнения в разных местах и ​​меньше зависит от правильно установленной переменной среды PATH.
  • On windows, people may want to change OS-specific definitions for the .exe, e.g.:
    • subsystem flag (GUI vs console app): a flag in the .exe file controls if windows will open a console window or not. java has java.exe and javaw.exe for console vs GUI programs. the required setting for .NET Core 3.0+ apps can be customized by the build process or project SDK (e.g. WinForms, WPF).
    • Встроенный значок: EXE-файлы Windows могут содержать значки. Если вы хотите, чтобы ваше приложение (особенно приложение с графическим интерфейсом пользователя) отображалось в проводнике или на панели задач со значком, вам понадобится файл .exe, который вы можете изменить с помощью значка.
    • Вставьте манифест Win32: файлы манифеста могут управлять множеством вещей, например повышенными требованиями к доступу (эти файлы .exe, которые предложат вам разрешить доступ администратора). Снова то, что вы не можете сделать с dotnet.exe theapp.dll.

Обратите внимание, что в настоящее время создание исполняемого файла отключено в macOS из-за требований Apple к нотариальному заверению. (В основном вам нужно будет подписать приложение, а яблоко должно будет нотариально заверить его, чтобы работать без предупреждений).

person Martin Ullrich    schedule 12.06.2020
comment
генерируется небольшой исполняемый файл хоста. Размер исполняемого файла составляет 140 000 байт, что смехотворно велико. Сравните исполняемый файл, создаваемый .NET Framework: менее 5000 байт, который уже включает программу hello world, которая все еще является отдельной DLL в .NET 5. - person kaalus; 04.02.2021

потому что Microsoft хотела, чтобы сгенерированный код был непосредственно исполняемым. Т.е. они не хотели

c:> rundotnet myapp

они хотели

c:> myapp

почему, потому что теперь пользователям придется решать, как что-то запускать, а не просто набирать или щелкать по нему. Поэтому они обернули IL в исполняемый файл начальной загрузки, который загрузил среду выполнения .net и вошел в основную точку входа IL.

Сравните это с запущенными Java-приложениями.

Обратите внимание, что в моно (в Linux) вы сделали

#: mono myapp

хотя позже они представили способ сделать это способом Windows

person pm100    schedule 05.06.2020