When I compile my C# Console it comes with an dll, if I remove the dll the application doesn't work, and I need it to work with only an .exe and no .dll files.
https://prnt.sc/t1gu4m
Right Click your Project
Select Publish
Deployment Mode: Self-Contained
Check the Produce single file option
Et voila, you got a single exe with the required dependencies
In addition to Maurice Legoland's answer. If you're using dotnet cli, run:
dotnet publish -p:PublishSingleFile=true --no-self-contained # Other arguments.
Only use the --no-self-contained flag if you want your executable to be dependent on .NET i.e, it cannot run without the user having .NET's CoreCLR. Otherwise simply set PublishSingleFile to true. You can also use a manifest/configuration file. See this for more information.
Related
MSBuild error MSB4018 cannot access project.assets.json in NET 5 build operation
MSBuild error MSB4018
I am building 70 C# NET 5 projects in parallel groups and sometimes get the following error on random projects within the build
error MSB4018: The "GenerateDepsFile" task failed unexpectedly.
[c:\dev\highspeed\HsCore\hscore\HsCore.csproj]
C:..\sdk\6.0.202\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets(172,5): error MSB4018: System.IO.IOException: The process cannot access the
file
'c:\dev\highspeed\HsCore\hscore\bin\Debug\net5.0-windows7.0\win-x64\HsCore.deps.json'
because it is being used by another process.
[c:\dev\highspeed\HsCore\hscore\HsCore.csproj]
The Microsoft doc says: This error is emitted when a task fails with an unhandled exception. This is generally a sign of a bug in the task. Error MSB4018 may be caused when running a task in an environment that it was not prepared for, for instance when a task has an x86 dependency but is running in a 64-bit MSBuild environment. This can manifest as a System.DllNotFoundException.
In my case, I am totally in a windows x64 environment, building and using AnyCPU libraries (and publishing to win-x64, but that doesn’t matter before the build runs).
I invoke the build on xxx.sln files with the following arguments:
Exit Code 1: /t:Clean;Restore;Publish /p:Platform="Any CPU"
/p:Configuration=Debug /p:TargetFramework=net5.0-windows7.0
/p:RuntimeIdentifier=win-x64 "c:\path\MySolution.sln"
The code normally builds and runs fine, except for when this kind of an error occurs. Often, when I run the build a second time, the build succeeds.
I do not understand why the MSBuild process (or one of its processes) cannot access the project.assets.json file, because MSBuild is the only one who ever accesses that file in that project. None of my tools ever reference that file; Visual Studio does not have the file or project open; No other projects in the parallel build group would ever access the projects.assets.json file anyway; so MSBuild is the only one working with the entire project tree.
The best I can think of is that maybe the Restore target in the Clean;Restore;Publish chain might be locking the file and not releasing it fast enough for the Publish(Build included) operation. But wouldn’t MSBuild be smart enough to manage that kind of thing?
Does anyone have any idea what might be going on? What other process could possibly be looking at (and locking) that file? Thank you
After days of debugging and investigating, I am convinced the problem is caused by using MSBuild multi-core operation (-m:) when building my solution (.sln) files.
If I remove the -m MSBuild command line argument, all the weird "file being used by another process" errors go away instantly. If I enable the -m:2 argument (or higher, or unbounded -m), the errors come back, instantly.
My .sln files that fail typically have three .csproj projects - a library DLL project, a LibraryXxxTests project, and a thin console program interface to the library. The Tests and console projects typically use a project reference to the library project.
Maybe (but I can't imagine why) the project references that point to the library project open the gate for MSBuild parallelism errors. (But MSBuild -m should be smart enough to see the project references and build the library project first before the console and Tests projects that reference the library DLL, yes?)
The other kind of project that sometimes fails has only two projects (lib and tests project).
My solution file and project files do nothing special or tricky - as far as I know, they are typical C# projects with 20 - 50 C# files. The errors occur on the main DLL file (Library.DLL) produced by the build, when some process is trying to write to that .DLL file and can't do it because of a lock. I don't know why.
But I do know that if I remove the MSBuild -m command line argument, the errors go away. Back to serial builds at the solution level for me ...
UPDATE: I wanted to believe MSBuild could figure out the build order among projects in a solution file, so I did more searching on the net. I found this information in the MSBuild documentation on how it calculates builds.
Graph option
If you specify the graph build switch (-graphBuild or -graph), the
ProjectReference becomes a first-class concept used by MSBuild.
MSBuild will parse all the projects and construct the build order
graph, an actual dependency graph of projects, which is then traversed
to determine the build order. As with targets in individual projects,
MSBuild ensures that referenced projects are built after the projects
they depend on.
Using the -graph option with the -m option seemed to work for solution-level builds (passing .sln files to MSBuild). The graph option tells it to calculate a build order graph among projects within each solution file. The -m -graph combination seems to let me use multiple cores to do the builds in a shorter time without MSBuild getting access errors among projects within a solution.
Keep in mind that this method requires that you use ProjectReferences in your project XML files. If you use direct assembly references to the project.DLLs stored in some other location, the -graph option cannot calculate a proper build order within the solution.
UPDATE 2:
The information about using -graph above seemed to help but did not solve all the problems. I was lucky enough to find the following information on GitHub:
I'm tempted to call this a duplicate of #9585, which is itself not the
first time the problem has been found but I can't find the original.
Problems arise whenever you explicitly pass a --framework (CLI) or
/p:TargetFramework= (direct MSBuild) to the build of a solution. The
issue is that global properties (such as that TF setting) are
inherited in most cases, but not all. Here, the ClassLibrary1 project
is built once with an explicit TF (inherited from the solution build)
and once with no TF (since it only has one, the ProjectReference from
WebApplication1 does not pass its TF down).
The best way out of this is to only pass --framework to builds of
individual projects, not solutions. Project-to-project references are
careful not to get into this situation.
Removing the /p:TargetFramework=win-x64 from the msbuild command line when building .SLN files seems to be working for me so far.
I have been running into an error lately trying to run some code with dotnetcore. When I try to run the project in the console (dotnet run), I get this error.
Unable to run your project.
Ensure you have a runnable project type and ensure 'dotnet run' supports this project.
A runnable project should target a runnable TFM (for instance, netcoreapp2.0) and have OutputType 'Exe'.
The current OutputType is 'Exe'.
FYI, here are entries in the .csproj file
Also, I have the following skds and runtimes installed. Yet, whatever TargetFramework I set in the .csproj, I get the same error.
I found a solution to my issue.
The problem was that I had created the project using Visual studio. Hence, the .csproj project file was not in a suitable format for dotnet core.
To solve the issue, I created an empty project with dotnet core:
mkdir myNewApp
cd myNewApp
dotnet new console
Then, I added to the project all the source files I had created with visual studio by simply copying and pasting them in the app folder. I grouped them in the single directory 'src'. At build, dotnet core automatically finds these files and builds the project with them.
Mine is an Azure Durable function. I got the following error when I try to run it with dotnet cli using the command dotnet run.
Unable to run your project.
Ensure you have a runnable project type and ensure 'dotnet run' supports this project.
A runnable project should target a runnable TFM (for instance, net5.0) and have OutputType 'Exe'.
The current OutputType is 'Library'.
The solution is simple. You cannot use dotnet cli for this. Instead You need to run using the command func start as explained here.
And of course you need to install the azure function tools.
Most probably it is do something with the version you are trying, in my case, I was using .nerstandard 2.0 which was wrong and I changed it to net5.0 and I was able to run successfully.
It looks like this now -
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
I have experienced the same problem that the project refuses to create an EXE file. It was showing to compile a DLL, yet required an EXE to run.
I was using dotnet core and VS-Code and didnt suspect anything until I tried to rename the project folder to start another with the same name. What I got was greyed out folder/file names for some time about 10 sec with no name change.
Only then I realized: though I deleted "bin" folder, there was an instance of the project somehow running alive but hidden (should have prevented me deleting folder otherwise) and prevents any new EXE to be written.
Solution you might ask, simple: just close/restart IDE completely. Any program spawned with it will be terminated. trying to close/terminate terminals do not work.
Open CMD.EXE and run the following commands:
dotnet new console -o myApp
cd myApp
dotnet run
It works for me.
https://dotnet.microsoft.com/learn/dotnet/hello-world-tutorial/run
I have a solution with two projects:
C# console application (.NET Core 3.1)
and C++ Dynamic Library (.dll)
I need to call the C++ DLL from the C# project, using DllImport. When I provide the full path of the DLL, the application finds it. But I want to replace the path with a relative path, and I can't figure out how to do it.
First of all, make the C++ project a dependency of the C# project. This ensures that the C++ project will be built before the C# project if it's outdated. You can set the project dependencies in the solution settings.
Now that we ensured that the dll is always up to date, we have to somehow get it in the same directoy as the C# executable. We have two options:
a post build command to copy the dll to the output directory of the C# project, or
we set the output directory of both projects to the same directory.
Post build event
We can simply use a copy command. Go to C++ project settings > Build Events > Post-Build Event and copy the following command to to the Command Line field:
xcopy /y "$(OutDir)*.dll" "$(SolutionDir)MY_CSHARP_PROJECT_NAME\bin\$(Platform)\$(Configuration)"
Replace MY_CSHARP_PROJECT_NAME with the name of your C# project. I'm using the default paths here, depending on your solution you might have to tweak the paths a bit.
Shared build directory
I wouldn't recommend this one, because you can run into trouble with it.
Go to the Build tab in the project settings of your C# project.
At the top of the page select Debug as configuration.
At the bottom of the page change Output path to match the C++ output directory for Debug builds (this one is usually in the same folder as the solution file).
Repeat 2 and 3 but this time with Release instead of Debug.
When I migrate WPF Project to .NET CORE 3.0 and try to pack assemblies using Costura I am getting the following error:
The target process exited without raising a CoreCLR started event. Ensure that the target process is configured to use .NET Core. This may be expected if the target process did not run on .NET Core.
The program '[7980] CryptoBot.exe' has exited with code -2147450740 (0x8000808c).
The program '[7980] CryptoBot.exe: Program Trace' has exited with code 0 (0x0).
I found out that the reason for this behavior is that Costura.Fody doesn't properly handle *.deps.json file and that it should be 'removed or modified accordingly' by me.
There are two problems with this approach:
First: I am using database.sqlite file to store the data, removing *.deps.json will break references to e_sqlite3.dll and I don't know how to modify it properly (just add sqlite basic packages using nuget to an empty project if you want to check it out):
Second: Even if it did work it doesn't produce a single .exe file, but rather small .exe and big .dll containing the dependencies.
The desired result: I would like it to work exactly as it worked in .NET Framework, I want single .exe containing all the .dlls produced on DEBUG after pressing CTRL + SHIFT + B.
Alternatively, I also tried this:
dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
but it didn't seem to pack anything at all, it just placed all the .dlls in the Release\netcoreapp3.0\win-x64 folder.
I PREFER that the app is packed into SINGLE .exe by using Costura and NOT anything else.
I downloaded a package from SourceForge, PlanEph, which has 64 and 32 bit DLLs for C#. I got the 32 bit included C# demo to work by putting the DLL in my bin/Debug directory (I'm using Visual Studio 2015 Community) and adding the DLL as a reference.
Then I tried to make my own version of the demo in a separate solution, and got the System.DllNotFoundException. Various experimentation lead me to believe I can't have two identical namespace names anywhere in my Visual Studio installation, so I erased everything and started over.
I made a directory C\GJAbin, put the DLL in it, and added it to the system Path variable. I also put a helloWorld type program in that dir and executed it from the command line to verify the directory really was in the path. Then I recreated the demo solution, added the DLL as a resource, and built the solution "successfully". Then I ran it and got the System.DllNotFoundException.
So I can't understand why the DLL is being found when compiling but not at run time.
Go to project settings, go to "publish" tab and on the top most button (labeled something like "application files"). Chose "Show all files" checkbox if you don't see your DLL. Set the DLL's publish status to "Include" (NOT "Include (Auto)"!!) and publish it again.
Now the DLL should be inside the publish folder.
So I can't understand why the DLL is being found when compiling but not at run time.
Locating the assembly at compile time is done differently (by MSBuild) than at runtime (by the CLR).
At compile time, MSBuild has specific search paths that it knows about, or in most cases like this, there will be something in your project file telling MSBuild where to look for the file. Usually the <Reference> has a <HintPath>.
At runtime, the CLR will attempt to find the assembly from its own set of well-known paths. It will look in your app's config file (if applicable), then in the Global Assembly Cache (GAC), then in your app's root directory. Much more detail on this is available here.
You can tell MSBuild to copy the reference to your build output directory (usually the same as your app root directory when running). In VS, you can do this by selecting the reference and looking at the Properties tool window (or press F4 by default). Set the CopyLocal state to True. In the project file, this will add a <Private>True</Private> on the <Reference>.
You can also add the assembly to the GAC using the gacutil tool, but this does make it harder if you want to share your app with others. Usually it's preferable to keep a copy in your app root directory.
If it's still not working, you can also see the log for how the runtime is trying to find this assembly. The fuslogvw.exe tool in the Windows SDK (you can run it from the VS command prompt and it will be on the %PATH%) allows you to enable logging for assembly loads. You do need to be able to run this as an administrator to configure the setting.
As you can see in the screenshot, you can either log the results in the exception (so that you can see it while debugging), or you can log it to a file on disk (so you can see it whenenver).
The problem turned out to be an unfortunate interaction among the way the author chose names and the way Visual Studio displays information and error messages. The author created a c# dll Astronomy.PlanEph32.dll containing a namespace PlanEph32, which which was really just a wrapper for the c dll PlanEph32.dll. So all the error messages about not being able to load PlanEph32.dll were referring to not finding the c dll; the c# dll was being found just fine.