如何在 osx 上分发 .net core 2.0 控制台应用程序
How to distribute a .net core 2.0 console application on osx
我正在使用 Visual Studio for Mac
,我的应用程序已编写,它可以满足我的要求。用户的目标平台是OSX。它依赖于 2 个具有自己依赖项的 Nuget 包,具体来说:
- NetMQ
- Microsoft.Extensions.Configuration.CommandLine
我 运行 向 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'
现在,AsyncIO
是 NetMQ
的依赖项,所以这就是它的来源。但是,我可以从我的文件系统上的任何地方 ./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
您对 build
和 publish
之间的区别有正确的直觉。
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”应用程序
我正在使用 Visual Studio for Mac
,我的应用程序已编写,它可以满足我的要求。用户的目标平台是OSX。它依赖于 2 个具有自己依赖项的 Nuget 包,具体来说:
- NetMQ
- Microsoft.Extensions.Configuration.CommandLine
我 运行 向 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'
现在,AsyncIO
是 NetMQ
的依赖项,所以这就是它的来源。但是,我可以从我的文件系统上的任何地方 ./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
您对 build
和 publish
之间的区别有正确的直觉。
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”应用程序