如何在 osx 上分发 .net core 2.0 控制台应用程序

How to distribute a .net core 2.0 console application on osx

我正在使用 Visual Studio for Mac,我的应用程序已编写,它可以满足我的要求。用户的目标平台是OSX。它依赖于 2 个具有自己依赖项的 Nuget 包,具体来说:

我 运行 向 build 应用程序发出以下命令:

dotnet build -c Release -r osx.10.11-x64

输出告诉我它成功了,并告诉我它把文件放在哪里。

该文件夹中包含以下文件,我认为该文件夹是我分发给我的用户的,但这会导致错误,因此出现这个问题:

MyApp <---- executable
MyApp.deps.json
MyApp.dll
MyApp.pdb
MyApp.runtimeconfig.dev.json
MyApp.runtimeconfig.json
libhostfxr.dylib
libhostpolicy.dylib

所以我的用户收到了这个并且他们安装了 dotnet 运行time。当他们转到 运行 可执行文件(此处 MyApp 又名 ./MyApp)时,他们收到以下错误:

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'

现在,AsyncIONetMQ 的依赖项,所以这就是它的来源。但是,我可以从我的文件系统上的任何地方 ./MyApp 并且它可以工作。因此,我认为作为开发系统安装在我的系统上的 Nuget 包仍然可以访问,而在新用户的系统上则不能访问。我还没有真正找到任何与 Mac 分发有关的文档。我现在唯一能想到的就是分发项目文件并指示用户 运行:

dotnet run -p MyApp.csproj

如果我理解正确的话,它将安装 nuget 包。

我也可以让用户使用:

dotnet MyApp.dll

我在谷歌搜索中看到过这种形式。不过,这让他们质疑为什么会生成可执行文件。乞丐不能挑三拣四,如果有办法dotnet <dll>我很高兴,我只需要得到运行。

一定是我遗漏了什么,否则 netcore2.0 应用程序的这个细节、分布被忽略了?

在进一步挖掘时,这似乎也是一个有用的命令:

dotnet publish -c Release --framework netcoreapp2.0 --runtime osx.10.11-x64

并且添加了所有类型的 DLL 以及所有依赖 DLL。像 publish 这样的词让我觉得这是需要走的路。

这两个链接是我主要获取信息的地方:

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

您对 buildpublish 之间的区别有正确的直觉。

dotnet build 将为本地开发构建应用程序。一方面是构建将假定所有依赖项都可通过本地 nuget 缓存获得。

dotnet publish 将构建用于部署到其他机器的应用程序。这明确地处理了依赖关系。

有两种发布模式:独立部署和依赖框架的部署。

依赖于框架的部署 依靠系统上已经存在的框架来工作。如果您以这种模式发布您的应用程序,您将只包含您的应用程序及其依赖项。

要在 FDD 中发布,请使用:

dotnet publish -c Release --framework netcoreapp2.0

自包含部署,相比之下,将包括整个 .NET Core 运行时间 您的应用程序和它的依赖项。

要发布 SCD,请使用:

dotnet publish -c Release --framework netcoreapp2.0 --runtime osx-x64

(顺便说一句,请使用更通用的 osx-x64 而不是非常具体的 osx.10.11-x64

你看出这两种发布模式的区别了吗?它只是 运行 时间 ID 的 presence/absence。在您的示例中,当您使用 --runtime 标志时,您要求将您的应用程序发布为 SCD,最终也包括所有 .NET Core 运行 时间。把它放在外面,你应该得到你期望的。

当您将应用程序发布为 FDD 时,您应该会在源代码中看到一个名为 bin/Release/netcoreapp2.0/publish 的目录。使用 that 目录(和 not bin/Release/netcoreapp2.0/)作为您的发布存档。您的用户应该 运行 dotnet ./path/to/publish/MyApp.dll.

查看 https://docs.microsoft.com/en-us/dotnet/core/deploying/ 了解更多信息。

它仍然可以追溯到他最初的观察,这就是我所看到的,即可执行文件 'MyApp' 并不是真正独立的二进制文件。如果将该二进制文件移动到其他目录,它会抱怨找不到 MyApp.dll.

具体来说,我使用的命令是:

dotnet new console
dotnet publish -c Release --runtime osx.10.12-x64 --self-contained true

我也有同样的问题,我的 'MyApp' 真的不是一个独立的应用程序。事实上,我发现 'MyApp' 在它所在的目录中至少需要以下文件:

MyStatic     ----> my 'exe'                   
MyStatic.dll                    
libhostpolicy.dylib
MyStatic.deps.json              
MyStatic.runtimeconfig.dev.json

任何独立的二进制文件都不应该要求所有这些垃圾 运行 独立。

跟进

如果你想把你的控制台应用程序打包成一个漂亮整洁的包,你只需 'click' 它就会打开一个终端来启动你的应用程序...这是一个示例应用程序(带有树形图标) :

你首先想要一个像这样的 folder/file 结构(开始 mkdir!):

然后在info.plist中粘贴

<?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>

.icns site off the internet 那里得到你的 'trees.icns'。

然后将 dotnet publish -c Release --framework netcoreapp3.1 --runtime osx-x64 命令中的所有内容复制到 osx-x64 文件夹中(这里会有大量的 .dll 文件。我有 ~197 个)

最后在launcher添加以下脚本:

#!/bin/sh

# Set the working directory
DIR=$(cd "$(dirname "[=11=]")"; pwd)

# Run the application
echo "running from $DIR/osx-x64"

open -a Terminal $DIR/osx-x64/dotnetconsole

然后瞧瞧...进入您的取景器并单击“MyApp”应用程序

参考:packaging jar tutorial