使用Visual Studio 2017将.NET Core应用程序编译为EXE文件

84

我在Visual Studio 2017中创建了一个.NET Core应用程序(v1.1)。编译代码后,生成的文件与预期不符,生成的是DLL文件而不是预期的EXE文件。我检查了csproj文件,并确认输出类型设置为exe,但仍未如愿。

为什么Visual Studio 2017还会生成DLL文件呢?

我确定有个快速设置我忘记了...

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

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

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <PlatformTarget>AnyCPU</PlatformTarget>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\Core.EF.SqlServer\Core.EF.SqlServer.csproj" />
  </ItemGroup>

</Project>
5个回答

110

更新2019年:

.NET Core 3.0+项目现在默认会包含一个可执行文件,可执行于构建平台。这只是一个shim可执行文件,您的主要逻辑仍在.dll文件中。

但是,.NET Core 3.0还引入了单文件部署,因此可以进行单文件部署。

dotnet publish -r win-x64 -p:PublishSingleFile=True --self-contained false

将所有依赖项打包成一个 .exe 文件。你可以将 --self-contained 更改为 true,以便还包括 .NET Core 运行时,这样在目标计算机上不必全局安装 .NET Core。

dotnet yourapp.dll

这个 DLL 文件适用于所有被 .NET Core 运行时支持的平台(Windows、Linux 和 macOS)。这被称为“可移植性”或“依赖框架”部署。

如果你想要一个真正的 .exe 文件,考虑使用自包含部署。这将创建一个输出文件,其中包含了 .NET Core 运行时的复制以及一个名为 yourapp.exe 的文件 - 但同时也增加了发布应用程序的大小,并且需要在运行时的新版本发布后进行更新。

此外,生成的应用程序仅适用于其发布的操作系统。

有关部署选项和如何设置它们的详细信息,请参阅 .NET Core 应用程序部署


8
感谢提供有关不同部署策略的信息。这有助于我更好地理解 .net-core。 - ajawad987
@Martin,我一直在寻找dotnetcore中“-p:PublishSingleFile = True”标志,这已经持续了一个月了。谢天谢地,我开始使用3.0版本的dotnetcore,这在OSX Mojave、Linux(CentOS 7.6)和Windows 10上都非常好用。 - tmt

63
在Visual Studio 2017中:
  1. 右键单击您的项目,选择发布(在Visual Studio 2019中,点击菜单 生成发布 <projectName>
  2. 选择“文件夹”并创建一个新配置文件
  3. 在“发布”选项卡中,点击“配置…”
  4. 选择部署模式:自包含,目标运行时:win-x86(或win-x64)
  5. 保存
  6. 发布
在文件夹<Your project>\bin\Debug\netcoreapp2.1\win-x86\中,您将看到EXE文件:

发布设置


2
谢谢!很高兴知道在Visual Studio中有一种方法可以做到这一点。 - ajawad987
在Visual Studio 2019中,此配置文件设置对话框中有一个“文件发布选项”部分。单击它以展开它,然后确保选中“生成单个文件”。 - Code-Apprentice

7

从.NET Core 2.2开始,您可以构建依赖于框架的可执行文件


虽然构建自包含部署可能是一个不错的解决方案,但它也有其缺点(请参见R.Titov和Martin Ullrich在SCD-s上的答案)。

幸运的是,.NET Core 2.2支持构建所谓的依赖于框架的可执行文件,它们实质上是标准dll的包装器二进制文件(在Windows上为.exe)。

这样,您就拥有了标准依赖于框架的部署的所有优点(和缺点)(再次参见Martin的答案),但是您也有了一种方便的启动方式,而无需通过dotnetCLI进行调用。

您可以使用以下语法将应用程序发布为依赖于框架的可执行文件:

dotnet publish -c Release -r <RID> --self-contained false

在这里,RID是运行时标识符,例如win-x64或您希望构建的任何平台(在此处查看目录)。


2
这是如何在任何操作系统中使用命令行进行自包含发布的方法:
dotnet publish C:\src\App\App.csproj -c release -r win-x64 -o output-win-x64

此外,您可能希望通过使用ILLink将简单的Hello World应用程序的输出从典型的约60 MB减少到约30 MB。
另外,您可能希望进一步使用ILCompiler获得一个大小约为5 MB的单个.exe文件。请参见此回复

值得一提的是,ILCompiler 是一个像 CoreRT 一样的 AOT 编译器平台,它有自己的限制(没有 Reflection.Emit 等)。 - Marcell Toth

0
其他答案也不错,但我有时发现以下做法很方便:
  • 不需要自包含,因为目标计算机很可能已安装正确版本的.NET Core。这可以减少需要发布的DLL文件数量。
  • 无需在命令行上指定dotnet

为此,可以使用一个批处理文件包装器,类似于以下这些行:

@ECHO OFF
REM see http://joshua.poehls.me/powershell-batch-file-wrapper/

SET SCRIPTNAME=%~d0%~p0%~n0.dll
SET ARGS=%*

dotnet "%SCRIPTNAME%" %ARGS%
EXIT /B %ERRORLEVEL%

如果你的应用程序最终以yourapp.dll结束,那么将批处理文件命名为yourapp.bat并将其放置在DLL文件旁边。现在,你可以调用yourapp params而不是dotnet yourapp.dll params

请注意,此答案的上下文是内部工具,因此使用该实用程序的所有开发人员将具有相当标准的开发机器设置。如果将其分发给外部客户,他们在其计算机上运行什么就不得而知,因此自包含选项要好得多。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接