【问题标题】:How to publish a self-contained C# executable that references another executable?如何发布引用另一个可执行文件的自包含 C# 可执行文件?
【发布时间】:2021-08-16 19:00:35
【问题描述】:

我有两个 C# .NET 5 项目,我们称它们为 A 和 B。它们都是可执行文件(不是 DLL)。项目 A 引用项目 B。我想将项目 A 发布为一个独立的可执行文件(尽管不是单个文件,如果这很重要)。我正在使用这个命令来启动发布过程:

dotnet publish A.csproj -c Release --self-contained -r win-x64 /p:PublishTrimmed=true /p:PublishReadyToRun=true

但是,这会在尝试构建项目 B 时产生以下错误(这是必需的,因为项目 A 引用了它):

error NETSDK1031: It is not supported to build or publish a self-contained application without specifying a RuntimeIdentifier. You must either specify a RuntimeIdentifier or set SelfContained to false.

但正如您所见,我 am(我认为?)使用 -r win-x64 指定运行时标识符。我猜我在命令行上指定的运行时标识符在构建项目 B 时没有通过。如何在不禁用 SelfContained 的情况下解决此问题

我的 dotnet 版本是:

dotnet --version
5.0.400

编辑:我不想将<RuntimeIdentifier>win-x64</RuntimeIdentifier> 放在我的项目文件中,因为我需要为多个不同的运行时进行构建,并且我希望能够通过命令行进行控制。

【问题讨论】:

  • 内部 .NET .exe 具有与 DLL 相同的格式,带有一些本机引导代码和入口点。他们提升和改进了 Java 的一个概念。 |编译它不需要 DLL - 甚至不需要框架 - 是 .NET Native 所做的,我认为:stackoverflow.com/a/45710/3346583
  • @Christopher 对不起,我不明白你的意思。
  • 我认为如果不以某种方式破解 msbuild,您将无法做到这一点。但我认为这只是架构的问题。为什么不在两个可执行项目之间提取共享库?这是支持的,官方的方式来做到这一点。我似乎找不到任何缺点。图书馆就是图书馆,应用就是应用。依赖另一个应用程序看起来很hacky
  • 我理解你希望你的项目是“自包含的”,在“没有外部依赖”的意义上。但是......你绝对确定你需要--self-contained吗?建议:尝试不使用。看看是否能解决问题;验证您的应用是否正常运行。
  • @Christopher 提取共享库需要几天的工作。长期以来一直支持引用其他 EXE 的 EXE。

标签: c# .net


【解决方案1】:

感谢this Github issue 中的几个 cmets,我能够弄清楚如何编译它:

  1. 从命令行中删除 --self-contained 标志。 (根据the docs,“如果指定了运行时标识符并且项目是可执行项目(不是库项目),则默认为真。”)

  2. /p:ValidateExecutableReferencesMatchSelfContained=false 添加到命令行。这是抑制错误所必需的:“引用的项目'B.csproj'是一个非独立的可执行文件。非独立的可执行文件不能被独立的可执行文件引用。”

  3. 如果您希望能够运行在构建项目 A 时生成的 B.exe 文件,则需要将适当的 B.deps.json 文件添加到构建输出中。我发现做到这一点的最简单方法是制作一个单独的独立构建 B,然后简单地从中复制 B.deps.json 文件。 (如果您像我一样使用 PublishTrimmed 进行构建,那么您可能需要将条目添加到您的 TrimmerRoots.xml 文件中,以防止项目 B 所需的代码从输出中删除。)

做完这两件事后,我的项目现在已经构建并运行成功了。我已经验证即使在没有安装 .NET 运行时的机器上它仍然可以工作,因此构建确实是自包含的。

【讨论】:

  • “尝试运行此可执行文件不起作用”是预期的,因为您使用了 /p:PublishTrimmed=true,它为 A 修剪 MSIL,但可能对 B 有害(修剪 B 所需的内容)。
  • @LexLi 我认为您可能是对的,PublishTrimmed 可能会导致问题(希望向 TrimmerRoot.xml 添加适当的条目可以解决这些问题?),但在我的情况下,事实证明它只是A 的构建输出不包括 B.deps.json 文件。如果我包含该文件,那么它运行良好!
猜你喜欢
  • 2011-10-22
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
相关资源
最近更新 更多