我使用来自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>
答案 0 :(得分:1)
非常有趣的问题。我会尽可能地覆盖它。
.net核心3.0的引入带来了Single file publish,如.Net的设计文档所述。因此,如果您拥有.net 3.0应用程序,则可以使用/p:PublishSingleFile=true
将所有内容捆绑在一个可执行文件中。
提防/p:PublishTrimmed=true
选项,因为摇树可能并且很可能会导致反射代码出现问题,因为摇晃并不能覆盖对代码的访问。
对于早期版本的net core,您需要使用wrap或Costura之类的打包程序之一。
根据exe文件,我将在包装文档中提及以下内容:
最终的自包含单个二进制应用程序由两个组成 部分:1)运行程序和2)压缩目标应用程序可执行文件 和依赖项。
由标准发布者创建的dll是多平台的,并且不特定于Windows。因此,可执行文件具有在Windows中创建进程并调用可在任何平台上使用的dll中的实际代码所需的所有代码。只是包装纸而已。
有关可执行文件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;
}
}