Why when compiling .NET Core console application we end up with both dll and exe files? - .net-core

I have noticed that both dll and exe files with the name of the project are created on Windows when compiling a .NET Core console application. Why is that? In full .Net framework only the exe file would be created.

Prior to .Net Core 3.0, only the dll was created (although you could still do a single file build that was platform-dependent). In these cases you had to use the command dotnet MyProject.dll to start your program.
With .Net Core 3.0, they added the exe, which is still really just a wrapper around the command above. On other operating systems it also creates an executable file, it just names it MyProject instead of MyProject.exe
If people have old scripts that still make the dotnet command, this setup doesn't break them, but if you want to just use an exe, you can do that too.

Related

Obfuscator for .NET Core Single Publish Files

Is there an obfuscation tool that can work well on the exe and pdb files that result from a dotnet core single file publish?
I am using dotnet core single file publish with the command: dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true. This works great in giving me just two neat files an exe and a pdb file, which I am able to give to a client to run my application.
However, I am still concerned about its ability to be decompiled.
I tried using ILSpy and JustCompile on both the files and they luckily could not be decompiled with these tools. Is it then that my files are safe, or it is that the tools have not yet caught up?
If the latter, what obfuscation tool can I use to protect these files? I attempted to use Obfuscar which did not work specifically on the single file publish outputs, the exe and pdb.
Any suggestions on the obfuscation tools to use for this?
Disclosure: I work for the Dotfuscator team at PreEmptive.
We have tested and verified that Dotfuscator Professional handles this scenario on both .NET Core 3 and .NET 5.
Specifically, you must use Dotfuscator Professional's MSBuild integration, which is now our recommended method of using Dotfuscator Professional for new projects. However, Dotfuscator will not update .pdb files on .NET Core or .NET 5, so you will not be able to debug builds which use Dotfuscator (e.g., Release builds). You should not ship .pdb files to untrusted users.
You can decompile .NET Core self-contained executables if you manually unpack them:
Can .Net Core 3 self-contained single executable be decompiled?
You would have to run the obfuscator as part of the build process, before the individual assemblies are compressed into the single file. That's probably possible if you add a custom MSBuild target that executes the obfuscator, and use the BeforeTargets attribute to integrate it at the correct point in the build process. But I haven't looked at the .NET core build system in detail.
You can use Obfuscar.
Use it in obj directory after target Compile and then copy obfuscated files to directory.(replace with original files)

Can I shrink a dotnet publish package

I have recently started developing using dotnet core (as opposed to old fashion plain .net) to create a number of small utility console applications.
The development is fine and it has come to the point I want to publish them.
I am using the CLI and as I am only interested in Win 10 deployments, tried
dotnet publish -c release -r win10-x64
It worked and built me a "publish" folder where everything seemed to work, though the "publish" folder is huge (~70mb) compared to the size of the app (~500 lines of code).
As I am only going to deploy to Win10 machines is there a way to package this so I don't need all the .NET files? I thought that was what the -r option was for but that does not seem to have achieved much.
It depends on how you want to deploy your app/who is going to use them.
The -r flag creates a self-contained app. This causes the publish command to include the necessary .NET Core DLL's for the specified platform (and platform specific nuget packages if they are avaiable), which means anyone can use the app without having to install .NET Core runtime.
If you remove the -r flag then publish will only include the DLL's for you app. But this means whoever wants to use your app must first install the .NET Core runtime.
You can see the difference by using the -o flag to write the publish output to different directories e.g.
dotnet publish -c release -r win10-x64 -o ./publish-win10
or
dotnet publish -c release -o ./publish-any
Now go and have a look at what has been written to ./publish-win10 and ./publish-any folders and you can the difference.
If you are installing them onto a system where the .NET Core runtime is already present then you can just distribute the DLL and save a lot of space. However if you want to be able to distribute the app without the end user having to worry about having the .NET Core runtime installed then the -r flag to create a self-contained distribution is the way to go, but results in the 'package' including the necessary .NET Core assemblies.
AFAIK the -r flag does not affect how you app is compiled, just what runtime DLL's are included as part of the publish command. So you always get the same DLL for your code if you publish it for win10-x64 or with, or without, the -r flag so your app DLL will run on any (.NET Core compatible) platform, but I am happy to be corrected on that point.
Unlike .NET 4.x which you are used to where building is the standard to create an output, .NET Core (And .NET 5) considers building and publishing to be very different.
The huge (70MB) size is because the publisher is assuming that your target does not have any form of the .NET Framework installed, so is bundling it in with your project.
You can change your publish line to
dotnet publish -r win-x64 --self-contained false
Just by itself, this will create the .NET Core standard - A .dll (Your application), a .exe (That runs the application), some .json files for settings, and a .pdb file for debugging symbols.
To alter the application to the .NET Framework standard output that you are used to, open the .csproj file in a text editor, and below the
<TargetFramework>netx.x</TargetFramework>
line, add
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
And rerun the publish command. This will result in a single .exe and a single .pdb in the publish directory (The .pdb file which you can safely delete).
Note: Since you have included --self-contained false, the target will need the specified version of the .NET Framework (The one specified in your .csproj file) installed. Whilst many versions of the .NET Framework are currently installed on most Windows 10 Devices (Generally located at C:\Windows\Microsoft.NET\Framework or C:\Program Files\dotnet\), the .NET Core / .NET 5 Runtimes aren't yet as common (Although will likely be distributed through Windows Update in the near future), so may require a once-off download if the recipient of your .exe does not have it.
Whilst the .NET Core / .NET 5 resultant binaries ARE larger (Although by around 150kb - Not 50MB), they run significantly faster than their .NET Framework 4.x counterparts.

.net core 2.0 console app : exe file location

I am working with .net core 2.0 console application. I need to run this console app using command prompt.
Like,
MyApp.exe arguments
I published the console app using below command to generate .exe :
dotnet publish -c Release -r win10-x64
It creates multiple .exe file,
1) \bin\Release\netcoreapp2.0\win10-x64
2) \bin\Release\netcoreapp2.0\win10-x64\publish
I believe both are same and I can use (2) as published version of the app. Correct me if wrong.
I am not sure why it generates .exe at (1) and does not contain bunch of dlls at there.
What is the difference?
anyone can give me more information about this?
The first one is still a framework-dependent deployment, it used when you call dotnet run -r win-x64. It resolves and configures the shared framework via the information in .runtimeconfig.json and your PATH environment variable and locates the DLLs via a values in the .runtimeconfig.dev.json and .deps.json based on your global packages cache (=> specific to your machine and user).
For deploying self-contained applications, the publish folder contains all the necessary assets. The host uses the local dlls instead of the shared framework and as well as the necessary DLLs.

Does .NET Core only have "dll" and not exe?

I just tried the quick start of .NET Core on Windows, following the sample, I created a desktop application. What seems a bit weird is the "main" program is compiled into a "dll" and no longer an "exe" like previous C# code.
Does it mean, from now on, .NET Core compiles everything into an "dll", like java compiles everything into a "class", and no longer need the "exe" because .NET Core VM is the sandbox for all .NET Core apps, like JVM?
Yes, exactly. With dotnet core, Microsoft went a step towards Java/Node/etc style of workflow where you can do most things through a command line tool (dotnet.exe).
I think this makes sense because .NET Core dependencies are app-local, so the runtime isn't scattered everywhere arround the file system as with .NET Framework.
You can create exe also by publishing the project for Windows OS.
For example (.Net Core 2.0):
dotnet publish -c release -r win7-x64
You need to specify win7-x64 in RuntimeIdentifiers also in the .csproj file

Compile ASPX/ASCX into DLL? (i.e. compile on client instead of server?)

If I understand correctly with our deployments most code gets compiled on the workstation, and the aspx/ascx files get compiled on first access on the server. Is there anyway to precompile these?
I would like to do this to trigger compile errors at workstation compile time, rather than at "run-time" and also to potentially allow C# 4 features to work in views as we use .NET 3.5 on the servers.
Visual Studio provides the command-line tools aspnet_compiler and aspnet_merge, and I blogged about how to call them from a batch file.
You can also add aspnet_compiler as a Post-Build event in the project to find compilation errors, but it slows down build times.
If you develop for .Net 4, you need to have the .Net 4 framework installed on the web server.
Follow this link for precompilation overview: ASP.NET Precompilation Overview
Also, if on server 4th framework doesn't installed you can't use C#4 features in your project even if you will precompile application on your dev machine.

Resources