将.NET核心应用程序发布为可移植可执行文件

Soh*_*deh 9 c# publish self-contained portable-executable .net-core

我有一个简单的.net核心应用程序,并通过以下命令发布它:

 dotnet publish -c Release -r win10-x64
Run Code Online (Sandbox Code Playgroud)

SqlLocalDbStarter.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Win32.Registry" Version="4.5.0" />
  </ItemGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

当发布过程完成dotnet win10-x64bin\Release文件夹中创建文件夹然后打开后,该文件夹包含publish文件夹和一些dll和exe文件.

对我来说有一些问题:

  • exe我需要PE应用程序中的哪一个文件(内部/外部发布文件夹)?
  • 为什么当我剪切exe文件并将其移动到其他地方时它不会运行(没有消息)?
  • 如果我需要所有dll文件来运行应用程序,那么我有两个选项(内部/外部发布文件夹),内部发布文件夹大小为66 MB但外部发布文件夹为1 MB.
  • 我想有一个exe文件来运行我的程序没有DLL文件.

文件夹大小图像

.Net信息

Alb*_*rtK 13

如上所述这里有两种两种类型的部署for .NET的核心应用和双方不允许得到一个单一的.exe文件.因此,它尚未得到支持.正如Karel Zikmund在评论中指出的那样,它计划用于.NET Core 3.0.

目前我们至少有两种选择:( PublishTrimmed=true感谢Darien Shannon在评论中提到它)和single exe

它是一个类似于ILMerge的经典工具csproj.这是非常容易使用.我在控制台应用程序上尝试使用csprojWindows x64 上的东西,它运行良好.

Dotnet CoreRT

现在,您可以尝试使用Warp项目将应用程序预编译为本机单文件可执行文件.我说"试试"因为文档:

该项目处于早期发展阶段.

然而,它至少适用于简单的应用程序.请在此处查看示例.根据其描述,您需要在项目文件夹中运行以下命令:

<PropertyGroup>
  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
Run Code Online (Sandbox Code Playgroud)

这会将nuget.config文件添加到您的应用程序中.打开文件并在元素下添加以下内容:

dotnet publish -r win-x64 -p:PublishSingleFile=true
Run Code Online (Sandbox Code Playgroud)

然后运行:

dotnet new nuget 
Run Code Online (Sandbox Code Playgroud)

然后运行:

<add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
Run Code Online (Sandbox Code Playgroud)

完成后,您可以在/bin/x64//netcoreapp2.0/publish/下找到项目根文件夹中的本机可执行文件.

  • 只是想提一下[warp](https://github.com/dgiagio/warp)是一个类似于ILMerge的工具,它可以用dotnet核心应用程序创建"自包含的单个二进制应用程序". (2认同)

Gop*_*opi 7

.NET Core 3.0之前

dotnet publish -r win-x64 -c Release --self-contained
Run Code Online (Sandbox Code Playgroud)

自我解释:

  • 从当前目录发布项目。
  • 生成要在Windows 64位计算机上运行的项目。
  • 在发布配置模式下构建
  • 将所有内容发布为“自包含”,以便将运行该应用程序所需的所有内容打包到我们的可执行文件中

因此这是正确的,我们最终得到一个包含我们的exe以及运行它所需的所有文件的文件夹,但是问题是,甚至需要运行一吨HelloWorld控制台应用程序。

发布文件夹

.NET Core 3.0之后

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
Run Code Online (Sandbox Code Playgroud)

所有这些操作都是运行我们的publish命令,但告诉它将其打包在一个文件中。您会注意到,我们不再指定自包含标志。这是因为假设如果您将其打包为单个exe,则将需要所有依赖关系。说得通。

发布文件夹

一个整洁的exe文件!执行此操作后,将依赖项提取到一个临时目录,然后从那里运行所有内容。它实质上是我们先前发布文件夹的zip!我玩过很多游戏,说实话,它确实有效。没什么可说的。它只是工作。

文件大小和启动成本

  • 敏锐的眼睛会注意到上面的屏幕截图。文件大小。超过70MB!对于只在屏幕上打印Hello World的应用程序而言,这真是太疯狂了!在.NET Core 3.0的Preview 6中,使用称为IL Linker或Publish trimmer的功能可以解决此问题,该功能会忽略未使用的DLL。
  • 您可能会发现的另一个问题是,第一次运行自包含的可执行文件时,启动成本会很小。因为从本质上来说,它需要在首次运行时将所有依赖项解压缩到一个临时目录,所以这将花费一些时间来完成。这并不疯狂(大约5秒钟),但是很明显。幸运的是,在随后的运行中,它使用了已经解压缩的temp文件夹,因此可以立即启动。

修改csproj并添加PublishTrimmed = true。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>netcoreapp3.0</TargetFramework>

    <PublishTrimmed>true</PublishTrimmed>

  </PropertyGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

现在运行以下命令:

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true
Run Code Online (Sandbox Code Playgroud)

参考

  1. https://dotnetcoretutorials.com/2019/06/20/publishing-a-single-exe-file-in-net-core-3-0/
  2. https://www.hanselman.com/blog/MakingATinyNETCore30EntirelySelfcontainedSingleExecutable.aspx