每次发布 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 ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

C# 极限压缩 dotnet core 控制台发布文件相关推荐

  1. 手把手教你用Jenkins做dotnet core自动化发布

    Jenkins部分 首先,我们要有个Jenkins咯,下载链接:https://jenkins.io/download/ 我们安装官网教程安装好jenkins,安装教程略-. 嗯?不是说好手把手么?你 ...

  2. Docker制作dotnet core控制台程序镜像

    (1)首先我们到某个目录下,然后在此目录下打开visual studio code. 2.编辑docker file文件如下: 3.使用dotnet new console创建控制台程序; 4.使用d ...

  3. .net core独立发布文件过多的问题

    参考:1.https://blog.csdn.net/sD7O95O/article/details/78951170 2.https://cloud.tencent.com/developer/ar ...

  4. dotnet core 通过 frp 发布自己的网站

    很多时候写出来的网站只能自己内网访问,本文告诉大家如何通过 Frp 将自己的 asp dotnet core 网站发布到外网,让小伙伴访问自己的网站 通过 frp 的方式,可以解决自己的服务器性能太差 ...

  5. arm linux源更新,[Linux] - Manjaro ARM 系统配置(更新镜像源,安装 Docker 和 Dotnet Core)...

    硬件:Raspberry Pi 4B 系统:Manjaro-ARM-xfce-rpi4-19.08 网址:https://manjaro.org/ Issue 系统启动后,中文字符显示为小方格乱码 解 ...

  6. 边缘化搭建 DotNet Core 2.1 自动化发布和部署(下)

    写在前面 本篇文章是上一篇边缘化搭建 DotNet Core 2.1 自动化发布和部署(上)的后续操作,本文主要讲解如何开启Docker Remote API,开启Remote API后的权限安全问题 ...

  7. .NET Core 跨平台发布(dotnet publish)

    .NET Core 跨平台发布(dotnet publish) ,无需安装.NET Core SDK,就可以运行. 前面讲解了.NET Core 的VSCode 开发.现在来讲讲发布(dotnet p ...

  8. DotNet Core 2.2 MVC Razor 页面编译为 View.dll 文件的解决方法

    DotNet Core 2.2 MVC Razor 页面编译为 View.dll 文件的解决方法 参考文章: (1)DotNet Core 2.2 MVC Razor 页面编译为 View.dll 文 ...

  9. .NET Core控制台程序发布后没有exe解决方案

    .NET Core控制台程序发布后没有exe解决方案 参考文章: (1).NET Core控制台程序发布后没有exe解决方案 (2)https://www.cnblogs.com/ya-jun/p/1 ...

最新文章

  1. DynamicMethodHelper R2 2012-08-14 DynamicMethod ILGenerator.Emit
  2. kali64位下载怎么是AMD_AMD平台虚拟机安装macOS Sierra方法
  3. LIST-PROCESSING命令的使用
  4. python装饰器参数讲解_python装饰器的详细解析
  5. 7个相同小球4个不同盒子_【计算启蒙】4个游戏陪娃玩懂“数拆分”,加减法都不用愁!...
  6. html图片倒角,CSS实例:纯CSS打造斜角
  7. 未来教育计算机二级答案19,2019年3月计算机二级MSOffice提分试题及答案019
  8. hdu 2586 How far away ?(LCA模板)(倍增法)
  9. 拜托,别再问我什么是 B+ 树了
  10. 关于IIS连接数限制的介绍
  11. html中倒计时精确到毫秒,倒计时功能 精确到毫秒
  12. Chapter 5. MPEG-4 Visual
  13. 金额大小写转换,这里有两种方法提供给你
  14. STM32基础12--数模转换(DAC)
  15. iOS中给图片加水印或文字的几种方法
  16. GRUB的menu.lst的写法
  17. 23种模式——策略模式
  18. 芯邦CMB2198A主控U盘量产工具V6000
  19. python符号积分
  20. 番茄工作法——中断(笔记)

热门文章

  1. 华为首款鸿蒙设备正式入网,华为首款鸿蒙设备正式入网:麒麟9000+挖孔全面屏,价格感人!...
  2. linux里查看最耗CPU的线程
  3. 20165310_获奖感想与Java阶段性学习总结
  4. 丁洪波 -- 不要“ 总是拿着微不足道的成就来骗自己”
  5. 旧题新做:从idy的视角看数据结构
  6. WD 蓝盘、绿盘、黑盘、红盘的区别
  7. java反射--注解的定义与运用以及权限拦截
  8. 用wordpress制作网站的总结
  9. Proxy模式简介和用例
  10. 如何使自己的不和谐机器人