Change .NET Core application generated exe description - .net-core

I have created a .NET Core application. When I do:
dotnet publish -r win81-x64
All files needed to execution are deployed in the following folder:
\bin\Debug\netcoreapp1.1\win81-x64\publish
There, among all the files I have a dll file with the name Example.dll and the exe file named Example.exe. Now, my problem is when I execute the exe, in the task manager the application description says:
dotnet
I would like to change that to Example, for that I tried to edit my csproj to contain the following:
<PropertyGroup>
<OutputType>Exe</OutputType>
<Version>1.0.0.0</Version>
<Description>Example</Description>
<TargetFramework>netcoreapp1.1</TargetFramework>
<RuntimeIdentifiers>win81-x64</RuntimeIdentifiers>
<Satellite_Description>Example</Satellite_Description>
</PropertyGroup>
But it doesn't seems to have any affect in the generated exe file, only ind the dll. How can I change the exe description?

Currently this is not possible in the build process.
Unlike classic .NET projects, this .exe file isn't actually compiled but is a pre-built binary (dotnet.exe, in 2.0 apphost.exe) acquired via a NuGet package and copied/renamed to the publish output.
There is an issue on GitHub about changing the description after being launched, but at the time of writing it is not assigned to a milestone of an expected release.

There is known issue in populating assemblyino manifest into EXE file. Looks like will be supported in .net core 3.0 release.
see: https://github.com/dotnet/sdk/issues/1899

Related

AssemblyInfo ingrored when building from GitLab-Runner

On a Windows machine there is a GitLab-Runner run from a domain user with admin rights. When I log as this user and call dotnet build -c release to build an ASP.NET Core app, the dll has all the information from the AssemblyInfo.cs file. When I do the same as part of a CI job, the produced dll is missing all this information (for example the version number).
The AssemblyInfo.cs file is not part of the repository, instead, it is produced by a prebuild event (using gitWCRev.exe tool). However after running some tests I can see that the AssemblyInfo.cs is actually generated when the job is run by the runner.
Any help as to why the file is ignored and how to overcome this issue would be appreciated.
At first I thought that this might be related to Pre-build task of Visual Studio project fails in GitLab Runner issue, but I don't get any build errors.
On the same machine, I build a .Net Framework app which has the same AssemblyInfo setup, but is compiled using msbuild /property:Configuration=Release by the runner and the produced dll file has all the expected information.
It turns out the problem was partially related to the AssemblyInfo.cs file not being part of the repository.
SDK-style csproj normally don't list the files in the project, but figure them out based on the folder contents. When dotnet build was run, AssemblyInfo.cs wasn't present in the project directory (GitLab-Runner usually clears out files not present in the repository before starting a job/pipeline), so build tools had no idea they needed to load it. It made no difference that the file was being created by the build tools.
The solution proved to be creating an empty AssemblyInfo.cs file before running dotnet build. This way build tools knew they needed to compile it. Actual compilation still happened after prebuild events, so all the needed information was there.
I created the empty AssemblyInfo.cs file using PowerShell:
New-Item -Path "Properties/AssemblyInfo.cs" -ItemType File
Also, checking the build logs helped me finally figure it out. To get the build logs I've called build tools like this:
dotnet build -c release /flp:v=diag
The .Net Framework app didn't have this problem because it wasn't an SDK-style project. All the files needed for compilation were listed in the project file and build tools knew to load them, even if they were created during the prebuild event.

Cannot understand "Single-file executables" feature in Net Core 3

While learning how Single-file executables work in net core 3.1 I created net core 3.1 C# Console Application. If I compile the default project created by VS, I can see this set of files
In order to run this console app I have to distribute 3 files - ConsoleNetCore.exe/dll/runtimeconfig
Now I want to improve a distribution story and prefer to have just one single file to distribute so I don't have exe and dll but just an exe. As was outlined in the above link and modified my project file by adding these properties:
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
so the entire project file is:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
</Project>
Then I rebuilt the project and noticed an extra folder win10-x64 under netcoreapp3.1 with 226 files in there, mainly dlls including ConsoleNetCore.exe. I copied from there the exe and put it under c:\temp and ran it and got the error:
The application to execute does not exist: 'c:\Temp\ConsoleNetCore.dll'
I then copied there that dll and tried to run the exe again and this time got:
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\Program Files\dotnet'
Obviously I failed producing Single-file executable, I expected literally a single exe file and nothing else so I could simply distribute that file, do I misinterpret this feature? How to make really single executable file which doesn't require any other files?
I realized that just rebuilding is not enough, I literally should Publish from within Visual Studio (or tools command line):

Restoring NuGet packages to the cache

I have a .net-core application that works on my machine but when I deploy it on another one, it complains about missing packages and points me to the TheApp.deps.json.
My theory is that on my machine the app looks for packages in some NuGet cache where they were probably installed by the IDE during development because the app's output-dir contains only a couple of internal dlls so the other nuget.org dependecies are definitely missing.
I'm building the app with
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
</PropertyGroup>
and then xcopy it to the other machine.
Question
Is there a way to restore or install the missing packages to the cache on the target machine based on the *.deps.json file?
dotnet build (and the F5/Build function in Visual Studio) simply build the code that you have provided via your source files (i.e cs, fs, vb, etc.).
Whereas dotnet publish (and the Build > Publish function in Visual Studio) does a full package restore, builds your source code, and resolves any external dependencies before moving the output to a specific directory ready for publishing to another machine.
The description on the dotnet publish command documentation states:
dotnet publish compiles the application, reads through its dependencies specified in the project file, and publishes the resulting set of files to a directory. The output includes the following assets:
Intermediate Language (IL) code in an assembly with a dll extension.
.deps.json file that includes all of the dependencies of the project.
.runtime.config.json file that specifies the shared runtime that the application expects, as well as other configuration options for the runtime (for example, garbage collection type).
The application's dependencies, which are copied from the NuGet cache into the output folder.
dotnet build is only really useful for building on your development machine, and when used in conjunction with dotnet run against a project file.

DotNet Pack Not Doing Anything

I am trying to create a nuget package for my web application but it is not producing any .nupkg outputs. I am using Visual Studio 2017 15.3.0.
To create the project I do the following:
File - New - Project,
Visual C# - Web,
Asp.Net Core Web Application,
Web Application
Then I go to a command prompt in the directory with the csproj file in and type:
"Dotnet Pack"
I get only the following output:
Microsoft (R) Build Engine version 15.3.409.57025 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.
But no nuget packages are created. I am expecting something like:
Producing Nuget Package "App.1.0.0" for App
Do I need to do anything else eg to the csproj file ?
Web applications are not packable by default. To change this, modify your csproj file to include this property:
<PropertyGroup>
<IsPackable>true</IsPackable>
</PropertyGroup>
Note that as of now (2017) there isn't a good story for "library web projects" or web project packages that work for all scenarios you would want to use a NuGet package for. But this property will at least unblock producing a package.
I had the same issue with VS2022, looked at the documentation and noticed they "silently deprecated" the command.
You now should add the following in your .csproj file:
You then generate a package and copy it to the "right" folder by calling
dotnet msbuild -t:pack -property:Configuration=Release "ProjectFile.csproj"
Have a look at the link, the title is a bit confusing but there seemed to have been a change after With MSBuild 15.1+

Compile a .NET Core application as an EXE file using Visual Studio 2017

I created a .NET Core application (v1.1) in Visual Studio 2017. When I compile it, I get a DLL file produced instead of the expected EXE file for the built project. I did check the csproj file and confirmed the output type is set to exe, but no dice.
Why is Visual Studio 2017 is still producing a DLL file?
I'm sure it's a quick setting somewhere that I forgot...
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core.EF.SqlServer\Core.EF.SqlServer.csproj" />
</ItemGroup>
</Project>
Update 2019:
.NET Core 3.0+ projects will now include an executable for the platform you build on by default. This is just a shim executable and your main logic is still inside a .dll file.
But .NET Core 3.0 also introduced single-file deployments so deploying with
dotnet publish -r win-x64 -p:PublishSingleFile=True --self-contained false
will create a single .exe file containing all your dependencies. You can change --self-contained to true to also include the .NET Core Runtime as well so .NET Core does not need to be installed globally on the target machine.
Original
.NET Core applications are supposed to be .dllfiles. OutputType set to Exe in this case means "executable" and does everything necessary to ensure that the output is runnable (entry point from Main() method, .runtimeconfig.json file). The resulting DLL file is meant to be run using:
dotnet yourapp.dll
This DLL file works across all platforms that are supported by the .NET Core runtime (Windows, Linux, and macOS). This is called a "portable" or "framework dependent" deployment.
If you want really a .exe file, consider self-contained deployments. This will create an output that contains its own copy of the .NET Core runtime and an yourapp.exe file - but it also increases the size of the published application and it needs to be updated when new versions of the runtime are released.
Also, the resulting application only works on the operating system published for.
Refer to .NET Core application deployment for more details on the deployment options and how to set them up.
In Visual Studio 2017:
Right click on your project and select Publish (In Visual Studio 2019, click on menu Build → Publish <projectName>)
Select 'Folder' and create a new profile
In tab 'Publish', click 'Configure...'
Select Deployment Mode: Self-contained, Target Runtime: win-x86 (or win-x64)
Save
Publish
In the folder <Your project>\bin\Debug\netcoreapp2.1\win-x86\ you will see the EXE file:
Starting with .NET Core 2.2 you can build framework-dependent executables
Although building a self-contained deployment can be a good solution, it has its own drawbacks. (See R.Titov and Martin Ullrichs' answers on SCD-s.)
Fortunately, .NET Core 2.2 supports the building of so called framework-dependent executable-s, that are essentially a wrapper binary (.exe on Windows) around the standard dll-s.
This way you have all the advantages (and disadvantages) of the standard framework-dependent deployment (again, see Martin's answer), but you have a convenient way to launch it, without having to call it through the dotnet CLI.
You can publish your app as a Framework-Dependent Executable using the following syntax:
dotnet publish -c Release -r <RID> --self-contained false
Where RID is the usual runtime identifier, e.g. win-x64 or whatever platform you wish to build for (see the catalog here).
That's how you do a self-contained publish with command-line in any OS:
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64
Besides, you might want to get the output decreased from typical ~60 MB for a simple Hello World app to ~30 MB by using ILLink.
Also, you might want to go further and get a single .exe file of a size at around 5 MB and use ILCompiler. See this reply.
The other answers are good, but what I find sometimes convenient is:
Not have it self-contained because the target machine is likely to have .NET Core of the correct version installed. This cuts on number of the DLL files I need to ship.
Not have to specify dotnet on the command line
For this, a bat file wrapper can be used, similar to these lines:
#ECHO OFF
REM see http://joshua.poehls.me/powershell-batch-file-wrapper/
SET SCRIPTNAME=%~d0%~p0%~n0.dll
SET ARGS=%*
dotnet "%SCRIPTNAME%" %ARGS%
EXIT /B %ERRORLEVEL%
If your application ends up in yourapp.dll, name the bat file yourapp.bat and place it along side the DLL file. Now instead of dotnet yourapp.dll params you can call yourapp params.
Note that the context of this answer is in-house tooling, so all the developers using the utility will have a pretty standard development machine setup. If this is to be distributed to an external customer who is running who knows what on their boxes, the self-contained option is far superior.

Resources