Why does dotnet publish create 2 copies of the same files? - .net-core

I asked here how to create a .exe to run on Windows and learned the command
dotnet publish --configuration Release --runtime win-x64
This created files in the \bin\Release\netcoreapp2.0\win-x64 folder
as well as a subfolder called publish which contains a copy of the same files.
Why are duplicate files created? ( In the Win-x64 folder and in the publish folder)

dotnet publish builds the project before copying binaries to the output directory. The files you see in bin\Release\netcoreapp2.0\win-x64 directory are the result of dotnet build command. You could check it by running following command:
dotnet build --configuration Release --runtime win-x64
You will see exactly the same files as if you run dotnet publish --configuration Release --runtime win-x64.
Output binaries provided by build stage are then copied to publish directory together with required dependencies. You probably could expect that binaries are built right away to publish directory without necessity to duplicate them from build directory to publish. Well, it's a fair assumption. However it will harm separation of different stages - build and publish. Also as far as HDD resource is very cheap now, it shouldn't be a big issue.

Related

Different number of files when I make an application using self-contained

When I use the publish wizard built into VS 2019 all the files I require are created (271 files). There are the files System..dll, api-ms-win-crt-utility-l1-1-0.dll etc.
However, when I use the command below, I only have 60 files and unfortunately the Windows Service application will not work. What do I need to add to the command so that the number of files is the same as that produced by the publishing wizard ?
dotnet publish /p:Configuration=Release /p:self-contained=true /p:framework=net5.0 /p:runtime=win-x64 /p:Platform="Any CPU"
Have you tried the following dotnet publish format:
dotnet publish --configuration Release --self-contained true --framework net5.0 --output "C:\Users\YourUserName\YOUR_RELEASE_FOLDER" --runtime win-x64

Why does `dotnet publish` use binaries from obj folder and not from bin folder?

I want to separate the build and publish processes, to do so I run the dotnet build command, collect the build output (that is everything in project's bin folder), then on a separate machine I restore collected build output from previous step, run dotnet restore (to restore NuGet packages) and run dotnet publish --no-restore --no-build command, unfortunately I get an error that it is impossible to copy myapp.dll from obj folder (not from bin) to the publish directory.
Why does dotnet publish use built binaries from obj folder and not from bin?

runtime folder with dotnet core application

If I create a net core 2 console app and get it to reference another project e.g. MyLibrary.csproj
This (MyLibrary.csproj) is a net core class library
If I run dotnet publish -c release --output test1
then in the output folder their is a runtime folder present
I have not found anywhere that describes this folders purpose.
Any one have a link?
Also do I need to copy this as part of my deployment?
The example I have has a reference to System.Data.SqlClient.dll which is present in the root publish folder(test1) so why does it need to get it from the runtime folder when I try to run via dotnet my.dll?
From the docs (https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore2x)
dotnet publish - Packs the application and its dependencies into a folder for deployment to a hosting system.

Publishing a dotnet application that's already running

I'm attempting to create a script to simplify the process of publishing a .NET Core website. I'm running into an issue when I run dotnet publish against an already running server. The server is IIS with the dotnet bundle installed, so IIS uses its app pool to start dotnet.
Here's my batch file. I'm happy to use another script type:
cd src/app
dotnet build --no-incremental
dotnet publish --framework netcoreapp1.0 --configuration Release --output ../../dist
When I run the script I get this error:
"The process cannot access the file 'C:\inetpub\wwwroot\app\dist\app.dll' because it is being used by another process."
This makes sense, it appears I need to stop, deploy, and restart dotnet. Can I do this from the script? Or is my approach to this problem wrong?
The best way is to drop an app_offline.htm file to your application folder. This will make IIS stop your application and serve the contents of the app_offline.htm file to the user while you are copying the new version. Once you complete copying the new version of your application remove the app_offline.htm file and IIS will start your application.
You can find more details on running ASP.NET Core applications with IIS in my post.
Based on Pawel's answer, I have a deploy folder containing my app_offline.html file and multiple deploy scripts to IIS. Here's a sample script I use to deploy:
copy .\app_offline.htm C:\hosting\my-project\app_offline.htm
dotnet publish ../MyProject.csproj -r win-x64 -f netcoreapp2.1 --self-contained -c Release -o C:\hosting\my-project
del C:\hosting\my-project\app_offline.htm
I think this is a valid solution, but doesn't help when I want to script the build process.
Stop-Website "xxx"
Stop-WebAppPool "xxx"
Start-Sleep -Seconds 5
dotnet publish --output d:\publocation
Stop-WebAppPool "xxx"
Start-Website "xxx"
if you've created a published profile in Visual Studio and you're using IIS, then you can use that profile instead of writing directly to the destination directory:
dotnet publish /p:PublishProfile=Properties\PublishProfiles\IISProfile.pubxml

Compile multiple dotnet core projects in one step using dotnet cli

Assuming this folder structure
SampleApp
global.json
Src
Web
project.json
Startup.cs
...
Model
project.json
Startup.cs
...
how does one compile both projects using dotnet? (from command line, not in visual studio)
If you run dotnet build at the root folder level you get
Could not find file .. project.json
I can see there is this outstanding enhancement on the CLI repo but that is from Feb2.
Any script would have to take dependencies into account before just blindly calling dotnet on all src sub-folders.
The dotnet build command accepts glob patterns. So you can do this:
dotnet build Src/**/project.json
There's no such a tool yet. Even KoreBuild, the tool that the ASP.NET team uses, goes blindly in each folder and invokes dotnet build/pack.
The nice thing is that dotnet build is now smart enough to not recompile the dependencies if they haven't changed, so that's not a problem anymore.
For linux I'm using:
for p in $(find . -name *.csproj); do dotnet build $p; done
I had a similar requirement. This is my workaround:
#echo off
for /D %%d in (*) do (
cd %%d
cd
dotnet restore
dotnet build
cd ..
)
exit /b
Use GNU Make. I use it to build my projects. all you have to do create a Makefile in your project root folder. You can nest Makefiles in directories and have a Top Level Makefile that runs the subdirectories. then you set up Makefiles for each of your "Sub Projects" folders and run any comandline tool. with dotnet core is is dotnet .
Wait... GNU - "GNU is not Unix" that's a Unix/Linux application... I run windows. Well the good news is you can do this is in windows. I'm using make.exe through my git-bash installation (git for windows). You will have to go find the cygwin port of make. (google: "make for git-bash") Then install it to your bin directory under the cygwin folder. You could also just install cygwin if you really wanted to.
The nice thing about using Gnu-Make is it is universal. Since dotnet core is platform agnostic, every environment Mac/FreeBSD/Linux have "make" most likely already installed. Adding it to your Windows machine and projects to me makes a lot of sense. Since you project can now be built by everyone the same way.
some of my projects need to build docker containers with dockerfiles, or snap packages, deploy to test, etc... Make (pardon the pun) makes it easy.
Here is a sample of simple projects Makefile. Running 'make' by itself is like saying 'make all' you could set up a command like 'cd ./subdir; make' as one of your .phoney directives. (Google: "Makefile documentation")
project_drive?=/c/prj
nuget_repo_name?=Local_Nuget_Packages
local_nuget_dir?=$(project_drive)/$(nuget_repo_name)
RELEASE_VERSION:= `grep "<Version>" *.csproj | cut -d '>' -f 2 | cut -d '<' -f 1`
.PHONEY: clean release test doc nuget install debug_nuget debug_install
all: doc MSBuild
test:
./test.sh
MSBuild:
dotnet build
clean:
dotnet clean; dotnet restore
release:
dotnet build -c Release
doc:
doxygen ./Doxyfile.config
nuget: release
dotnet pack -c Release
install:
cp ./bin/Release/*.$(RELEASE_VERSION).nupkg $(local_nuget_dir)
debug_nuget: MSBuild
dotnet pack
debug_install:
cp ./bin/debug/*.$(RELEASE_VERSION).nupkg $(local_nuget_dir)
What's missing is that you can also use the commands on project.sln files if you do not have project.json
dotnet build src/**/project.json
-- or --
dotnet build src/project.sln
same goes for dotnet test

Resources