C# 极限压缩 dotnet core 控制台发布文件

每次发布 dotnet core 应用都会觉得发布文件太大,而如果使用极限压缩,用 CoreRT 能让发布的控制台文件到 5KB 左右,不需要带框架就能在其他设备运行

这是微软 MichalStrehovsky 大佬,也就是 CoreRT 项目开发者给的方法

在开始写代码之前,需要定义一些基础的类,因为不包含任何运行环境,所以基础的 object 这些都需要重新定义,这里的代码放在 github 我也在本文最后贴出代码

现在输出控制台的代码不是原先的 Console.WriteLine 而是通过底层方法

unsafe class Program
{[DllImport("api-ms-win-core-processenvironment-l1-1-0")]static extern IntPtr GetStdHandle(int nStdHandle);[DllImport("api-ms-win-core-console-l1-1-0")]static extern IntPtr WriteConsoleW(IntPtr hConsole, void* lpBuffer, int charsToWrite, out int charsWritten, void* reserved);static int Main(){string hello = "Hello world!";fixed (char* c = hello){int charsWritten;WriteConsoleW(GetStdHandle(-11), c, hello.Length, out charsWritten, null);}return 42;}
}

最难的是如何编译这个文件

编译需要先使用 csc 编译为 IL 代码,然后通过 ilcompiler 编译为obj文件,然后通过 link 编译为运行文件

从开始菜单找到 x64 Native Tools Command Prompt for VS 2019 然后进入上面代码所在文件夹,执行下面代码编译

csc /debug:embedded /noconfig /nostdlib /runtimemetadataversion:v4.0.30319 zerosharp.cs /out:zerosharp.ilexe /langversion:latest /unsafe

编译完成可以看到 zerosharp.ilexe 文件,然后通过 ilcompiler 将这个文件编译为 zerosharp.map 和 zerosharp.obj 文件

在自己的 NuGet 缓存文件里面找到 runtime.win-x64.microsoft.dotnet.ilcompiler 库,可以在资源管理器地址输入下面代码找到缓存文件

%appdata%..\..\..\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler

找到里面的最新版本,在文件夹里面的 tools 文件夹可以找到 ilc.exe 文件,如在我电脑的的文件是

c:\Users\lindexi\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\1.0.0-alpha-27606-05\tools\ilc.exe

记下这个路径,接下来将使用这个工具编译

>c:\Users\lindexi\.nuget\packages\runtime.win-x64.microsoft.dotnet.ilcompiler\1.0.0-alpha-27606-05\tools\ilc.exe zerosharp.ilexe -o zerosharp.obj --systemmodule zerosharp --map zerosharp.map -O

然后用 link 连接

link /subsystem:console zerosharp.obj /entry:__managed__Main kernel32.lib /merge:.modules=.pdata /incremental:no

执行上面代码就可以编译 zerosharp.exe 文件,这个文件只有5KB可以将这个程序放在其他设备运行

下面是所有代码

using System;
using System.Runtime.InteropServices;#region A couple very basic things
namespace System
{public class Object { IntPtr m_pEEType; }public struct Void { }public struct Boolean { }public struct Char { }public struct SByte { }public struct Byte { }public struct Int16 { }public struct UInt16 { }public struct Int32 { }public struct UInt32 { }public struct Int64 { }public struct UInt64 { }public struct IntPtr { }public struct UIntPtr { }public struct Single { }public struct Double { }public abstract class ValueType { }public abstract class Enum : ValueType { }public struct Nullable<T> where T : struct { }public sealed class String { public readonly int Length; }public abstract class Array { }public abstract class Delegate { }public abstract class MulticastDelegate : Delegate { }public struct RuntimeTypeHandle { }public struct RuntimeMethodHandle { }public struct RuntimeFieldHandle { }public class Attribute { }namespace Runtime.CompilerServices{public class RuntimeHelpers{public static unsafe int OffsetToStringData => sizeof(IntPtr) + sizeof(int);}}
}
namespace System.Runtime.InteropServices
{public sealed class DllImportAttribute : Attribute{public DllImportAttribute(string dllName) { }}
}
#endregion#region Things needed by ILC
namespace System
{namespace Runtime{internal sealed class RuntimeExportAttribute : Attribute{public RuntimeExportAttribute(string entry) { }}}class Array<T> : Array { }
}namespace Internal.Runtime.CompilerHelpers
{using System.Runtime;class StartupCodeHelpers{[RuntimeExport("RhpReversePInvoke2")]static void RhpReversePInvoke2() { }[RuntimeExport("RhpReversePInvokeReturn2")]static void RhpReversePInvokeReturn2() { }[System.Runtime.RuntimeExport("__fail_fast")]static void FailFast() { while (true) ; }[System.Runtime.RuntimeExport("RhpPInvoke")]static void RphPinvoke() { }[System.Runtime.RuntimeExport("RhpPInvokeReturn")]static void RphPinvokeReturn() { }}
}
#endregionunsafe class Program
{[DllImport("api-ms-win-core-processenvironment-l1-1-0")]static extern IntPtr GetStdHandle(int nStdHandle);[DllImport("api-ms-win-core-console-l1-1-0")]static extern IntPtr WriteConsoleW(IntPtr hConsole, void* lpBuffer, int charsToWrite, out int charsWritten, void* reserved);static int Main(){string hello = "Hello world!";fixed (char* c = hello){int charsWritten;WriteConsoleW(GetStdHandle(-11), c, hello.Length, out charsWritten, null);}return 42;}
}

本文会经常更新,请阅读原文: https://blog.lindexi.com/post/C-%E6%9E%81%E9%99%90%E5%8E%8B%E7%BC%A9-dotnet-core-%E6%8E%A7%E5%88%B6%E5%8F%B0%E5%8F%91%E5%B8%83%E6%96%87%E4%BB%B6.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/300742.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

按id进行查找按名称进行排序_Excel工作表中如何按需要的顺序快速进行排序

在工作中&#xff0c;有时候需要经常对一组内容按一定的顺序来进行排序。如果每次都手动进行排序&#xff0c;会小号很多时间。因此可以将特定顺序添加到自定义序列中。有两种不同的操作方法可以来实现。方法一如图&#xff0c;现在有一列水果名称&#xff0c;之后需要都按照现…

ajax 返回flase,Django request.is_ajax返回false

小编典典我不知道你怎么了 我测试并取得了良好的消息&#xff1a;This is ajax。我的代码&#xff1a;urls.pyurl(r^$, myapp.views.home, namehome),url(r^ajax_test/$, myapp.views.ajax_test, nameajax_test),views.pydef home(request):return render_to_response(home.htm…

20种最先进的机器人,感觉有点吓人!

全世界只有3.14 % 的人关注了青少年数学之旅随着科技的发展&#xff0c;机器人必然逐渐进入我们的生活&#xff0c;甚至在许多领域替代人类。以下是目前全球范围内最先进的一些机器人&#xff1a;Actroid-F这种实验性机器人的目标&#xff0c;是创造最逼真的仿人类机器人&#…

PDF批量删除注释

使用Adobe Acrobat Pro的批量处理完成 1.在“自定义”-“添加新工具集”-“动作向导”-将“创建新动作”加入-“保存”2.然后点新出现的“创建新动作”图标3.将“内容”-“删除所有注释”添加上&#xff0c;然后再添加上“保存和导出”中的保存4.保存设定的动作列表&#xff0c…

linkButton与Button 的click事件与onclientClick事件

linkButton与button 在ie7中两个事件都能被执行。但是在ie6中&#xff0c;linkButton中的onclientClick事件先执行&#xff0c;而click事件不被执行。在ie7中&#xff0c;二者都执行了。button就没有这个问题。实验&#xff1a;通过showModalDialog()弹出一个窗口&#xff0c;窗…

怎么让图片手机上排列_荣耀手机系列档次怎么排列?

目前&#xff0c;我们按照处理器和手机表现进行排列。荣耀magic2因为充电口(塑料问题)&#xff0c;所以&#xff0c;排名第一的位置我给荣耀V20&#xff01;其次&#xff0c;是荣耀magic2&#xff0c;然后是荣耀10&#xff0c;荣耀note10&#xff0c;其次是荣耀v10&#xff0c;…

.NET 6 即将到来的新特性 — 隐式命名空间引用

.NET 6 即将到来的新特性 —— 隐式命名空间引用Intro之前我们在 ASP.NET Core 6 Minimal API 中曾经提到过现在我们还是需要手动加命名空间引用&#xff0c;在以后的版本中可能就不需要手动加命名空间的引用了&#xff0c;确实是的。今天看到一个更新&#xff0c;可以不需要写…

金蝶显示服务器异常,金蝶提示云服务器异常

金蝶提示云服务器异常 内容精选换一换生命周期是指弹性云服务器从创建到删除(或释放)历经的各种状态。当云服务器网络异常、防火墙未放行本地远程桌面端口、云服务器CPU负载过高等场景均可能导致云服务器无法正常登录。当您的云服务器无法远程登录时&#xff0c;我们建议您首先…

Ajax 缓存

今天遇到ajax缓存的问题,指定同样的url和参数值总是有缓存&#xff0c;跳不到后台程序里&#xff01; 我先用了一种龌龊的方法,就是在url后又加了个由数据数产生的参数var randMath.random();var url"A.aspx?t"escape(t)"&r"escape(rand); 不知道大家…

S5PC100基于I2C子系统的lm75驱动流程图

转载于:https://blog.51cto.com/387929/1312237

如何有效利用碎片时间?这里有个办法

全世界只有3.14 % 的人关注了青少年数学之旅用了这么久微信&#xff0c;关注的公众号没有上千个&#xff0c;也有上百个&#xff0c;但其实大部分每天主动打开的公众号只有寥寥几个。今天就为大家推荐一些颜值与才华并存的好评公众号&#xff0c;希望你喜欢。【关注方式 】1 - …

mat opencv 修改roi_设置图片ROI(OpenCV学习笔记之二)

ROI相关简介ROI是什么ROI是region of interest首字母的简写&#xff0c;翻译为感性趣的区域。其实在写本篇之前应该写一篇关于图片是什么的学习笔记&#xff0c;但又感觉里面没多少东西还不能承载一篇学习笔记&#xff0c;所以这里只简单提一下。图片是什么其实大家也应该能猜到…

gRPC四种模式、认证和授权实战演示

前言上一篇对gRPC进行简单介绍&#xff0c;并通过示例体验了一下开发过程。接下来说说实际开发常用功能&#xff0c;如&#xff1a;gRPC的四种模式、gRPC集成JWT做认证和授权等。正文1. gRPC四种模式服务以下案例演示&#xff0c;服务端用微软提供的模板创建&#xff0c;客户端…

ajax mode,DWR的三种Reverse Ajax Mode配置详解

Full Streaming ModeEarly Closing ModePolling Mode在DWR应用中.默认启用的是Full Streaming Mode .它是三种modes中最快的一种.它每60秒检查一次浏览器是否是活跃的.配置很简单:dwr-invokerorg.directwebremoting.servlet.DwrServletactiveReverseAjaxEnabledtrue然后在要使用…

WinXP中鲜为人知的28项隐藏功能

WinXP中鲜为人知的28项隐藏功能 Windows的很多隐藏功能&#xff0c;都没有直接体现在菜单或者系统的开始项中&#xff0c;而是直接以文件的形式存在于Windows安装目录中&#xff0c;今天&#xff0c;笔者就带大家认识一下它们吧。 1、免费的系统教程&#xff08;system32文件…

摄像头预览左右翻转_轻薄翻转触控本里的高性能机型:惠普ENVY x360 13评测

自从今年3月末AMD锐龙4000系列处理器正式登陆移动平台以来&#xff0c;目前已有多款机型上市&#xff0c;并涌现出了不少高热度、高性价比的机型。我们也体验测试了其中数款机型&#xff0c;总体上给用户的印象是是价格香、性能强。而今天牛叔要聊的这款机型&#xff0c;也是搭…

Oracle用户、权限、角色管理

Oracle 数据库用户管理Oracle 权限设置一、权限分类&#xff1a;系统权限&#xff1a;系统规定用户使用数据库的权限。&#xff08;系统权限是对用户而言)。实体权限&#xff1a;某种权限用户对其它用户的表或视图的存取权限。&#xff08;是针对表或视图而言的&#xff09;。二…

聊一聊关于聊天记录的存储

背景 即时通讯(Instant Messaging)&#xff0c;也就是我们常说的 IM&#xff0c;其实在很多业务场景上都会有或多或少的应用&#xff0c;有的会是核心&#xff0c;有的会是辅助。既然是聊天&#xff0c;那么必然就会产生聊天记录&#xff0c;而且聊天记录随着人数的增加和时间的…

考勤机信息同步不到服务器,考勤机实时同步功能上线啦

一、考勤机管理重磅上线&#xff0c;告别手动处理打卡数据考勤机打卡仍然是当前企业主流的考勤方式&#xff0c;而考勤机打卡数据的核算也是HR最头痛的一点。HR每个月都要去电脑打开复杂难用的考勤机配套软件&#xff0c;导出并整理打卡数据&#xff0c;逐个统计员工的迟到、早…

对那些刷抖音外放音乐的人,就这么治他!| 今日最佳

世界只有3.14 % 的人关注了青少年数学之旅&#xff08;视频源B站春风里、&#xff09;我最讨厌抖音方外了&#xff01;↓ ↓ ↓