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

时间:2018-06-05 15:17:41

标签: c# .net-core publish portable-executable

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

datagrid.ItemsSource = itemsource;
DataGridRow row = (DataGridRow)datagrid.ItemContainerGenerator.ContainerFromItem(itemsource[i]);

SqlLocalDbStarter.csproj

 dotnet publish -c Release -r win10-x64

当发布过程完成后,dotnet在<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> 文件夹中创建win10-x64文件夹,然后在打开文件夹后,该文件夹包含bin\Release文件夹和一些dll和exe文件。

对我来说有一些问题:

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

Folder Size Image

.Net Info

3 个答案:

答案 0 :(得分:6)

如上所述here,.NET Core应用程序有两种类型的部署,两者都不允许获取单个.exe文件。因此,它尚未得到支持。正如Karel Zikmund在评论it is planned for .NET Core 3.0中指出的那样。

目前我们至少有两个选项:Warp(感谢Darien Shannon在评论中提到它)和dotnet CoreRT

Warp

这是一个类似于经典.NET Framework的{​​{3}}的工具。这是非常容易使用。我在Windows x64上使用EF Core内容在控制台应用上尝试了它并且效果很好。

ILMerge

现在,您可以尝试使用Dotnet CoreRT项目将应用程序预编译为本机单文件可执行文件。我说“尝试”因为文档dotnet CoreRT

  

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

尽管如此,它至少适用于简单的应用程序。请参阅示例says。 根据其描述,您需要在项目文件夹中运行以下命令:

dotnet new nuget 
  

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

<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" />

然后运行:

dotnet add package Microsoft.DotNet.ILCompiler -v 1.0.0-alpha-* 

然后运行:

dotnet publish -r win-x64 -c release
  

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

下的项目

答案 1 :(得分:2)

来自Microsoft的

This documentation使用您使用的相同dotnet publish -c Release -r win10-x64,并将其记录如下(强调添加):

  

这会为每个目标平台创建应用程序的Release(而不是Debug)版本。 生成的文件放在一个   子目录名为publish ,它位于项目的子目录中   。\ bin \ Release \ netcoreapp1.1子目录。 注意   每个子目录都包含完整的文件集(两者都是你的   启动应用程序所需的应用程序文件和所有.NET Core文件。

     

与应用程序的文件一起,发布过程会发出一个   程序数据库(.pdb)文件,包含有关的调试信息   你的应用。该文件主要用于调试异常。您   可以选择不将其与应用程序的文件打包在一起。您   但是,应该在您要调试的情况下保存它   发布您的应用内容。

因此,要部署的正确文件是publish子目录中的文件。该目录是60多MB,因为它包含自包含部署所需的.NET核心库。

答案 2 :(得分:2)

.NET CORE 3.0之前的版本

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

自我解释:

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

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

Publish folder

.NET CORE 3.0之后

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true

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

Publish folder

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

文件大小和启动费用

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

修改csproj并添加PublishTrimmed = true。

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

  <PropertyGroup>

    <OutputType>Exe</OutputType>

    <TargetFramework>netcoreapp3.0</TargetFramework>

    <PublishTrimmed>true</PublishTrimmed>

  </PropertyGroup>

</Project>

现在运行以下命令:

dotnet publish -r win-x64 -c Release /p:PublishSingleFile=true

参考

  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