I am using Visual Studio for Mac
, my application is written, it does what I want. The user's target platform is OSX. It relies on 2 Nuget Packages with their own dependencies, specifically:
I run the following command to build
the application:
dotnet build -c Release -r osx.10.11-x64
The output tells me it succeeded and shows me where it put the files.
Contained in that folder are the following files, this folder is what I assume I distribute to my user, but that leads to errors hence this question:
MyApp <---- executable
MyApp.deps.json
MyApp.dll
MyApp.pdb
MyApp.runtimeconfig.dev.json
MyApp.runtimeconfig.json
libhostfxr.dylib
libhostpolicy.dylib
So my user receives this and they have the dotnet
runtime installed. When they go to run the executable (Here MyApp
aka ./MyApp
)they receive the following error:
An assembly specified in the application dependencies manifest (MyApp.deps.json) was not found:
package: 'AsyncIO', version: '0.1.26'
path: 'lib/netstandard1.3/AsyncIO.dll'
Now, AsyncIO
is a dependency of NetMQ
so that's where that is coming from. However, I can ./MyApp
from anywhere on my filesystem and it works. So I'm left to think that the Nuget packages being installed on my system as the development system are still accessible where as on the new users's system they are not. I haven't really found any documentation pertaining to distribution from a Mac. The only thing I can think to do right now is to distribute the project files instead and instruct the user to run:
dotnet run -p MyApp.csproj
Which, if I understand correctly, will install the nuget packages.
I can also have the user use:
dotnet MyApp.dll
I have seen this form around in my googling. That begs they question though, of why an executable is generated though. Beggars can't be choosers, if the way to do it dotnet <dll>
I'm happy, I just need to get it to run.
There has to be something I'm missing here or else this detail, distribution, of netcore2.0 apps was just overlooked?
In digging around some more this also seems like a useful command:
dotnet publish -c Release --framework netcoreapp2.0 --runtime osx.10.11-x64
And that adds ALL kinds of DLLs and all of the dependency DLLs as well. Words like publish
make me think this is the way this needs to go.
These 2 links are where I am primarily getting my info:
https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli https://docs.microsoft.com/en-us/dotnet/core/tools/project-json-to-csproj
Right-click on the HelloWorld project (not the HelloWorld solution) and select Publish from the menu. On the Target tab of the Publish page, select Folder, and then select Next. On the Specific Target tab of the Publish page, select Folder, and then select Next. On the Location tab of the Publish page, select Finish.
You have the right intuition about the difference between build
and publish
.
dotnet build
will build the application for local development. One aspect is that the build will assume all dependencies are available via local nuget cache.
dotnet publish
will build the application for deployment to other machines. This deals with dependencies explicitly.
There are two modes of publishing: self-contained deployments and framework-dependent deployments.
Framework-dependent deployments work by relying on a framework already present on the system. If you publish your application in this mode, you will only include your application and its dependencies.
To publish in a FDD, use:
dotnet publish -c Release --framework netcoreapp2.0
Self-containted deployments, in contrast, will include the entire .NET Core runtime and your application and its dependencies.
To publish a SCD, use:
dotnet publish -c Release --framework netcoreapp2.0 --runtime osx-x64
(Btw, please do use the more general osx-x64
rather than the very specific osx.10.11-x64
)
Do you see the difference between the two modes of publishing? It is just the presence/absence of the runtime id. When, in your example, you use --runtime
flag, you are asking your application to be published as a SCD, which ends up including all of .NET Core runtime as well. Just leave it out and you should get what you expect.
When you publish your application as a FDD, you should see a directory called bin/Release/netcoreapp2.0/publish
in your source code. Use that directory (and not bin/Release/netcoreapp2.0/
) as your release archive. Your users should just run dotnet ./path/to/publish/MyApp.dll
.
Take a look at https://docs.microsoft.com/en-us/dotnet/core/deploying/ for more information.
Following up on @omajid's answer,
If you want to pack your console application in a nice and tidy package where you just 'click' it and it opens a terminal to start your app... heres an example app (with a tree icon):
You first want a folder/file structure like this (begin the mkdir!):
Then in info.plist, just paste in
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>launcher</string>
<key>CFBundleIconFile</key>
<string>trees.icns</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>2.2</string>
<key>CFBundleSignature</key>
<string>xmmd</string>
<key>CFBundleVersion</key>
<string>2.2</string>
<key>NSAppleScriptEnabled</key>
<string>NO</string>
</dict>
</plist>
Get your 'trees.icns' from some .icns site off the internet.
then copy everything from dotnet publish -c Release --framework netcoreapp3.1 --runtime osx-x64
command into the osx-x64 folder (theres going to be a TON of .dll files in here.. i had ~197)
Finally in launcher
add the following script:
#!/bin/sh
# Set the working directory
DIR=$(cd "$(dirname "$0")"; pwd)
# Run the application
echo "running from $DIR/osx-x64"
open -a Terminal $DIR/osx-x64/dotnetconsole
Then Voila... go into your finder and click the "MyApp" application
reference: packaging jar tutorial
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With