

はじめに
技術の進歩に伴い、Microsoft の .NET フレームワークは毎回のイテレーションで驚くべき新機能をもたらしています。.NET 9 バージョンでは、特に注目すべきハイライトとして AOT(Ahead-of-Time)サポートが挙げられます。これにより、開発者はアプリケーションをコンパイル段階で最適化し、Windows 7 や Windows XP などの古い Windows システムでも動作させることが可能になります。これはパフォーマンスを向上させるだけでなく、依然としてこれらの古いプラットフォームに依存している企業や個人の開発者に新たな可能性を提供します。
豆知識:
- .NET 9 AOT の概要
.NET 9 の AOT コンパイラは静的コンパイルにより、.NET アプリケーションをターゲットマシンで直接実行可能な実行可能ファイルに変換し、実行時の JIT(Just-In-Time)コンパイルに必要な時間とリソースを排除します。これは、高いパフォーマンスが求められ、かつ旧バージョンシステムをサポートする必要があるシナリオで顕著な利点があります。
- Windows 7 および Windows XP サポートの背景
Windows 7 や XP はもはや主流の OS ではありませんが、企業のレガシーシステム、組み込みデバイス、リソース制約の厳しい環境など、特定の分野ではまだ広く使われています。.NET 9 の AOT コンパイルのこの拡張は、そのようなシナリオにおける互換性とパフォーマンスのニーズを満たすことを目的としています。
- 実現方法
- コンパイルプロセスの最適化: .NET 9 は AOT コンパイル時にコードをより細かく最適化し、生成される実行可能ファイルを小さくし、起動速度を高速化します。
- 下位互換性: 慎重に設計されたコンパイル戦略により、Win7 および XP の API との互換性を確保し、コードがシームレスに動作するようにします。
- セキュリティの考慮: 古いシステムをサポートしながらも、.NET 9 はセキュリティを重視し、潜在的なリスクを防ぐための一定の保護メカニズムを提供します。
- 応用例と利点
- パフォーマンス向上: AOT コンパイル後のプログラムは通常、JIT 実行のプログラムよりも高速であり、特に CPU 負荷の高いタスクで有効です。
- デプロイの容易さ: ユーザーが .NET ランタイムをインストールする必要がなく、デプロイプロセスが簡素化されます。
- メンテナンスコストの低減: 古いシステムに依存する企業は、ランタイムを頻繁にアップグレードする手間が省けます。
この記事は、読者とサイト運営者が実践した成果を共有することを目的としています。さらなる発見があれば、投稿やこの記事への PR をお待ちしています。
Windows 7 サポート
下図は、あるユーザーがコンパイルした Avalonia UI クロスプラットフォームプロジェクトを Win 7 (SP1 未インストール) 環境で実行したスクリーンショットです。

上図の通り、左側がプログラムの実行画面、右側が OS のバージョンです。


読者のコードコピーを容易にするため、参考設定を以下に示します。
<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 OS で動作可能(XP で Avalonia は失敗) -->
<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" />
<!-- 下記の条件は、Release 構成で Avalonia.Diagnostics パッケージがビルド出力に含まれないようにするために必要です -->
<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 OS で動作可能にします。
VC-LTL
VC-LTL は、Microsoft VC をベースに修正したオープンソースのランタイムであり、アプリケーションサイズを効果的に削減し、msvcr120.dll や api-ms-win-crt-time-l1-1-0.dll などの Microsoft ランタイム DLL への依存を排除します。
Win7 以上では、AOT で正常に動作する可能性があります(.NET ランタイムのインストール不要)。ただし、ターゲットシステムで実行に失敗する場合があるため、このライブラリを追加して再度 AOT コンパイルを試みることができます。詳細な原理はリポジトリを参照:https://github.com/Chuyu-Team/VC-LTL
サイト運営者の実測:Windows 7 ではさらに YY-Thunks パッケージの参照が必要な場合があります。
<PackageReference Include="YY-Thunks" Version="1.1.4-Beta3" />
YY-Thunks について:リンク、説明:
ご存知の通り、Windows のアップデートごとに多数の新しい API が追加され、異なるバージョンの Windows との互換性を保つには多大な労力が必要です。そのため、現在多くのオープンソースプロジェクトは、Windows XP RTM などの初期の Windows バージョンとの互換性を維持していません。
プログラムのエントリポイントを解決できないという問題を迅速かつ効率的に解決する方法はないのでしょうか?
YY-Thunks は、異なるシステム間の差異を吸収することを目的としており、コンパイル時に単一の obj を追加するだけで、これらの互換性問題を自動的に解決します。これにより、古いバージョンの Windows との互換性をより簡単に実現できます!
テストの結果、Winforms は .NET 9 x86 AOT 公開後に実行可能で、スクリーンショットを以下に示します。

Winforms プロジェクトの設定は以下の通りです。

コピー可能な設定:
<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>
/// アプリケーションのメインエントリポイントです。
/// </summary>
[STAThread]
static void Main()
{
// アプリケーション構成をカスタマイズするには(例:高DPI設定やデフォルトフォント)、
// 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、メモに加群と記載)を追加して、微信技術交流グループに参加してください。
