Self-contained .NET Core Applications
Just in case you missed it, .NET is all open source now and .NET Core is a free, open source, cross-platform framework that you can download and start with in <10 minutes. You can get it on Mac, Windows, and a half-dozen Unixes at http://dot.net. Take that along with the free, cross-platform Visual Studio Code and you'll be writing C# and F# all over the place.
Ok, that said, there's two ways to deploy a .NET Core application. There's FDD and SCD. Since TLAs (three letter acronyms) are stupid, that's Framework-dependent and Self-contained. When .NET Core is installed it ends up in C:\program files\dotnet on Windows, for example. In the "Shared" folder there's a bunch of .NET stuff that is, well, shared. There may be multiple folders, as you can see in my folder below. You can have many and multiple installs of .NET Core.
When you're installing your app and its dependencies BUT NOT .NET Core itself, you're dependent on .NET Core already being on the target machine. That's fine for Web Apps or systems with lots of apps, but what if I want to write an app and give it to you as zip or on a USB key and and I just want it to work. I'll include .NET Core as well so the whole thing is a Self Contained Deployment.
It will make my "Hello World" application larger than if I was using an existing system-wide install, but I know it'll Just Work because it'll be totally self-contained.
If I deploy my app along with .NET Core it's important to remember that I'll be responsible for servicing .NET Core and keeping it up to date. I also need to decide on my target platforms ahead of time. If I want it to run on Windows, Mac, and Linux AND just work, I'll need to include those target platforms and build deployment packages for them. This all makes mostly intuitive sense but it's good to know.
I'll take my little app (I'm just using a "dotnet new" app) and I'll modify project.json in a text editor.
My app is a .NETCore.App, but it's not going to use the .NET Core platform that's installed. It'll use a local version so I'll remove "type="platform"" from this dependency.
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1"
}
}
}
}
Next I'll make a runtimes section to specify which ones I want to target. There's a list of ALL the Runtime IDs here.
"runtimes": {
"win10-x64": {},
"osx.10.10-x64": {},
"ubuntu.14.04-x64": {}
}
After running "dotnet restore" you'll want to build for each of these like this:
dotnet build -r win10-x64
dotnet build -r osx.10.10-x64
dotnet build -r ubuntu.14.04-x64
And then publish release versions after you've tested, etc.
dotnet publish -c release -r win10-x64
dotnet publish -c release -r osx.10.10-x64
dotnet publish -c release -r ubuntu.14.04-x64
Once this is done, I've got my app self-contained in n folders, ready to deploy to whatever systems I want.
You can see in the Win10 folder there's my "MYAPPLICATION.exe" (mine is called scd.exe) that can be run, rather than running things like developers do with "dotnet run."
There's lots of good documentation about how you can tune and define exactly what gets deployed with your self contained application over at the .NET Core Docs. You can do considerable trimming to .NET Core, and there's talk of that becoming more and more automated in the future, possibly down to the method level.
Sponsor: Big thanks to Redgate for sponsoring the feed this week. Discover the world’s most trusted SQL Server comparison tool. Enjoy a free trial of SQL Compare, the industry standard for comparing and deploying SQL Server schemas.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Now I got an documentation about the framework IDs too thx alot:)
Btw: Your link to the runtime IDs is broken, there you have an extra ' character at the end :).
However, I wouldn't mind a stripped down version of Winforms, windowing with basic controls could take you a long way, IMO.
I spent a couple of nights recently playing around with the binary installations trying to get a deeper understanding of how it all hangs together and I'll be honest I'm still a bit lost.
Previously with dnvm I could run dnvm list this would give me all the runtimes installed and I could easily switch with dnvm use. But now it isn't clear (to me at least) how you switch between installations or indeed what the dotnet binary actually is. For example, when I run the following:
which dotnet
I get the following path in my terminal:
/usr/local/share/dotnet/dotnet
So this is the current version of dotnet installed on my Mac which if I run dotnet --version gives me 1.0.0-preview2-003131. I'd recently upgraded from 1.0.0-preview1-002702 so where is that? I can see two installations in the following directories:
/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.0
/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.1
And each of these directories contains the following binaries which upon inspection look exactly the same as the binary returned by which dotnet:
/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.0/dotnet
/usr/local/share/dotnet/shared/Microsoft.NETCore.App/1.0.1/dotnet
To further compound my confusion when I execute either of the above binaries I get:
Microsoft .NET Core Shared Framework Host
Version : 1.0.1
Build : cee57bf6c981237d80aa1631cfe83cb9ba329f12
I get this when I just execute dotnet directly without any switches and when I append the --version suffix I get a blank line in my console. I (perhaps crudely) expected it to act the same as when I run the typical dotnet command and have no idea why the behaviour is different. I thought it might be something to do with a macOS installation but I fired up a couple of Linux VMs and had the same result.
The self contained model is very cool but after working for the past year to ship an app using it given the caveats above I am not sure it is really better for my users.
I can't believe I missed that - that's a lot clearer! Thanks :-)
Re: "If I deploy my app along with .NET Core it's important to remember that I'll be responsible for servicing .NET Core and keeping it up to date"
What if I like the packaging model, but just want to use the same "curated" dependencies/patches that MS has spent time validating for FDD? Couldn't there be a simple tool for updating tested combinations of framework dependencies/patches? "Simple" not meant passive-aggressively...perhaps not so simple?
I was wondering whether there is a good official document explaining each section of the project.json file. It is clear to me now what the type="platform" is used for but what about other keys?
There are a lot of blog posts that are trying to explain these configuration keys but they either are out dated or didn't explain why.
Thanks.
I am very excited about .Net 5 ^H^H Core.
Will self-contained replace ClickOnce apps? If not, how would we use this in conjunction with ClickOnce? Will we use Certs?
How would we "servic[e] .NET Core and [keep] it up to date"? What about dependencies like SQL or local DB?
Thanks
Ric
Also I don't quite understand why did you not implement the scenario we have currently in full .Net - an exe bootstapper with app code. It could does the same thing as 'dotnet run', but wouldn't depend on external cli tools.
Marie Wada
192.168.01 IP Address Definition
I know with Mono (and other languages) if you can get a package for your distro and/or get Mono running on that distro from source you can create a static bundle right now for that target. Bit worried about this being too centralised and lagging behind current Linux changes.
In short if you can run it/build it it should also allow linking of .NET Core. Cross compiling to other platforms is an extra use case IF i want to deploy to other platforms - I would say a lot of places won't need to.
I can relate. Same here, I did Delphi/Pascal. Its like MS is selling old wine in new bags but its not quite the same.
Self contained apps is super nice but for .NET with its periodically security patches the developer gets responsible for security patches instead of the system administrator and the windows security patches! Yes thats whats a developer needs :-(
Applications compiled with for example c and pascal do not have all the security patches administration and responsibility which comes with .NET. I understand completely why MS does not want this too.
For this reason I can understand why a system administrator can refuse self contained Core apps.
For cross platform mobile and windows apps I switched back to Delphi Firemonkey (there is also a C++ builder Firemonkey) so I can compile directly without .core/mono (xamarin). Not only for security reasons btw.
When I try the above, it doesn't seem to generate any "EXE"s:
10/01/2016 08:52 AM <DIR> .
10/01/2016 08:52 AM <DIR> ..
10/01/2016 08:52 AM 441 scd.deps.json
10/01/2016 08:52 AM 4,096 scd.dll
10/01/2016 08:52 AM 408 scd.pdb 10/01/2016 08:52 AM 125 scd.runtimeconfig.json
4 File(s) 5,070 bytes
2 Dir(s) 2,299,387,904 bytes free
Tried on Mac and Windows. Would appreciate a pointer in the right direction ?
Comments are closed.