Windows Form アプリケーションでAOT (Ahead On Time) によるネイティブビルドをする - C#

Windows Form アプリケーションでAOT(Ahead On Time) を有効にしてネイティブビルドする手順を紹介します。

概要

.NETアプリケーションはデフォルトでは、アプリケーションの実行時にコンパイルをするJIT (Just-In-Time)コンパイルで動作します。 実行時にILコードからネイティブ・コードにビルドされるため、32ビット/64ビットアプリケーションを共通にできたり、クロスプラットフォームで動作するアプリを用紙できますが、 一方でアプリケーション実行時にコンパイルされるため、オーバーヘッドがあり、パフォーマンス面ではネイティブアプリケーションに比べ、若干劣る部分があります。
.NET 7で導入されたAOT(Ahead On Time)を利用すると事前にネイティブアプリケーションにコンパイルできるため、ネイティブアプリケーションに近いパフォーマンスになります。 この記事では、AOTを有効にしてビルドする手順を紹介します。

手順

Windows Form アプリケーション(.NET)を作成します。

プロジェクト作成ダイアログの[フレームワーク]の設定で ".NET 7.0" を選択します。



Windows Formアプリケーションが作成できました。

UI

下図のフォームを作成します。フォームにLabelコントロールを配置します。

プロジェクトファイルの設定

ソリューションエクスプローラーのウィンドウでプロジェクトのノードをクリックして選択します。プロジェクトのノードを右クリックします。 下図のポップアップメニューが表示されます。メニューの[プロジェクト ファイルの編集]の項目をクリックします。


プロジェクトファイルがコードで表示されます。


プロジェクトファイルを編集します。
プロジェクトファイル (編集前)
<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>


PublishAot タグと PublishTrimmed タグを追記します。
プロジェクトファイル (編集後)
<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>
    <PublishTrimmed>false</PublishTrimmed>
  </PropertyGroup>

</Project>

補足

PublishTrimmedタグを記述せずにトリミングを有効な設定でビルドすると、以下のエラーが発生します。
エラーメッセージ
エラー NETSDK1175 : Windows フォームに関して、トリミングの有効化はサポートおよび推奨されていません。詳細については、https://aka.ms/dotnet-illink/windows-forms を参照してください。

構成マネージャーの設定

構成マネージャーでx64プラットフォームのビルド構成を追加します。 追加の手順はこちらの記事を参照してください。
ツールバー上部の[ソリューションプラットフォーム]の設定をx64に設定されていることを確認します。


プロジェクトをビルドします。ビルドの成功後、出力フォルダを確認します。
下図のファイルが作成されています。ファイルの数が非常に多い状態で出力されています。


なお、PublishAotがfalseの場合、デフォルトの設定の場合は下図のファイルが出力されます。ファイルの数がPublishAotの場合と比べて非常に少ないです。

アプリケーションの発行

アプリケーションを発行した場合の結果を確認しようとしましたが、発行を実行するとエラーが発生します。
対処法は不明です。
コンソールアプリケーションと同様に、1つのファイルにまとめられる動作を期待していましたが、 トリミングをFalseに設定していることが影響しているためか、現状うまく動作しないようです。


ログファイルには以下のエラーが記録されます。
エラーログ
yyyy/mm/dd hh:mm:ss
System.AggregateException: 1 つ以上のエラーが発生しました。 ---> Microsoft.WebTools.Shared.Exceptions.WebToolsException: 発行でエラーが発生しました。エラーの原因を特定できませんでした。詳細については、出力ログを確認してください。
   --- 内部例外スタック トレースの終わり ---
---> (内部例外 #0) Microsoft.WebTools.Shared.Exceptions.WebToolsException: 発行でエラーが発生しました。エラーの原因を特定できませんでした。詳細については、出力ログを確認してください。<---

Microsoft.WebTools.Shared.Exceptions.WebToolsException: 発行でエラーが発生しました。エラーの原因を特定できませんでした。詳細については、出力ログを確認してください。

===================
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2022-11-19
iPentec all rights reserverd.