This is a series on the .Net Core 1.0 bits. Looking for .Net Core 2 Series?
- Getting Started
- What’s in the box
- Using Multiple Projects
- Testing
- NuGet
- Multi-targeting
- Publishing Portable Applications <=(We are here)
- Self-contained Applications
We can now take everything we have learned and start publishing our applications. Luckily, there is a command for that too.
The Setup
I don’t know why I bother saying anything here, this is pretty straight-forward by now.
mkdir mynewapp
cd mynewapp
dotnet new
dotnet restore
dotnet build
And again, we replace the contents of Program.cs. This time, lets try printing a few verses of Dr. Seuss Explaining Computers
using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Dr. Seuss Explains Computers");
Console.WriteLine("============================");
Console.WriteLine("");
Console.WriteLine("If a Packet Hits a pocket on a socket on a port, and the bus is interrupted as a very last resort, and the address of the memory makes your floppy disk abort, then the socket packet pocket has an error to report.");
Console.WriteLine("If your cursor finds a menu item followed by a dash, and the double-clicking icon puts your window in the trash, and your data is corrupted 'cause the index doesn't hash, then the situation's hopeless and your systems gonna crash!");
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("Read the rest at: http://computerjokes.net/112.asp");
Console.WriteLine("");
}
}
}
And for good measure another build.
dotnet build
Publishing
To publish our application we use the most obvious of commands:
dotnet publish
Which results in the following file structure.
mynewapp
|-- Program.cs
|-- project.json
|-- project.lock.json
+-- bin
+-- Debug
+-- netcoreapp1.0
|-- mynewapp.deps.json
|-- mynewapp.dll
|-- mynewapp.pdb
|-- mynewapp.runtimeconfig.dev.json
|-- mynewapp.runtimeconfig.json
+-- publish
|-- mynewapp.deps.json
|-- mynewapp.dll
|-- mynewapp.pdb
+-- mynewapp.runtimeconfig.json
The publish
command adds a new build artifact folder - publish
. Inside are all of the files for the application to distribute (to someone who has the runtime available). In this case our application is a netcoreapp1.0, so the distribution is the dll, to run with .Net Core runtime.
We can execute our application using the command dotnet mynewapp.dll
from inside the publish folder, or from the project folder using a relative path dotnet .\bin\Debug\netcoreapp1.0\mynewapp.dll
.
Output folder
We probably want to publish to a different location, so we can use the option -o <OUTPUT_PATH>
to publish somewhere else. At the same time, we might use the -c <CONFIGURATION>
option to specify a release build.
dotnet publish -o "../Pack/mynewapp" -c Release
Which will give you the following in the Pack folder:
Pack
+-- mynewapp
|-- mynewapp.deps.json
|-- mynewapp.dll
|-- mynewapp.pdb
+-- mynewapp.runtimeconfig.json
Include Files
We can also include extra files into our output folder. For instances lets add a readme.md
file beside our program.cs
file.
MyNewApp
========
version 1.0.0
This app prints the first verse of a poem.
In our project.json
file we can add packageOptions
includeFiles
properties, to include our readme.md
file.
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"publishOptions": {
"includeFiles": [
"readme.md"
]
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
},
"imports": "dnxcore50"
}
}
}
dotnet restore
dotnet build
dotnet publish -o "C:\dev\publishingapps\Pack\mynewapp" -c Release
Note there is a current(1.0.0/1.0.1) bug that you need to specify the full path to the app for the output path or it will not include included files correctly. https://github.com/dotnet/cli/issues/3951
(This appears to no longer be a problem for the upcoming csproj
changes.)
Otherwise, that’s how easy it is to include extra files when publishing.
Publishing .Net 4.5.2 applications
Or 4.5, 4.5.1 & 4.6. They all basically follow the same principles.
It all starts with the project.json
file. For reality sake, I am going to add to rather then replace the netcoreapp1.0
target.
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"publishOptions": {
"includeFiles": [
"readme.txt"
]
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
},
"imports": "dnxcore50"
},
"net452": {
}
}
}
dotnet restore
dotnet build
dotnet publish -o "C:\dev\publishingapps\Pack\mynewappNet452" -c Release -f net452
Your Pack folder should now have two packaged application folders like the following:
Pack
|-- mynewapp
| |-- mynewapp.deps.json
| |-- mynewapp.dll
| |-- mynewapp.pdb
| |-- mynewapp.runtimeconfig.json
| +-- readme.md
+-- mynewappNet452
|-- mynewapp.exe
|-- mynewapp.pdb
+-- readme.md
We now have a .Net 4.5.2 exe
that we can run anywhere where .Net 4.5.2 has been installed.
One thing missing is an App.Config
, which some of your existing applications likely use for useful things like configuration. You can simply add an include with a trasform to map a file called App.Config
, with a transformation to the more expected name of %APPNAME%.exe.config
.
Add our App.Config
file.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<!-- Settings go here, you know how to use them already? -->
</appSettings>
</configuration>
And modify the net452
section we added earlier to include the file as a build artifact (that way it is available when using dotnet run
as well)
"net452": {
"buildOptions": {
"copyToOutput": {
"mappings": {
"mynewapp.exe.config": "App.Config"
}
}
}
}
dotnet restore
dotnet build
dotnet publish
Remember, if you use build, pack, or publish without using -f <framework>
you will get all target frameworks included. (And if you use -f
and -o
together with publish
, it will dump the targets’ output on top of each other in the same folder. Probably don’t do that.)
Lets take one last look at the filetree in the mynewapp
project folder:
mynewapp
|-- Program.cs
|-- project.json
|-- project.lock.json
+-- bin
+-- Debug
|-- net452
| |-- mynewapp.exe
| |-- mynewapp.pdb
| +-- win7-x64
| |-- mynewapp.exe
| |-- mynewapp.exe.config
| |-- mynewapp.pdb
| +-- publish
| |--mynewapp.exe
| |--mynewapp.exe.config
| |--mynewapp.pdb
| +--readme.md
+-- netcoreapp1.0
|-- mynewapp.deps.json
|-- mynewapp.dll
|-- mynewapp.pdb
|-- mynewapp.runtimeconfig.dev.json
|-- mynewapp.runtimeconfig.json
+-- publish
|-- mynewapp.deps.json
|-- mynewapp.dll
|-- mynewapp.pdb
|-- mynewapp.runtimeconfig.json
+-- readme.md
In our win7-x64
folder, we have the built output targeting .Net 4.5.2 including our app.config file, and inside that folder is a publish folder, which is our publish output, including both the earlier readme.md
and the transformed app.config
file ready to zip up and distribute as required.
Onward to the finish!
We are almost wrapped up, only one last piece to go, Self-contained Applications. Stay tuned.