I have a question that I'm very confused about. The way I understand .NET is like this:
csc.exe
(compiler) -> If so, why is the output from building a .NET app a Windows executable? I thought the whole idea was that your source code compiles down to MSIL, which targets the locally installed CLR. However, both .NET Core and .NET 5 generate a windows executable, which run atop of the operating system, not in a virtual machine.
This is unlike Java, which compiles to a .class
bytecode file (not an .exe
), and those files do run atop a virtual machine (or, later, you can package all the class files into a .jar
).
What I'm trying to ask is: Why doesn't the C# compiler generate a specific application file type that runs atop .NET? E.g., a .net
file that is associated with the common language runtime?
My best guess is that the Windows .exe
generated is not, in fact, a Windows executable, but instead some kind of .NET executable. But, in that case, why can't it run on any platform with .NET Core? Linux doesn't know what an .exe
file is.
It's a regular executable but the only native code it contains is a small stub that will call into the .NET runtime. The runtime will then inspect the MSIL embedded in that file and do the rest.
As other answers already answered, the default on Windows is currently that a small host executable is generated that boots up the .NET runtime and loads the appropriate MSIL assembly.
An interesting factoid is that the MSIL assembly is packaged in the same runtime format ("PE" - portable executable) as all windows .exe or .dll files..
Earlier version of "the new .NET" (.NET Core, now .NET 5+) only produced the .dll file that could run on all platforms and required users to use dotnet theapp.dll
to run the application.
While this works, .NET Core 3.0 and later moved to generating an "app host" assembly as an alternative entry point as well. The code generated by dotnet publish
is still cross-platform, but additionally generating the executable has a few advantages:
ps
- like finding the right java.exe process, having hundreds of dotnet.exe
processes around is a bit hard for ops tasks.dotnet.exe
or dotnet
(linux / macOS) may be cumbersome to find or set up. By using an executable, it can look for the runtime in various places and is less dependent on a correctly set PATH environment variable.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).dotnet.exe theapp.dll
.Do note that currently, this executable file generation is disabled on macOS due to Apple's notarization requirements. (Basically you would need to sign the app and apple would need to "notarize" it in order to run without warnings).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With