日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

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

發布時間:2023/12/4 C# 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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?,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。

總結

以上是生活随笔為你收集整理的C# 极限压缩 dotnet core 控制台发布文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。