自从NET7发布以来。官方并没有放弃winform。任然继续维护。
传统NET F发布程序。首先需要NET环境。被各种吐槽。发布一个应用2MB,结果客户需要安装一个百MB的NET环境。现在NET7中已经得到很大改善。单发布应用也可以直接将环境一起发布。发给客户使用时候。直接运行,不需要客户安装NET环境。
现在介绍一个更好的方法。winform程序 AOT发布。发布后和原生APP一样。直接将IL代码编译成原生应用。不但免NET环境运行,且和C/C 发布程序相似,得到了很快的运行速度。一个原生EXE。速度性能等得到大幅度提升。
注意此方法是官方推荐,但并非官方发布。发布后需要测试。
一.新建一个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。此包是发布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发布。注意 只有NET7以上有效。
_SuppressWinFormsTrimError:抑制WinForms修剪错误。若不添加WinFormsComInterop包此项是无效的。添加这个后便winform程序编译器不会报错误不可修建。此属于必须。
AllowUnsafeBlocks:允许不安全的块
CustomResourceTypesSupport:自定义资源类型支持。此项很重要。程序中添加图标,图档等没有这项会报错。
RdXmlFile:添加rd描述文件,此项很重要。帮助编译器修剪。
下面贴出完整。使用期间根据自己开发需求添加
<?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()); } }}
到此,全部改造完成。
现在生成的程序便可以AOT发布了。
随机布局。调试启动成功。
添加发布
如下改动
完成发布后目录下生成如下文件。
启动成功。目标目录下附带很多Dll文件,我接下来测试发现将程序复制到win7环境,并不需要复制dll文件也能顺利启动。
复制程序到win7环境顺利运行。
通过以上改动,一个NET7开发的程序使用AOT发布完成。若是用此方法开发一些小工具简直太方便了。若是发布后感觉文件很大,完全可以用upx压缩.依然有效。
最后我们把程序拖动到ILspy中发现看不到任何内容。
至此确确实实是一个windows原生程序应用。是不是很好。
若需要测试源码。留言评论。或者发私信给我。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。