自從NET7發(fā)布以來。官方并沒有放棄winform。任然繼續(xù)維護。
傳統(tǒng)NET F發(fā)布程序。首先需要NET環(huán)境。被各種吐槽。發(fā)布一個應用2MB,結果客戶需要安裝一個百MB的NET環(huán)境?,F(xiàn)在NET7中已經得到很大改善。單發(fā)布應用也可以直接將環(huán)境一起發(fā)布。發(fā)給客戶使用時候。直接運行,不需要客戶安裝NET環(huán)境。
現(xiàn)在介紹一個更好的方法。winform程序 AOT發(fā)布。發(fā)布后和原生APP一樣。直接將IL代碼編譯成原生應用。不但免NET環(huán)境運行,且和C/C 發(fā)布程序相似,得到了很快的運行速度。一個原生EXE。速度性能等得到大幅度提升。
注意此方法是官方推薦,但并非官方發(fā)布。發(fā)布后需要測試。
一.新建一個winform項目。選NET7。
生成后如下。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net7.0-windows</TargetFramework> <Nullable>enable</Nullable> <UseWindowsForms>true</UseWindowsForms> <ImplicitUsings>enable</ImplicitUsings> </PropertyGroup></Project>
對上面的內容改動。增加AOT。
1.nuget 添加 WinFormsComInterop。此包是發(fā)布AOT前提。
然后改動 csproj 項目內容。完整如下。
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>WinExe</OutputType> <TargetFramework>net7.0-windows</TargetFramework> <Nullable>enable</Nullable> <UseWindowsForms>true</UseWindowsForms> <ImplicitUsings>enable</ImplicitUsings> <PublishAot>true</PublishAot> <_SuppressWinFormsTrimError>true</_SuppressWinFormsTrimError> <AllowUnsafeBlocks>True</AllowUnsafeBlocks> <CustomResourceTypesSupport>true</CustomResourceTypesSupport> </PropertyGroup> <ItemGroup> <RdXmlFile Include="rd.xml" /> </ItemGroup> <ItemGroup> <PackageReference Include="WinFormsComInterop" Version="0.4.3" /> </ItemGroup></Project>
PublishAot :程序啟動AOT發(fā)布。注意 只有NET7以上有效。
_SuppressWinFormsTrimError:抑制WinForms修剪錯誤。若不添加WinFormsComInterop包此項是無效的。添加這個后便winform程序編譯器不會報錯誤不可修建。此屬于必須。
AllowUnsafeBlocks:允許不安全的塊
CustomResourceTypesSupport:自定義資源類型支持。此項很重要。程序中添加圖標,圖檔等沒有這項會報錯。
RdXmlFile:添加rd描述文件,此項很重要。幫助編譯器修剪。
下面貼出完整。使用期間根據自己開發(fā)需求添加
<?xml version="1.0" encoding="utf-8" ?><Directives> <Application> <Assembly Name="System.Resources.Extensions"> <Type Name="System.Resources.Extensions.RuntimeResourceSet" Dynamic="Required All" /> <Type Name="System.Resources.Extensions.DeserializingResourceReader" Dynamic="Required All" /> </Assembly> <Assembly Name="System.Drawing"> <Type Name="System.Drawing.Bitmap" Dynamic="Required All" /> <Type Name="System.Drawing.Icon" Dynamic="Required All" /> </Assembly> <Assembly Name="System.Windows.Forms"> <Type Name="System.Windows.Forms.PropertyGridInternal.PropertiesTab" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewButtonColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewComboBoxColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewCheckBoxColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewImageColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewLinkColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewTextBoxColumn" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewButtonCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewComboBoxCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewCheckBoxCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewHeaderCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewImageCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewLinkCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewRowHeaderCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewTextBoxCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewTopLeftHeaderCell" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewComboBoxEditingControl" Dynamic="Required All" /> <Type Name="System.Windows.Forms.DataGridViewTextBoxEditingControl" Dynamic="Required All" /> <Type Name="System.Windows.Forms.RadioButton" Dynamic="Required All" /> <Type Name="System.Windows.Forms.RichTextBox" Dynamic="Required All" /> </Assembly> </Application></Directives>
以上準備工作完成后,對啟動程序修改。
改動Program.cs 中的代碼 增添一下內容
ComWrappers.RegisterForMarshalling(WinFormsComInterop.WebView2.WebView2ComWrapper.Instance);
using System.Runtime.InteropServices;namespace TestAotApp{ internal static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ComWrappers.RegisterForMarshalling(WinFormsComInterop.WebView2.WebView2ComWrapper.Instance); ApplicationConfiguration.Initialize(); Application.Run(new Form1()); } }}
到此,全部改造完成。
現(xiàn)在生成的程序便可以AOT發(fā)布了。
隨機布局。調試啟動成功。
添加發(fā)布
如下改動
完成發(fā)布后目錄下生成如下文件。
啟動成功。目標目錄下附帶很多Dll文件,我接下來測試發(fā)現(xiàn)將程序復制到win7環(huán)境,并不需要復制dll文件也能順利啟動。
復制程序到win7環(huán)境順利運行。
通過以上改動,一個NET7開發(fā)的程序使用AOT發(fā)布完成。若是用此方法開發(fā)一些小工具簡直太方便了。若是發(fā)布后感覺文件很大,完全可以用upx壓縮.依然有效。
最后我們把程序拖動到ILspy中發(fā)現(xiàn)看不到任何內容。
至此確確實實是一個windows原生程序應用。是不是很好。
若需要測試源碼。留言評論?;蛘甙l(fā)私信給我。
版權聲明:本文內容由互聯(lián)網用戶自發(fā)貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權/違法違規(guī)的內容, 請發(fā)送郵件至 舉報,一經查實,本站將立刻刪除。