C#.NET标准1.6在已发布的应用程序中具有过度依赖性
我正在试用Visual Studio 2017和.NET Core,这是我几年来第一次尝试C#/.NET(从Golang回来)。我尝试创建一个小型hello world风格的网络应用程序,它只侦听和回显来自tcp客户端的输入:C#.NET标准1.6在已发布的应用程序中具有过度依赖性,c#,.net,.net-core,C#,.net,.net Core,我正在试用Visual Studio 2017和.NET Core,这是我几年来第一次尝试C#/.NET(从Golang回来)。我尝试创建一个小型hello world风格的网络应用程序,它只侦听和回显来自tcp客户端的输入: using System; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; using System.Text; namespace T
using System;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
namespace TaskSockets
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
TcpListener server = new TcpListener(IPAddress.Any, 5555);
server.Start();
while (true)
{
TcpClient newClient = server.AcceptTcpClientAsync().Result;
Task.Run(async () => {
StreamWriter sWriter = new StreamWriter(newClient.GetStream(), Encoding.ASCII);
StreamReader sReader = new StreamReader(newClient.GetStream(), Encoding.ASCII);
Boolean bClientConnected = true;
String sData = null;
while (bClientConnected)
{
sData = await sReader.ReadLineAsync();
Console.WriteLine("Client: " + sData);
}
});
}
}
}
}
我的项目/生成配置如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netstandard1.6</TargetFramework>
<RuntimeIdentifiers>win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Runtime.CoreCLR" Version="1.1.1" />
<PackageReference Include="Microsoft.NETCore.DotNetHostPolicy" Version="1.1.0" />
</ItemGroup>
</Project>
Exe
netstandard1.6
win7-x64
发布应用程序(dotnetpublish)后,我会得到一个包含所需可执行文件的文件夹。然而,我遇到的问题是,该文件夹包含205个文件(大部分是与.NET相关的DLL文件),大小超过30 MB。这包括dll文件,其中引用了我甚至不使用的.NET库,如System.Xml和Linq
有没有办法减少已发布应用程序的文件数量和大小,以便包括我需要的内容
更新:
尝试使用dotnet工具而不是visual studio从头开始重新创建项目:
dotnet新控制台--语言C#--名称套接字--输出套接字
--框架netcoreapp1.0
这创建了此项目(由于某些原因,尽管存在exe输出类型和控制台应用程序目标,但它仍编译为dll):
Exe
netcoreapp1.0
然后手动修改csproj文件,使其如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<RuntimeIdentifiers>win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Runtime.CoreCLR" Version="1.0.6" />
</ItemGroup>
</Project>
Exe
netcoreapp1.0
win7-x64
现在使用以下内容发布:
dotnet发布--运行时win7-x64--配置发布
并转到:
./bin/Release/netcoreapp1.0/win7-x64
现在突然有一个工作的exe文件和几个大小约为1MB的DLL文件。通过删除名为“publish”的子文件夹,我现在有了一些可以在没有大部分膨胀的情况下工作的东西。不知道为什么会这样,也不知道它是否被认为是预期的行为。不知道发布文件夹的用途,也不知道在未安装.NET的计算机上部署是否需要它。Microsoft在文档方面还有一些工作要做。请查看
在第一种情况下,您的publish
命令为依赖于框架的部署生成输出,该部署依赖于目标计算机上是否存在.NET Core Framework。您的代码(以dll的形式)将由运行时执行
在第二种情况下,当您使用--runtime
选项指定目标运行时,publish
会为自包含部署生成输出,其中包含使用过的.NET Core framework版本。有一种方法可以减少输出的总大小,如上面提到的文章中的部署一个占地面积较小的自包含部署部分所述
至于为什么Exe
没有生成Exe
-文件,请查看
它基本上是说
二进制文件包括中间语言(IL)中的项目代码
扩展名为.dll的文件
指定和不指定Exe
库的IL DLL不包含入口点和
无法执行
使用.NET Framework而不是.NET Core,除非您希望它跨平台工作。否则,只需删除项目中未使用的引用。@Therplexedone I need cross-platform;有没有办法让dotnet工具放弃或以某种方式确定哪些引用实际上不需要?听起来有点吓人,只是开始随机删除DLL,希望以后一切正常。使用ReSharper。这是一个整理代码的神奇工具。它还标识了未使用的引用/名称空间。这难道不仅仅是.net core使用的kestrel的依赖项吗?这段代码不应该依赖kestrel imhoThanks来获得明确的答案。你知道为什么便携式版本需要几乎1 MB大小的DLL,尽管需要安装.Net core,以及为什么自包含版本需要200多个DLL(包括我不使用的DLL)和50 MB大小吗?不客气!可移植的,又名FDD,版本应该只包括你自己的代码和你的应用可能具有的任何非.NET核心依赖项。在你的例子中,没有。在一个一次性文件夹中,运行dotnet新控制台
,dotnet还原
,然后运行dotnet构建
和/或dotnet发布
,在输出文件夹中只会看到一个小的dll
(以及json
和pdb
大小不大的文件)。在您的项目中,尝试删除bin
和obj
文件夹,并重复从dotnet restore
开始的步骤。对于SDD,您将得到许多文件,因为这种部署类型包括.NET Core本身。正如我在文章中提到的,通过在.csproj
文件中显式引用应用程序所需的.NET Core组件,可以最大限度地减少部署的占用空间。我看到您试图通过显式引用Microsoft.NETCore.Runtime.CoreCLR来执行此操作。但是还有一件事需要在.csproj
中完成——将netcoreapp1.0
更改为netstandard1.6
。我真正不明白的是,为什么微软坚持捆绑库DLL,比如“System.Xml”,而它不被项目使用,也不被定义为依赖项。我也不太理解发布后“/bin/Release/netcoreapp1.0/win7-x64/”和“/bin/Release/netcoreapp1.0/win7-x64/publish/”之间的区别(两者都有应用程序,但只有publish捆绑了整个.NET核心).我想这里的想法是希望整个.NET核心框架可以在目标机器上使用。这可能是有原因的。其中一个可能是,当您生成SDD时,.exe
文件不是您的程序,而是平台特定.NET核心主机的重命名版本,可能需要更多的框架
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.0</TargetFramework>
<RuntimeIdentifiers>win7-x64</RuntimeIdentifiers>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NETCore.Runtime.CoreCLR" Version="1.0.6" />
</ItemGroup>
</Project>