

引言
隨著技術的不斷進步,微軟的 .NET 框架在每次迭代中都帶來了令人驚喜的新特性。在 .NET 9 版本中,一個特別引人注目的亮點是 AOT(Ahead-of-Time)支援,它允許開發人員將應用程式在編譯階段就最佳化為能夠在老舊的 Windows 系統上執行,包括 Windows 7 和甚至 Windows XP。這不僅提升了效能,也為那些依然依賴這些老平台的企業和個人開發者提供了新的可能性。
小知識普及:
- .NET 9 AOT 簡介
.NET 9 的 AOT 編譯器透過靜態編譯,將 .NET 應用程式轉換為可以直接在目標機器上執行的可執行檔,消除了在執行階段的 JIT(Just-In-Time)編譯所需的時間和資源。這對於對效能要求高且需要支援舊版系統的場景具有顯著優勢。
- 支援 Windows 7 與 Windows XP 的背景
儘管 Windows 7 和 XP 已經不再是主流作業系統,但它們在某些特定領域,如企業遺留系統、嵌入式裝置或者資源受限的環境中仍有廣泛應用。.NET 9 的 AOT 編譯這一擴展,旨在滿足這些場景的相容性和效能需求。
- 如何實現
- 編譯過程最佳化:.NET 9 在 AOT 編譯時,對程式碼進行了更為細緻的最佳化,使得產生的可執行檔更小,啟動速度更快。
- 向下相容性:透過精心設計的編譯策略,確保了對 Win7 及 XP API 的相容性,使程式碼能夠無縫執行。
- 安全性考量:雖然支援老舊系統,但 .NET 9 依然注重安全,提供了一定程度的保護機制以抵禦潛在的風險。
- 實例應用與優勢
- 效能提升:AOT 編譯後的程式通常比 JIT 執行的程式更快,尤其對於 CPU 密集型任務。
- 部署簡易:無需使用者安裝 .NET 執行階段,簡化了部署流程。
- 維護成本降低:對於依賴老舊系統的企業,避免了頻繁升級執行階段的困擾。
本文只在分享網友及站長實踐的一個成果,如有更多發現,歡迎投稿或給本文 PR。
Windows 7 支援
下圖是網友編譯的 Avalonia UI 跨平台專案在 Win 7 非 SP1 環境執行效果截圖:

如上圖,左側是程式執行介面,右側是作業系統版本。


為了便於讀者程式碼拷貝,參考配置貼出如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<PublishAot>true</PublishAot>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<InvariantGlobalization>true</InvariantGlobalization>
<!--支援在Windows XP或更高版本的Windows作業系統上執行,XP下嘗試Ava失敗-->
<WindowsSupportedOSPlatformVersion>5.1</WindowsSupportedOSPlatformVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetPlatformMinVersion>5.1</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="VC-LTL" Version="5.1.1-Beta3" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.1.1" />
<PackageReference Include="Avalonia.Desktop" Version="11.1.1" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.1" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.1.1" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.1" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.1.1" />
</ItemGroup>
</Project>
上面關鍵配置說明:
<PublishAot>true</PublishAot>
該開關用於支援 AOT 編譯發佈
<WindowsSupportedOSPlatformVersion>5.1</WindowsSupportedOSPlatformVersion>
支援在 Windows XP 或更高版本的 Windows 作業系統上執行
VC-LTL
VC-LTL 是一個基於微軟 VC 修改的開源執行階段,有效減少應用程式體積並擺脫微軟執行階段 DLL,例如 msvcr120.dll、api-ms-win-crt-time-l1-1-0.dll 等依賴。
Win7 及以上版本,可能 AOT 就能正常執行(不需要安裝 .NET 執行階段)。但也有可能在目標系統執行失敗,可新增該庫嘗試重新 AOT 編譯。詳細原理參考該倉庫:https://github.com/Chuyu-Team/VC-LTL
經站長實測:Windows7 可能還需要新增 YY-Thunks 套件參考:
<PackageReference Include="YY-Thunks" Version="1.1.4-Beta3" />
關於 YY-Thunks:連結,說明:
眾所周知,從 Windows 的每次更新又會新增大量 API,這使得相容不同版本的 Windows 需要花費很大精力。導致現在大量開源項目已經不再相容一些早期的 Windows 版本,比如 Windows XP RTM。
難道就沒有一種快速高效的方案解決無法定位程式輸入點的問題嗎?
YY-Thunks(鴨船),存在的目的就是抹平不同系統的差異,編譯時單純新增一個 obj 即可自動解決這些相容性問題。讓你相容舊版本 Windows 更輕鬆!
經測試,Winform 可以 .NET 9 x86 AOT 發佈後執行,效果截圖如下:

Winform 工程配置如下:

可拷貝配置如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<InvariantGlobalization>true</InvariantGlobalization>
<WindowsSupportedOSPlatformVersion>5.1</WindowsSupportedOSPlatformVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<TargetPlatformMinVersion>5.1</TargetPlatformMinVersion>
<PublishAot>true</PublishAot>
<_SuppressWinFormsTrimError>true</_SuppressWinFormsTrimError>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="VC-LTL" Version="5.1.1-Beta3" />
<PackageReference Include="WinFormsComInterop" Version="0.5.0" />
</ItemGroup>
</Project>
入口再加一句程式碼 ComWrappers.RegisterForMarshalling(WinFormsComInterop.WinFormsComWrappers.Instance);:
using System.Runtime.InteropServices;
namespace WinFormsAotDemo;
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.WinFormsComWrappers.Instance);
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
Windows XP 支援
目前測試可執行主控台程式:

網友得出結論:

XP 需要連結 YY-Thunks,參考連結:https://github.com/Chuyu-Team/YY-Thunks(前面有提及,Win7 如果失敗也可以新增該套件參考嘗試)

大家可關注 YY-Thunks 這個 ISSUE:https://github.com/Chuyu-Team/YY-Thunks/issues/66

主控台支援 XP 的工程配置如下:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<InvariantGlobalization>true</InvariantGlobalization>
<WindowsSupportedOSPlatformVersion>5.1</WindowsSupportedOSPlatformVersion>
<SupportWinXP>true</SupportWinXP>
<PublishAot>true</PublishAot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="VC-LTL" Version="5.1.1-Beta3" />
</ItemGroup>
</Project>
網友心得:

有待加強的部分
經測試 Prism 框架使用會報錯:

使用 HttpClient 也會出錯:

2024-08-02
通過閱讀開源 Avalonia 主題庫 Semi.Avalonia 的原始碼及作者
Rabbitism兔佬的 PR 已經解決 Prism 問題的,其他庫問題使用方法應該類似,修改如下:主工程新增 Roots.xml,內容如下:
<linker> <assembly fullname="CodeWF.Toolbox.Desktop" preserve="All"/> <assembly fullname="Ursa.PrismExtension" preserve="All" /> <assembly fullname="Prism" preserve="All" /> <assembly fullname="DryIoc" preserve="All" /> <assembly fullname="Prism.Avalonia" preserve="All"/> <assembly fullname="Prism.DryIoc.Avalonia" preserve="All"/> <assembly fullname="CodeWF.Toolbox" preserve="All" /> </linker>主工程新增該 XML 配置:
<ItemGroup> <TrimmerRootDescriptor Include="Roots.xml" /> </ItemGroup>HttpClient 也是類似的處理方法,這裡不贅述,需要你進行更多嘗試。
每個公司的不同專案都是極其不同、複雜的,實際發佈還需要不斷測試,為了支援 Windows 7、Windows XP 可能不得不做出使用庫替換、部分 API 使用取捨等操作,歡迎讀者將使用過程中的心得體會進行分享。
結語
.NET 9 的 AOT 支援無疑拓寬了 .NET 生態的應用範圍,為那些需要在老舊平台上執行高效能應用程式的開發者提供了強大的工具。隨著技術的發展,我們期待未來更多的 .NET 版本能夠進一步打破界限,讓程式設計變得更加靈活和高效。
感謝網友 GSD 及 M$達 分享的這個好消息,大石頭這篇文章《各版本作業系統對 .NET 支援情況》推薦大家閱讀:https://newlifex.com/tech/os_net
參考 AOT 專案:https://github.com/dotnet9/CodeWF.Toolbox
技術交流
軟體開發技術交流新增 QQ 群:771992300
或掃站長微信(codewf,備註加群)加入微信技術交流群:
