Runtime: 单exe自包含控制台应用程序

创建于 2016-11-03  ·  98评论  ·  资料来源: dotnet/runtime

如此处所述,在.net核心中发布一个独立的控制台应用程序

是否可以捆绑所有依赖项,以便我们获得一个可执行文件? 例如,在定位Windows时,一个较大的myapp.exe

我想我正在寻找与ILMerge类似的东西,但要使用.net核心。 是否可以通过dotnet publish上的某些选项标志或其他命令? 如果没有,请考虑作为功能要求。 谢谢。

area-Meta question

最有用的评论

这真是太可怕了,我想知道为什么这是在设计过程中被批准的,想将您的应用程序分发给您的一位客户,然后祝他好运找到打开的东西:
image

这只是丑陋而彻底的一团糟

运行/
我的程序
MyLib.dll

这本来是个更好的主意

甚至Java处理起来也更好:
explorer_2018-04-21_16-42-33

所有98条评论

目前不支持此方案。 请密切注意https://github.com/dotnet/corert存储库上可能导致此问题的工作。

CoreRT是搜索此解决方案的正确位置。

谢谢。 看起来CoreRT正是我想要的。

对于其他可能会迷失方向的人,请阅读此处

我特别希望此功能而无需提前编译。 我不希望corert –我想要与普通的独立应用程序相同的jit,调试和运行时体验–但我也不想为每个实用程序分发四个文件。 对于想使用该实用程序的人来说,这很不方便。 我只希望它打包并从单个exe运行。 这使我为许多实用程序选择了.NET Core而不是.NET Framework。

.NET Framework正在“作弊”,因为操作系统中已经存在大量文件。
如果需要,可以通过安装计算机范围内的共享.NET Core来使用.NET Core实现相同的目的。

重构CoreCLR以将其所有文件合并为一个文件(包括本机+托管文件)是一项艰巨的工作,而且我认为这种情况对于太多客户而言并不那么有趣。

不同之处在于,每台Windows机器都保证具有.NET Framework,但没有.NET Core,因此,除非有特殊的原因值得使部署变得更加复杂,否则我最终会呆在那里。
我猜客户通常不会编写单个exe实用程序。 可能有一天。 :-)

除非有特殊的原因值得使部署更加复杂

有很多理由比.NET Framework更喜欢.NET Core。 性能,模块化,可维护性,隔离性等。而这忽略了跨平台性。

具有单个exe实用程序通常是一个修饰问题。 如果可执行文件是单个文件或其中包含少量文件的单个文件夹,则对于任何涉及的人而言,没有真正的功能差异。

@mellinoe哦,我同意一般的项目,这确实是正确的。 在需要这种外观的小型实用程序中,.NET Framework到目前为止已经做得很好。 我同意,这与能够指定装配公司和版权信息的意义相同。 但是,作为一个装饰性的东西并不能使我不那么喜欢它。 显然,这里不是优先事项,这是可以理解的。

可能相关: https :

它主要不是化妆品。 想象一下,我想分发一个内部嵌入了多个组件的应用程序,例如Idsrv4或RavenDb +我自己的东西。 它们依赖于aspnet核心位。 只要它们依赖于相同版本的aspnet核心,这一切都可以正常工作。 一旦其中一个向前滚动到下一个版本,它可能将不再起作用。 如果OTOH,我可以将每个组件分解为单个.dll,问题就消失了。

要记住的一件事是,不仅ILMerge不起作用,还有更多的技术问题。 运行时本身从根本上分为许多文件,并且还有辅助文件,例如CLR主机,运行时依赖项文本文件等。 过去,单文件可执行文件起作用的唯一原因是因为依赖于.NET Framework(全球系统范围的安装)。 比较这两种情况有点不公平,因为.NET Framework实际上没有“自包含”选项。

只要它们依赖于相同版本的aspnet核心,这一切都可以正常工作。 一旦其中一个向前滚动到下一个版本,它可能将不再起作用。

这不是真的。 您可以针对不同的运行时版本发布多个不同的应用程序,然后将它们捆绑到同一“ uber-app”中。 您只是不能将它们的依赖项混合到单个文件夹中。 即使您使用依赖于框架的发布选项,您仍然可以混合和匹配版本。 我了解到,这比实际拥有单个文件要方便得多,并且可能会阻止将exe嵌入为PE中的资源之类的事情。 我不确定这是否是您要指的是,因为您可能仍需要提取文件来执行它,您仍然可以使用目录来执行。

我不是说运行时版本,我知道那是行不通的。 我的意思是,当每个组件都依赖[email protected]时,在我的方案中会发生什么[email protected] 通常,这很好,但是在这种假设下,LibXYZ的作者不知道/不关心语义版本。 Ilmerge使这个问题消失了。

除了@thefringeninja相关点之外,我建议使用一个可部署的二进制单元来减少操​​作开销。 它减少了部署出现问题的可能性,减轻了认知上欣赏您所交付产品的负担,并减少了脚本编写或所需状态的操作工具配置。

我赞赏dotnet工具是新生的,仅达到2.0,但与golang等替代产品相比,此功能非常缺失。 请考虑将其添加到路线图中?

作为一个lib开发人员,我非常感谢ILMerge回到Core中。 👍

Dotnet.exe是一个文件。 NuGet.exe是单个文件。 我认为化妆品很重要,并且单个文件exe会以一种简单的方式大喊大叫,以至于其中没有100个文件的文件夹! 找到一个用dotnetcore实现此目标的方法将是很棒的

我以为这是有可能的,经过几周的工作,我终于将CLI控制台工具发布到单个.exe了。。。
我以为这是独立应用程序的重点?

@PRIMETSS

我以为这是独立应用程序的重点?

自包含应用程序的要点是它们是自包含的,也就是说,它们不需要在目标计算机上安装.Net Core,因为该应用程序本身包含了运行所需的所有内容。

要部署这样的应用程序,您必须复制整个文件目录。 仅拥有一个文件将使部署更加容易,但仅此而已,即使没有该文件,它仍然是一个自包含的应用程序。

对于大型和类似服务的应用程序,这可能并不重要,但是对于命令行工具和小型应用程序来说,尽可能简单和对COPY部署友好至关重要。

我经常在.NET中编写命令行工具,并将它们作为1个EXE来简化升级/部署/打包方式。 我总是将所有.config和其他所需文件打包在EXE内。

将该单个EXE视为一个微型容器。 基于容器的部署的几乎所有好处都适用于此。

这真是太可怕了,我想知道为什么这是在设计过程中被批准的,想将您的应用程序分发给您的一位客户,然后祝他好运找到打开的东西:
image

这只是丑陋而彻底的一团糟

运行/
我的程序
MyLib.dll

这本来是个更好的主意

甚至Java处理起来也更好:
explorer_2018-04-21_16-42-33

是的,我一直在思考,因为自包含的应用程序需要将运行时文件包含在其中(很明显!)(而且我们没有合并这些文件的方法),所以我还认为只是文件夹分离会更加整洁,是的,我也认为运行时文件应该存储在运行时文件夹中,因此,任何尝试使用用核心编写的命令行工具的人,至少都会发现它运行起来更直观。

@Scellow @PRIMETSS我必须同意

这怎么仍然是个问题? 需求来自屋顶。

是这个单独的文件夹,除了将其压缩到一个bin中外,还有两个文件,exe和bin。 易于分发。

另一个+1重新打开并具有功能。

我期望自包含的部署是自包含的,并在这里找到了自己的出路。 我也希望看到这种情况的发生。

谁能说这只是一个表面问题? (仅框架开发人员...)
没有人想到未安装的工具吗? (.NET解决了dll-hell,而.net核心将其恢复了)

我只希望命令行工具是独立的。

这很糟糕,真的很糟糕!

+1

+1我刚刚尝试在没有.net核心运行时的群集上的Azure Batch中运行自定义活动,并且它无法处理“自包含”版本创建的大量文件。

Total size of resourceFiles cannot be more than 32768 characters

这不是官方的解决方案,但可能会有用。 我是warp的作者,该工具可让您创建自包含的单个二进制应用程序: https :

我认为基本上就是每个人都在这里寻找经线! 它只是具有一个exe文件的功能,无论在后台是什么,仅此而已。 考虑一下NuGet包:这是一个.nuget文件,仅此而已; 它比打包其他文件的文件更复杂。

经编是一个棘手的解决方案,这不是我们想要的

我们想要的是:

dotnet publish --self-contained -c Release -r win10-x64

它产生:

App.exe
runtime/

或更像GO / Rust等

App.exe

其他一切都不想要

Warp产生一个App.exe ... hacky怎么样? 显然,它不是框架的一部分,但是可以实现“一个exe文件”的目标。

这就是我的意思,这应该是默认行为,而不是使用第三方解决方案(我认为)

经纱可以治疗。 感谢您的工作@dgiagio!

+1

我非常希望看到捆绑可执行文件和所有依赖项的某种单文件存档。 不必包括本机的-我认为要求在系统上安装dotnet内核是完全可以的。 与Java的jar文件非常相似。 DAR文件?

就像是:
dotnet发布-自包含
dotnet运行-自包含的MyApp.dar

看来现在有个建议: https :

这是跟踪问题: https :

我阅读了提案,然后看到了:

image

那不是我的想法,这听起来像一个缓慢的过程,基本上只是压缩所有内容。
我将所有代码合并到一个可执行文件/ dll中吗? 还是我错过了提案中的内容?

@RUSshy您是否要本地编译所有托管代码并将所有内容链接在一起以获得一个可执行文件(如CoreRT)? 这不是.Net Core中当前单文件工作的目标。

但是,提出了减少磁盘提取和启动时间的解决方案(例如:直接从包中加载某些文件类型,重新使用提取的文件)。 单文件解决方案的发展阶段描述这里

CC: @jeffschwMSFT

为什么需要提取文件? 我们过去常常使用ILMerge在.NET中解决这个问题。

@菲利普-海顿,如所描述这里,ILMerge和单文件解决方案,实现不同的目标。

ILMerge将来自多个程序集的IL合并为一个,但是在此过程中,丢失了合并程序集的原始标识。 因此,诸如基于原始程序集名称使用反射之类的操作将失败。 如果应用程序可以容忍此更改,则仍可以使用ILMerge。

CoreRT是另一种东西,您的.NET代码的AOT编译,看上去确实很有趣,但是还没有准备好(我希望MS会专注于它,并分配更多的资源。.这正是人们想要的,以及他们为什么转向GO的原因)

无论如何,我没有技术知识来谈论细节,但是用例是:

发布一个独立的可执行文件,仅此而已,没有压缩,没有提取,没有开销,只有可执行文件

@ swaroop-sridhar您是否有一个在Linux上用于dotnet核心的示例? 根据https://github.com/dotnet/ILMerge/blob/master/ILMerge/ILMerge.csproj#L13的说明,这是Windows / mono专用项目。

@thefringeninja ILMerge是Windows工具,我不知道将ILMerge移植到其他平台的任何计划。
单文件解决方案将跨平台实现。 这是在发展过程中。

@karelz @mellinoe
部署部署部署!如果单个或更少,如1-3个文件,那将是更好的部署(包括发布,更新)!

CoreRT是AOT
但是ppl想要AOT吗?
该项目(CoreRT)始终未准备就绪(自2014年起)。 现在是2019年!(大约需要5年
对于pragram语言来说,这是多么宝贵的五年!CoreRT甚至没有下一个版本的计划!让ppl再等5年?

@ swaroop-sridhar不幸的是。 ILMerge / ILRepack非常适合库开发人员避免菱形依赖问题。

计划在.NET Core 3.0中支持它- @richlander可以为您更新状态。
在.NET Core 3.0博客文章中已提到它-例如,在以下位置: https :
另请阅读: https :

.net不需要所有这些技巧来生成小的单个自包含可执行文件..它应该是默认行为,您会被GO吞噬,Rust也来了,专注于CoreRT或ILMerge,.net核心应用程序也已经由于要加载所有文件而需要很长的时间开始,不要像提案中提到的那样使用zip / unzip对此添加更多的窃听,这不是可行的方法

.net不需要所有这些技巧来生成小的单个自包含可执行文件..它应该是默认行为,您会被GO吞噬,Rust也来了,专注于CoreRT或ILMerge,.net核心应用程序也已经由于要加载所有文件而需要很长的时间开始,不要像提案中提到的那样使用zip / unzip对此添加更多的窃听,这不是可行的方法

您喜欢.net不需要活着,因为ppl具有Java。
go或rust或dlang不应该支持Single可执行程序的构建目标,因为它们具有Fuck Zip / Unzip!

@RUSshy

.net不需要所有这些技巧来生成小的独立的可执行文件

同意同时,.NET提供了超越其他语言的某些功能,这些功能很难与静态链接器的要求保持一致(例如,在动态代码生成,反射,数据绑定等方面)。 我们已经尝试过在单文件/静态链接很重要的情况下排除这些功能。 我们从客户反馈中了解到,这样做的结果不再像.NET,部分原因是您可以从生态系统中使用的库数量急剧下降。

因此,正确地进行链接程序而不影响我们都已在.NET中获得依赖和喜爱的功能的保真度是一个难题。 作为解决此问题的一部分,我们正在尝试各种方法。 您称此为骇客,我称此为开放思维并乐于跳脱思维。 但是仅仅盲目地将.NET转换为Go / Rust / C ++并不是正确的答案。

我们已经尝试过在单文件/静态链接很重要的情况下排除这些功能。 我们从客户反馈中了解到,这样做的结果不再像.NET,部分原因是您可以从生态系统中使用的库数量急剧下降。

团队是否考虑过创建一个专门针对本机开发和受限环境的.net单独版本,例如jetbrains与kotlin JVM / kotlin NATIVE合作完成的?

正如您所说,尝试使.net适应每个用例不是最明智的选择,因此特定的风格可能是此问题的正确答案

还有tbh,afaik,因为每个Windows安装都已经有.net框架,所以这个问题在.net核心之前并没有真正存在,因此您只需要分发几个KB exe文件,而让我烦恼的是似乎没有人考虑过这种情况设计.net核心时的问题,这基本上是对.net框架的重写。这就是为什么我说这些选项是简单的技巧,它们是在这里修复设计错误的原因

在阅读https://github.com/dotnet/designs/blob/master/accepted/single-file/staging.md之后,该提案似乎还有更多步骤,而且该提案并未以zip / unzip结尾,因此不是失败的战斗,希望该团队能够提供该文件中提到的更轻巧的东西,很好!

这样的事情就是Windows仍然是玩具OS的原因。

@kjkrum事情怎么样?

@cryru是人们不知道自己在做什么时所说的话。

@Cryru诸如无法构建独立的可执行文件之类的事情,以及对真正需要这样做的遗忘。 现有的几乎所有其他构建系统都将不仅构建静态链接的可执行文件,还将剥离依赖项中未使用的部分。 至少十年以来,剥离依赖项一直是标准功能。 自从编译器发明以来就实现了静态链接。

@Cryru诸如无法构建独立的可执行文件之类的事情,以及对真正需要这样做的遗忘。 现有的几乎所有其他构建系统都将不仅构建静态链接的可执行文件,还将剥离依赖项中未使用的部分。 至少十年以来,剥离依赖项一直是标准功能。 自从编译器发明以来就实现了静态链接。

同意,这实际上与C#程序在操作系统中的位置有关。
C#程序始终无法成为一等公民。只能成为二等。

解决了。
TLDR: dotnet publish -r win10-x64 /p:PublishSingleFile=true

细节:
https://docs.microsoft.com/zh-cn/dotnet/core/whats-new/dotnet-core-3-0#single -file-executables
https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md

解决了。
TLDR: dotnet publish -r win10-x64 /p:PublishSingleFile=true

细节:
https://docs.microsoft.com/zh-cn/dotnet/core/whats-new/dotnet-core-3-0#single -file-executables
https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md

在哪个版本的dotnet-core中添加了此功能? 我正在使用3.0.100-preview5-011568并收到此错误:
error MSB4030: "/p:PublishSingleFile=true" is an invalid value for the "SelfContained" parameter of the "ResolveFrameworkReferences" task. The "SelfContained" parameter is of type "System.Boolean".

LE:实际上,这是可行的,在https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md中似乎只有语法错误,其中指出以dotnet publish -r win10-x64 --self-contained /p:PublishSingleFile=true并且实际上没有添加--self-contained

谢谢@mihaimyh,我将在设计文档中修复错字。

我一直反对将zip / unzip解决方案用于Single exe自包含功能
因为这将导致下一个问题。
如何减少Single exe文件大小!

实际上,从一开始就应该使用IL-Merge相似的方式。

不应进行辩论,这是时间的浪费,没有人要求对整个内容进行压缩/解压缩,但是他们带来了这种设计,浪费了他们的时间和我们的时间

人们要求单个可执行文件和AOT,不要浪费我们的时间Microsoft

我明确希望没有AOT的单文件。 我更喜欢JIT的功能,以便可以使用反射,泛型和运行时生成的代码。

我想MS不想听,好

我一直反对将zip / unzip解决方案用于Single exe自包含功能
因为这将导致下一个问题。
如何减少Single exe文件大小!

不确定我是否理解,好像它的Zipped已经被压缩了。 还是您要减少冗余依赖关系并因此在压缩前减小大小?

不了解消极情绪。 除快速测试外,我还没有使用过它。 但是似乎单个可执行文件非常适合将应用程序部署到客户端或作为CLI工具的情况。 我认为该功能很有用。 除此之外,在Dev或其他环境中,我看不到用例,因此他们所做的事情现在可以很好地用作解决方案。

@RUSshy

我想MS不想听,好

相反,他们要求并收集各种用例,您可以在相关线程中看到这些用例。 您的意见很重要,但是社区中其他人的意见也同样重要,因此您不应嘲笑Microsoft听他们的意见。

根据您的陈述,我认为您可能误会我为Microsoft。 我只是一个像您一样的社区成员,不会以任何身份代表Microsoft。

我一直反对将zip / unzip解决方案用于Single exe自包含功能
因为这将导致下一个问题。
如何减少Single exe文件大小!

不确定我是否理解,好像它的Zipped已经被压缩了。 还是您要减少冗余依赖关系并因此在压缩前减小大小?

如果您使用WebApi或MVC或ConsoleApp,请编写HelloWorld! 我们很清楚我的意思。
打包文件太大。它带来太多代码,但永远不会执行。
如果IL合并方式将减少未使用的代码分支。

是的,我确定我做了一个控制台HelloWorld,是的,它的68K
Capture
不包含在内67K
但是它的C#不是汇编语言。 如果我想要一个小于1K的HelloWorld,为什么要使用c#?
较大的应用程序使用了更多的框架,因此在某种程度上,其自定义代码比框架更多。
我们真的担心100K吗? 如果是这样,请不要使用框架并花时间从头开始编写所有内容??
我在这里想念什么?

我一直反对将zip / unzip解决方案用于Single exe自包含功能
因为这将导致下一个问题。
如何减少Single exe文件大小!
如果您使用WebApi或MVC或ConsoleApp,请编写HelloWorld! 我们很清楚我的意思。
打包文件太大。它带来太多代码,但永远不会执行。
如果IL合并方式将减少未使用的代码分支。

@sgf这里有两个稍微分开的问题:

  • 如何减少应用程序的代码?
  • 如何将应用打包为一个文件?

为了减少代码,还有其他几种技术

  • 合并IL:并非适用于所有应用程序,因为在此过程中它将丢失程序集标识。 这不是当前单exe工作的目标。
  • 修剪未使用的IL: ILLinker旨在修剪未使用的IL。 此功能已集成到dotnet SDK( PublishTrimmed属性)中,并且正在开发ILLinker中的更多优化。
  • 压缩/解压缩:dotnet publish当前不压缩已发布的单个文件,但可以完成。

如何将应用打包为一个文件?
dotnet publish支持发布到单个文件中-发布的文件将与应用程序原本一样大。

关于生成本机代码:

  • 当前,对生成本机代码的支持是通过现成的编译器( PublishReadyToRun属性)。
  • 通过AOT编译进行发布非常棒( CoreRT ),但尚不可用。 对于AOT编译,可执行文件的大小也取决于编译选项:例如:我们是否包括用于执行生成的代码的jit等?

是的,我确定我做了一个控制台HelloWorld,是的,它的68K
Capture
不包含在内67K
但是它的C#不是汇编语言。 如果我想要一个小于1K的HelloWorld,为什么要使用c#?
较大的应用程序使用了更多的框架,因此在某种程度上,其自定义代码比框架更多。
我们真的担心100K吗? 如果是这样,请不要使用框架并花时间从头开始编写所有内容??
我在这里想念什么?

很抱歉,如所示,您的img具有自我约束。那就是68626KB,大约68mb = 68KK,不仅是68K!
我们将不需要<1kb(可以接受自我限制),<3000KB可以,接受。
但是68mb是30X +
你不会总是只写一个HelloWorld程序!

抱歉,深夜K的错误
感谢您的补充说明/信息swaroop-sridhar,那里有一些我不知道的新开关。
刚尝试使用3.preview 6与以下开关

dotnet publish -r RID / p:PublishTrimmed = true / p:PublishSingleFile = true
现在下降到29,000K

当然,并不是所有的应用程序都是Hello World,但是对于C#Core自包含应用程序,它也包含运行时。。。个人而言,我不必担心。 当然,我知道,如果您编写的是微型控制台工具,那么将其设置为3K会很好。 但是为什么首先要使用C#?
伙计们,有趣的讨论!

image
Capture

大声笑30mb,等到1-3mb时打电话给我,运行时充满膨胀,检查GO,人们在波浪中迁移

https://www.jetbrains.com/lp/devecosystem-2019/

甚至Kotlin也开始获得份额,并且使用Kotlin本机,这使C#感到羞耻

Swift即将登陆Windows https://forums.swift.org/t/swift-win32-programming/20686

所以这里有一些建议:

  • 添加选项以删除反射
  • 添加选项以删除JIT内容
  • 更好地优化C#代码,因此您不必依赖JIT

大声笑30mb,等到1-3mb时打电话给我,运行时充满膨胀,检查GO,人们在波浪中迁移

https://www.jetbrains.com/lp/devecosystem-2019/

甚至Kotlin也开始获得份额,并且使用Kotlin本机,这使C#感到羞耻

Swift即将登陆Windows https://forums.swift.org/t/swift-win32-programming/20686

所以这里有一些建议:

  • 添加选项以删除反射
  • 添加选项以删除JIT内容
  • 更好地优化C#代码,因此您不必依赖JIT

我认为这不公平。 .NET并非旨在构建最小的单个文件控制台应用程序。 我们将其用于Asp.Net网站和api。 因此,除了可以包含的大量nuget程序包之外,该框架本身还带来了许多功能。 我无法想象,如果Web应用程序的大小为50或数百兆字节,就没有问题了。 主要关注的是速度,内存使用情况以及长期可维护性。 谁在乎服务器的大小。

如果您唯一的目的是构建小型的mb大小的控制台应用程序,那为什么不使用正确的工具来完成这项工作。 除了抱怨一个具有全功能框架的应用程序打包到一个文件中,甚至对于一个“ hall world”来说,它的大小也要几十兆字节,为什么不使用Rust?

自开始以来,Microsoft在.NET方面一直做得很好,在过去的几年中甚至做得更多,因此谢谢您。

对这种无意识,谎言和缺乏效率感的回应是什么?

您没有意识到.net核心方向有多么错误,只是直到最近他们才开始通过Distribution / IL Merge / AOT来实现它。

现在,他们不能继续使用Web组装货车,因为.net运行时非常庞大,无法部署大小合适的文件

而且您仍然坚持“谁在乎服务器的大小”。这种思维方式是将“本应是现代的” .net核心变成已经过时且不相关的技术堆栈的原因。

微软在.net方面做得不好,他们失败了,因为他们想让老年人享受.net框架的兼容性,这是他们的错误之一

抱歉,我听起来很粗鲁,但有时您需要进行更改

对不起,如果我听起来很粗鲁,但是

你听起来很粗鲁,周期。 那,以及您的解雇和下结论,不会具有说服力。

抱歉,深夜K的错误
感谢您的补充说明/信息swaroop-sridhar,那里有一些我不知道的新开关。
刚尝试使用3.preview 6与以下开关

dotnet publish -r RID / p:PublishTrimmed = true / p:PublishSingleFile = true
现在下降到29,000K

当然,并不是所有的应用程序都是Hello World,但是对于C#Core自包含应用程序,它也包含运行时。。。个人而言,我不必担心。 当然,我知道,如果您编写的是微型控制台工具,那么将其设置为3K会很好。 但是为什么首先要使用C#?
伙计们,有趣的讨论!

image
Capture

作为现代语言,难道不应该有统一世界的野心吗?
您是否希望所有开发人员都为C ++编写C#? 还是推他们去,科特琳,雨燕?
市场份额会进一步侵蚀C#?

.Net因为不执行跨平台而错过了前15年以上的巨大发展机会。
但是现在.net回到正确的方向。

是的,正如我在我之前评论的那样,我不确定为什么要消极。
如果您来自Full Framework,那么.Net Core就是什么了不起。 我认为.Net标准+核心合并愿景是明智的和渐进的。

将.NET与GO或任何其他语言/框架进行比较是没有意义的。
无论如何,Im OUT就是这个话题,因为我认为他们正在为Single .exe改进的解决方案很好地解决了我几年前的“提问”……对我来说足够好,并且适合我的迫切需求。

因此,感谢Guys&Gals!

我想提醒每个线程有关行为准则的人

可以不同意或有不同的意见,但请保持谦虚,并以技术性讨论的方式表达出来。 无需使用强词。
同样,根据您的意见来针对想法,实施方案也是公平的游戏。 但是,攻击后面的人员是不可接受的。 请大家互相尊重,让我们听听不同的意见,避免发表有力的言论和令人反感的评论。

另外,我想请所有人对其他观点和意见持开放态度。 在做出判断之前,通常最好先听到对方的声音-事情为什么会这样一直存在着一个故事。 当人们知道想法和解决方案为何如此时,他们通常会提高工作效率。

谢谢!

我一直反对将zip / unzip解决方案用于Single exe自包含功能
因为这将导致下一个问题。
如何减少Single exe文件大小!
如果您使用WebApi或MVC或ConsoleApp,请编写HelloWorld! 我们很清楚我的意思。
打包文件太大。它带来太多代码,但永远不会执行。
如果IL合并方式将减少未使用的代码分支。

@sgf这里有两个稍微分开的问题:

  • 如何减少应用程序的代码?
  • 如何将应用打包为一个文件?

为了减少代码,还有其他几种技术

  • 合并IL:并非适用于所有应用程序,因为在此过程中它将丢失程序集标识。 这不是当前单exe工作的目标。
  • 修剪未使用的IL: ILLinker旨在修剪未使用的IL。 此功能已集成到dotnet SDK( PublishTrimmed属性)中,并且正在开发ILLinker中的更多优化。
  • 压缩/解压缩:dotnet publish当前不压缩已发布的单个文件,但可以完成。

如何将应用打包为一个文件?
dotnet publish支持发布到单个文件中-发布的文件将与应用程序原本一样大。

关于生成本机代码:

  • 当前,对生成本机代码的支持是通过现成的编译器( PublishReadyToRun属性)。
  • 通过AOT编译进行发布非常棒( CoreRT ),但尚不可用。 对于AOT编译,可执行文件的大小也取决于编译选项:例如:我们是否包括用于执行生成的代码的jit等?

根据需要,将本机DLL动态合并为一个名称,例如:XXX.exe(不受管)。
在编译nativeDLLs(非托管)功能级链接时使用静态分析进行分析。

api-ms-win-core-console-l1-1-0.dll
api-ms-win-core-datetime-l1-1-0.dll
api-ms-win-core-debug-l1-1-0.dll
api-ms-win-core-errorhandling-l1-1-0.dll
api-ms-win-core-file-l1-1-0.dll
api-ms-win-core-file-l1-2-0.dll
api-ms-win-core-file-l2-1-0.dll
api-ms-win-core-handle-l1-1-0.dll
api-ms-win-core-heap-l1-1-0.dll
api-ms-win-core-interlocked-l1-1-0.dll
api-ms-win-core-libraryloader-l1-1-0.dll
api-ms-win-core-localization-l1-2-0.dll
api-ms-win-core-memory-l1-1-0.dll
api-ms-win-core-namedpipe-l1-1-0.dll
api-ms-win-core-processenvironment-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-1.dll
api-ms-win-core-profile-l1-1-0.dll
api-ms-win-core-rtlsupport-l1-1-0.dll
api-ms-win-core-string-l1-1-0.dll
api-ms-win-core-synch-l1-1-0.dll
api-ms-win-core-synch-l1-2-0.dll
api-ms-win-core-sysinfo-l1-1-0.dll
api-ms-win-core-timezone-l1-1-0.dll
api-ms-win-core-util-l1-1-0.dll
api-ms-win-crt-conio-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-locale-l1-1-0.dll
api-ms-win-crt-math-l1-1-0.dll
api-ms-win-crt-multibyte-l1-1-0.dll
api-ms-win-crt-private-l1-1-0.dll
api-ms-win-crt-process-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
aspnetcorev2_inprocess.dll
clrcompression.dll
clretwrc.dll
clrjit.dll
coreclr.dll
dbgshim.dll
dotnet-aspnet-codegenerator-design.dll
hostfxr.dll
hostpolicy.dll
mscordaccore_amd64_amd64_4.6.27317.07.dll
mscordbi.dll
mscorrc.dll
mscorrc.debug.dll
sni.dll
sos.dll
sos_amd64_amd64_4.6.27317.07.dll
ucrtbase.dll
...etc...

如果做好,结果可能是2-3mb。 当我直接用7zip将它们打包时,大约需要4.85mb。现在我们得到XXX.exe

用IL-merge开发类似的功能级链接。
对于托管的DLL,同样的老把戏。
最后,将托管的DLL嵌入为PE.exe节(标记为.net节)。

对于反射,分析反射类型的DLL。 保留元数据和反射类型(包括函数)及其所有依赖于树的类型。

抱歉,我不想再花更多的时间参与有关此问题的讨论。意见无法统一。
起初,我曾期望结果。 但是现在,我可能应该考虑使用其他编程语言来满足我的需求(也许DlangGoKotlinNimRust才是最好的语言)。

感谢所有与我交谈。 对不起,我na了。 出

@sgf我认为您提出了一些要点,并且我知道您已经签署了该主题。 只是想说,我相信您所需要的功能将在未来几年内出现在.NET Core中。 实际上,如果您今天想减小文件大小,则将mono作为目标可能是可行的。

  1. Mono已通过链接支持AOT编译以减小文件大小。 这就是为什么在浏览器.net运行时实现中选择了mono的原因之一。 https://www.mono-project.com/docs/advanced/aot/ ,我认为这就是Blazor项目可以具有链接器的原因。

  2. 微软已经宣布,他们希望将.NET运行时合并为一个“功能强大”的运行时。 他们希望在某些情况下提供单个运行时,而不是在某些方面使用单声道,而在其他方面使用.NET Core。 实际上,这意味着它将需要支持AOT和链接/代码剥离等。因此,我希望在未来几年中,.NET Core运行时获得这些功能,或者将Mono和.NET Core功能整合到新功能中运行。

如果有人知道更好,请通知我。

+ 2¢

我认为问题在于似乎决策是在没有太多信息的情况下做出的。 这些天,我到处都是人们谈论的话题。 绝大多数部署程序的人都将其放在了愿望清单的首位,并且许多正在从C#转移到具有更好AOT /可部署性的其他语言。 我认为这是一个非常确定的事实,如果您在社区中活跃,这一点将变得非常明显。 然而,它似乎丝毫没有影响决策。

问题是,似乎没有人确切知道这在什么程度上很重要。 对我个人而言,这非常重要,因此我当然会非常有偏见,但是我的印象是,总体而言,这是至关重要的,而且似乎MS并没有给予应有的关注,给我们很多人留下了印象他们正在做出统一的决定,这反过来又使我们对整个技术的未来没有信心。

我同意@RUSshy。 CoreRT是一个令人难以置信的项目,肯定会朝着正确的方向发展,但是总的来说,似乎所有努力都集中在服务器/ Web技术上。 在这方面,诸如运行时,jits和大型二进制文件之类的东西可以说明一切。 没有人部署软件想要这些东西。

话虽这么说,我个人仍在使用这项技术,尽管在某些领域我并没有真正让我屏息。

我希望看到社区中更多的人朝着正确的方向前进,即使事实证明这与我个人期望的相反。 但是到目前为止,似乎在做出决策时并未考虑到这一点。 看来服务器/网络是赚钱的地方,而部署程序的人很少(至少在利润方面),但是如果是这种情况,我至少想知道那是他们基于其决定(很有可能),因为从外面看,他们好像在掷硬币。

@ Alan-FGR

但是到目前为止,似乎在做出决策时并未考虑到这一点。

您是否愿意分享此类决策的具体示例,我很想了解更多。

我认为MS非常了解当前dotnet核心运行时的缺点,这就是为什么他们将来会寻求与Mono运行时进行功能奇偶校验的原因。

只需查看.net core 3.0.0预览版6的发行说明:

今天,我们发布了.NET Core 3.0 Preview6。它包括用于编译程序集的更新,以改进启动,通过改进链接程序和EventPipe来优化应用程序的大小。 我们还在ARM64上为Alpine发布了新的Docker映像。

在我看来,他们非常了解应用程序大小对于某些情况非常重要-尤其是现在混合使用Blazor。

@ Alan-FGR同意,考虑到IIS大约有8%的市场份额并在下降,Web焦点相当奇怪。 ASP.NET无关紧要,对C#或其标准库的任何改进都不会改变它。 控制台应用程序,Windows服务,移动应用程序和PC游戏支持C#。 它应归功于Unity和Xamarin。 真可惜,因为C#是一种非常令人愉悦的开发语言。这是来自长期Java开发人员的高度赞誉,他仍然认为Microsoft在Windows XP中留下了自己的高标。

根据需要,将本机DLL动态合并为一个名称,例如:XXX.exe(不受管)。
在编译nativeDLLs(非托管)功能级链接时使用静态分析进行分析。

我不确定您所说的动态合并是什么意思,但是有一个计划可以将本机组件与主机静态链接在一起。 请参阅本节

用IL-merge开发类似的功能级链接。
对于反射,分析反射类型的DLL。 保留元数据和反射类型(包括函数)及其所有依赖于树的类型。

我们已经讨论了将程序集合并为一个,并具有辅助数据表来支持动态功能的选项。 它确实节省了大量尺寸。 但是实现它的成本非常高-因为新的元数据支持以及调试器/分析器等进行处理所需的更改。

还有其他一些方法可以减少二进制文件的大小-例如,当我们能够直接执行单个文件(而不必提取到文件)时,我们可以删除每个DLL上的签名/证书,以利于对整个应用程序进行签名。 有时可以节省几MB。

但是到目前为止,似乎在做出决策时并未考虑到这一点。

您是否愿意分享此类决策的具体示例,我很想了解更多。

我认为MS非常了解当前dotnet核心运行时的缺点,这就是为什么他们将来会寻求与Mono运行时进行功能奇偶校验的原因。

@dazinator我认为MS某种程度上认为Mono是任何问题的一个不错的解决方案这一事实表明,他们真的不了解他们的产品。 我曾经使用过Mono,虽然它是一项重要的技术,并且极大地推动了.NET的普及,但它肯定缺乏质量... Xamarin在推广其技术方面做了一些出色的营销工作,但它基于过分的承诺和不足似乎是谁在MS做出这些决定的人都只是看过他们的一些促销材料而从未真正使用过这项技术。 另一方面,CoreRT是一项迄今为止对我来说超额交付的技术。 在我看来,它处于另一种质量水平,但是它却被MS忽略了,转而支持某些我怀疑与鸭子磁带结合在一起的技术。

商定,考虑到IIS大约有8%的市场份额并在下降,Web的关注点很奇怪。 ASP.NET无关紧要,对C#或其标准库的任何改进都不会改变它。 控制台应用程序,Windows服务,移动应用程序和PC游戏支持C#。

@kjkrum就是重点。 但是,对于他们来说,也许在网络上8%的市场份额仍然比Windows和移动应用程序重要得多。 优秀的网络技术至少可以帮助Windows服务器销售,因此他们的兴趣很明显,但是,将重点放在这上面是一项非常肤浅的策略,我拒绝相信这是决定其动机的因素。 MS凭借dotnet基础和许多有前途的项目正在朝着正确的方向发展,但似乎他们正在让拥有主导技术的机会过去。

我知道这是轶事,所以可能毫无意义,但由于完全可以解决的限制,我认识的所有使用C#进行项目的人(主要是游戏开发人员)都搬到了其他地方。 他们转向了Rust,D,Go和C ++。 我本人定期使用C ++,并且正在学习Rust,但是我仍然在一些个人项目中使用C#,因为这样做要好得多,即使在后方部署高质量的产品也很麻烦。

它应归功于Unity和Xamarin。

是的,由于许多技术问题,这是一种祝福和诅咒。 例如,Unity的声誉非常差,但幸运的是,这似乎并未影响.NET / C#。
然而,XNA尽管远非完美,但在用户和开发人员中仍享有极高的声誉。

今天很高兴看到.NET Core 3.0的出现。 谢谢大家! 👍

我不确定这是人们想要的,如果最终得到的是141mb exe的简单计算器,那么该功能将失败(并且我认为实际成本为141mb * 2,因为它将在正确的位置提取内容)

image

是的,这绝对是我想要的。 它仍然比常规的独立部署要小。

欢迎进行更积极的装配修剪和摇树,但这是一个非常有用的开始。 增量改进是实现价值的最明智的方法。

哦,这就是你想要的吗? 我不好,我不知道know肿的应用程序很受欢迎

计算器不需要JIT,甚至不需要Reflection,但是由于这就是您想要的,我想自一开始我就错了,我应该停止编程

@RUSshy它没有比其他任何独立部署更肿了,对吗?

删除JIT和反射与是否将所有内容打包到单个exe文件无关。 也就是说,您可以在不使用Single-exe的情况下删除JIT和反射,也可以在不删除JIT和反射的情况下使用Single-exe。 它们是独立的工作。

我不确定这是人们想要的,如果最终得到的是141mb exe的简单计算器,那么该功能将失败(并且我认为实际成本为141mb * 2,因为它将在正确的位置提取内容)

将其解压缩到C:Users [YourUserName] AppDataLocalTemp.net

有什么方法可以覆盖将单个exe解压缩的位置吗?
当它尝试解压缩到/ var / ....时出现了问题,用户没有写权限。

@eiva这是哪个操作系统? 是AWS lambda吗?
https://github.com/dotnet/core-setup/issues/7940跟踪修复此问题。

同时,您可以设置DOTNET_BUNDLE_EXTRACT_BASE_DIR环境变量来控制将捆绑文件提取到的位置。

@ swaroop-sridhar感谢您的回复!
这是centos.7从“受限”服务帐户启动应用程序。

@ jnm2我感谢您喜欢C#,我也这样做。 但老实说,计算器为128兆字节是疯狂的。

@TechnikEmpire我觉得有必要指出,“我爱C#”是我在上面所说的内容的密集还原:D

直到我有能力对自己的代码和库,引用的第三方库以及.NET本身进行摇晃,我个人才会感到完全满意。 但这并没有使单exe功能对我今天没有任何价值。 这是一个维度的一步。 摇树是一个独立的方面,我希望它能引起很多关注。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

nalywa picture nalywa  ·  3评论

noahfalk picture noahfalk  ·  3评论

EgorBo picture EgorBo  ·  3评论

matty-hall picture matty-hall  ·  3评论

omariom picture omariom  ·  3评论