I am migrating a medium-sized Win10 app (.NET Framework 4.8) to net5-windows. The solution contains about 30 projects.
While the migration process worked rather straightforward in Visual Studio 2019 (Version 16.8.3) the only problem remained to package everything in a self-contained exe. Instead of struggling with the project entries in VS, I am using the command-line method discussed by Scott Hanselmann in his blog. This also worked smooth and produced an exe of about 140MB size.
One issue remains: Not all of the system dll's are included in the exe. The following ones have to be copied manually to the directory of choice:
Without these DLLs the app does not work.
My question: What is the reason for this behavior, and how can these dll's be included in the self-contained exe?
To include a system DLLs into single file app you should use IncludeNativeLibrariesForSelfExtract property or /p:IncludeNativeLibrariesForSelfExtract=true switch for dotnet publish command, as mentioned in single file publish design document
Related
I have C# application (.NET Framework 4.6.2) with WebApi projects which references System.Runtime.InteropServices.RuntimeInformation (v4.3.0) library through nuget package. See
Nuget package reference screen Package was auto-installed as a dependency of 'Microsoft.CodeAnalysis.Razor.2.2.0, Microsoft.DotNet.PlatformAbstractions.2.1.0'
This application was working fine (Builds from my localhost are ok) until I tried to do automatic builds from my teamcity server (different machine). For some reason builds of my app which are provided by teamcity will not start. I get error Could not load file or assembly 'System.Runtime.InteropServices.RuntimeInformation, Version=4.0.2.0...'
So I started to investigate and I found out this:
Builds from my localhost (bin/debug) contains lib System.Runtime.InteropServices.RuntimeInformation.dll (File version=4.6.26011.1, Date modified=10.8.2021) --this build works fine
Teamcity build contains lib System.Runtime.InteropServices.RuntimeInformation.dll (File version=4.6.24705.1, Date modified=11.5.2016) --this build is not working
Nuget package which was downloaded (..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0) on both machines (localhost and teamcity server) contains System.Runtime.InteropServices.RuntimeInformation.dll (File version=4.6.24705.1, Date modified=11.5.2016)
And now I am stuck and literally dont know how to investigate it further. Questions I am asking myself:
How is it possible that my localhost builds contains this reference lib with file version 4.6.26011.1 when in my \packages\ folder this .dll contains file version 4.6.24705.1? Does msbuild maybe take this reference from different location? But from where? I swear I searched my computer and I did not found this library in version 4.6.26011.1 (which is apparently copied to bin/debug by msbuild).
Is there a way to monitor msbuild process and see from where it copies this .dll reference to my bin/debug/ folder on my localhost machine?
How to fix my references so the app runs fine?
21.6.2022 Edit:
Thanks to #mu88 comment I have managed to find out that this library is copied from this location: "C:\Program Files\JetBrains\JetBrains Rider 2021.2.2\tools\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net462\lib\System.Runtime.InteropServices.RuntimeInformation.dll" to my bin\debug. I have zero ideas why msbuild is using this path for this lib. (This is only library which is copied from this path)
--Additional info: I am using some AspNetCore references (e.g Kestrel, ..) so I am targeting .Net Standard 2.0. Could this relate? I am asking because my investigation lead to this issue: ms-build-extensions-file-corrupt-my-bin-web-api-folder. In this issue I have found other links to people having similiar problems like this. I just dont understand the solution there :(
So I managed to solve my problem. I had to install .NET SDK to Visual Studio Build Tools 2019 via Visual Studio Installer. Which done "some" magic and it created *MSBuild\Microsoft\Microsoft.NET.Build.Extensions* folder to my msbuild and now during the build process some System libraries are "overidden" and copied from this new location.
So even if I use nuget to download System lib then this package is not used during the build.
I did not manage to find any more info about the build process :( It would be nice if someone could explain this to me. I created a separate question for this here: What is Microsoft.NET.Build.Extensions and how does it work?.
Let us imagine that we have two projects:
AspNetRunnerProject – an ASP.NET 6 project which is capable of loading DLLs of classlibs and serves as a driver/executor of such classlibs.
ClassLibraryProject – a .netstandard 2.1 classlib project which uses AspNetRunnerProject's nuget as its driver
What I've been able to do so far is to publish ClassLibraryProject as a self-contained app. This way all the DLLs that are needed (any kind of NuGet package or .NET 6 runtime DLLs) are bundled inside a common folder and the app can be executed with dotnet AspNetRunnerProject.dll. This way the driver project loads the classlibs it needs and runs it all.
Is it possible to publish the ClassLibraryProject (which has a NuGet reference towards the AspNetRunnerProject) as a framework dependent deployment instead of self contained app so that it can still be run with dotnet AspNetRunnerProject.dll?
If I try to execute something like the last command I get the info that "AspNetRunnerProject.deps.json" file does not exist, because the file that exists is actually "ClassLibraryProject.deps.json"?
Simple copying of this file to desired name does not solve the issue.
After researching for a few days I came to the following conclusions:
Find the ClassLibraryProject.runtimeconfig.json file in the published artifacts and rename it to AspNetRunnerProject.runtimeconfig.json
Execute the app with dotnet AspNetRunnerProject.dll
Alternatively it is possible to have a global appname.runtimeconfig.json file which could be used across multiple such projects.
For more info check https://learn.microsoft.com/en-us/dotnet/core/runtime-config/#runtimeconfigjson
i'm trying to obtain an executable file with only the necessary dlls in the release folder, unfortunately VS is putting in that folder even System dlls, that afaik are not supposed to be redistributed with the executable.
I'd like to know if there's a way to make VS add to the release folder only dlls the executable can not work without, the ones that are supposed to be redistributed.
Thank you.
Release folder:
These assemblies are shims for .Net Standard where the full framework had gaps. Based on the assemblies in that folder, I assume that your exe is targeting .net 4.6.x and you are consuming a .net standard library.
If you upgrade to .net 4.7.2 you will see the number of required System.* assemblies reduced greatly.
See this answer for more details: Why does my .NET Standard NuGet package trigger so many dependencies?
I'm assuming this is a dotnet core project. Use the "dotnet publish" command to create your deployment files (the screenshot looks like a VS build directory?). You might see more dlls than you're used too if you're coming to dotnet core from using the Windows frameworks previously, but it depends on the publish options you use.
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish
Last year, I asked the question how to solve a DllNotFoundException for sharpdx_direct3d11_effects_x64.dll with SharpDX.Direct3D11.Effects.dll version 3
Now I'm trying the same thing with version 4.
I was expecting the two DLLs sharpdx_direct3d11_effects_x64.dll and sharpdx_direct3d11_effects_x32.dll to be added to the Visual Studio project but they are not.
Has the deployment mechanism for these two DLLs changed?
Has the deployment mechanism for these two DLLs changed?
Yes, the author of this package xoofx has changed deployment mechanism for these two DLLs from the version 4.0.0-ci120. You can check the the 4.0.0 release notes about Updated D3D11.Effects to the new project system..
Besides, you can download two version of this packages, check the different with NuGet Package Explorer:
According to the official document: Supporting multiple .NET framework versions:
If you have architecture-specific assemblies, that is, separate assemblies that target ARM, x86, and x64, you must place them in a folder named runtimes within sub-folders named {platform}-{architecture}\lib{framework} or {platform}-{architecture}\native.
So the change in the deployment mechanism is correct.
OK I got this to work thanks to #Leo-MSFT's answer above.
I had to download the NuGet package from here.
Rename to *.zip and unzip
Copy the folders runtime/win-x64/sharpdx_direct3d11_1_effects.dll and runtime/win-x86/sharpdx_direct3d11_1_effects.dll to my project and set to Copy Always
This didnt' work so I now copied win-x64/sharpdx_direct3d11_1_effects.dll to the project root and renamed as win-x64/sharpdx_direct3d11_1_effects_x64.dll and set to Copy Always and it worked.
I'm sure this isn't intentional so I've reported a bug to SharpDX on Github.
Is there any way to package a C# project that am working on in Visual Studio 2015 Community into a stand-alone executable that doesn't need any other files or VS/.NET dependencies? Thanks in advance.
If you are developing an application with .net, it will always need the .net dependencies. Depending on any libraries that you use, you will need them as dependencies as well. If you truly want a native single exe than there are some third party vendors that can do this. They make virtual applications that package the dependencies inside of the exe. They are not free and I have not had good luck with these, but worth a shot.
One example https://turbo.net/studio
Build your project in release and you can use the output exe from bin/Release folder as a standalone executable.
If it has dependencies on assemblies which are not part of .NET framework you also need to merge all referenced dll assemblies into one exe file using ilmerge.
In both cases, users needs to have .NET framework installed on their machine.
The bin, obj, properties, etc. directories are part of your source code project not your executable. To exe application gets created in the bin directory. If you build it in debug mode, you'll find it in the bin\Debug folder. If you build it in release mode, you will find it in the bin'Release directory, etc.
That exe file should be good to run in any other computer.