.Net发布生成的exe的内容是什么?

时间:2019-11-26 09:26:11

标签: c# .net .net-core

我使用来自this post的以下命令发布了一个小的C#.Net Core 2.2控制台应用程序,它是可执行文件:

dotnet publish -c Release -r win10-x64

生成的文件既包含经典的ConsoleApp.dll,又包含我期望生成的可执行文件ConsoleApp.exe。

我的问题是为什么仍然生成DLL,因为它的所有代码(我想是)都可以像在.Net Framework应用程序中一样被编译为.exe?

另一方面,我尝试使用ILSpy反编译.exe文件,但是似乎不是托管代码。在这种情况下,我还假设.exe文件只是使用dotnet命令调用DLL。这个假设对吗?

下面是控制台应用程序.csproj文件的内容:

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

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

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

  <ItemGroup>
    <PackageReference Include="System.Management" Version="4.7.0-preview3.19551.4" />
  </ItemGroup>

  <ItemGroup>
    <None Update="input.txt">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>

</Project>

2 个答案:

答案 0 :(得分:1)

非常有趣的问题。我会尽可能地覆盖它。

.net核心3.0的引入带来了Single file publish,如.Net的设计文档所述。因此,如果您拥有.net 3.0应用程序,则可以使用/p:PublishSingleFile=true将所有内容捆绑在一个可执行文件中。

提防/p:PublishTrimmed=true选项,因为摇树可​​能并且很可能会导致反射代码出现问题,因为摇晃并不能覆盖对代码的访问。

对于早期版本的net core,您需要使用wrapCostura之类的打包程序之一。

根据exe文件,我将在包装文档中提及以下内容:

  

最终的自包含单个二进制应用程序由两个组成   部分:1)运行程序和2)压缩目标应用程序可执行文件   和依赖项。

由标准发布者创建的dll是多平台的,并且不特定于Windows。因此,可执行文件具有在Windows中创建进程并调用可在任何平台上使用的dll中的实际代码所需的所有代码。只是包装纸而已。

Wrap application

有关可执行文件Microsoft .net core deploying docs

的更多信息
  

独立部署。与FDD不同,它是独立的部署   (SCD)不依赖目标上共享组件的存在   系统。所有组件,包括.NET Core库和   .NET Core运行时,包含在应用程序中并且是独立的   来自其他.NET Core应用程序。 SCD包含可执行文件(例如   Windows平台上的app.exe用于名为app)的应用程序,这是一个   特定于平台的.NET Core主机的重命名版本,以及.dll   文件(例如app.dll),它是实际的应用程序。

答案 1 :(得分:0)

我不确定您的假设。但是使用以下命令,它将仅生成两个文件,一个文件是.exe,另一个文件是.pdb,位于win10-x64目录内的发布目录中。

void insertAtStart(int val) {
    Node* n = new Node(val);

    // If start and end are null
    if(start == nullptr && end == nullptr) {
        start = end = n;
    }
    // There is at least 1 node in the list
    else {
        n->next = start;
        start->prev = n;
        // There is only one node in the list
        if(start->next == nullptr) {
            end->prev = n;
        }
        start = n;
    }
}

void insertAtEnd(int val) {
    Node* n = new Node(val);

    // If start and end are null
    if(start == nullptr && end == nullptr) {
        start = end = n;
    }
    // There is at least 1 node in the list
    else {
        n->prev = end;
        end->next = n;
        // There is only one node in the list
        if(end->prev == nullptr) {
            start->next = n;
        }
        end = n;
    }
}