.NET 8にはWindows向けx86(32ビット)ランタイムがあります。ただし、32ビットのアプリを動かすことと、32ビット版Windowsをサポートすることは別です。利用者はアプリが指定するランタイムの種類とx86/x64を選び、開発者はAny CPUのアセンブリと起動用EXE(apphost)のアーキテクチャを分けて確認してください。
.NET 8の32ビット版・64ビット版を入手する
Microsoft公式の.NET 8ダウンロードで、Windows欄のx86が32ビット版、x64が64ビット版です。アプリの説明や起動時の不足メッセージに従い、次の種類を選びます。「8.0以上」という条件だけで、別のメジャーバージョンを入れれば.NET 8アプリも必ず起動できるとは限りません。
| 目的 | 選ぶもの | 確認点 |
|---|---|---|
| WinForms・WPFのデスクトップアプリを実行 | .NET Desktop Runtime | 必要なx86/x64を選ぶ。.NET Runtimeも含む |
| コンソールアプリを実行 | .NET Runtime | 必要なアーキテクチャとメジャー版を確認 |
| アプリをビルド・開発 | .NET SDK | 実行だけならSDKを必須にしない |
| ASP.NET CoreアプリやIISでのホスト | ASP.NET Core Runtime / 対応するHosting Bundle | アプリ・サーバーの導入手順に従う |
MicrosoftのWindowsへの.NET導入案内にある対応OSも確認します。Windows 11上でx86の.NETアプリを使うことは、32ビット版Windows 11が存在するという意味ではありません。古い32ビットPCでは、OSの版・エディション・サポート期間を別に確認してください。x86ランタイムがダウンロードできても、Windows 7/8.1など未対応OSでの動作・サポートは保証されません。
Any CPUなのにEXEが起動しない理由を確認する
C#のPlatformTargetの説明では、Any CPUはアセンブリの設定です。.NET 8でも、この設定とネイティブのapphostのアーキテクチャは分けて考えます。「Any CPUがILではなくapphostの設定になった」という説明は正確ではありません。
Visual Studio 2022 で .NET 8 の WinForms / WPF / Console アプリをビルドすると、通常の構成では次のような出力を確認できます。
MyApp.dll…… 実際の .NET アセンブリ(IL)MyApp.exe…… ネイティブのスターター(apphost)
Microsoftの配布方式の説明では、フレームワーク依存の配布にも、プラットフォーム固有のapphostを生成できます。64ビットのEXEを32ビットOSへコピーしても、ランタイムを追加するだけではそのEXEを32ビット用へ変更できません。SDK・プロジェクト・発行設定によって成果物が異なるため、「Any CPUなら既定で必ずx64」とも断定しません。
| 確認対象 | 意味 | 32ビット対応で見ること |
|---|---|---|
| PlatformTarget=AnyCPU | マネージドアセンブリの対象 | ネイティブ依存や起動ホストとは別 |
| RuntimeIdentifier=win-x86 | 発行先のOS・アーキテクチャ | apphostと依存資産をx86向けとして発行 |
| UseAppHost=false | ネイティブ起動EXEを生成しない | DLLを起動するdotnet.exeのアーキテクチャを確認 |
| SelfContained / –self-contained | ランタイムを同梱するか | 同梱してもOS要件やネイティブDLLの互換性は残る |
開発者向け:win-x86とwin-x64を分けて発行する
dotnet publishの公式仕様に従い、対象プロジェクトから発行先RIDと配布方式を指定します。次はMyApp.csprojというプロジェクト名の例です。元のTargetFrameworkやWinForms/WPF設定は維持し、自分のプロジェクト名へ置き換えます。
dotnet publish MyApp.csproj -c Release -r win-x86 --self-contained false -o publish-x86
dotnet publish MyApp.csproj -c Release -r win-x64 --self-contained false -o publish-x64
この例はランタイムを同梱しないため、利用者のPCに対象の.NETランタイムが必要です。EXEだけでなく、それぞれの発行フォルダー内の必要ファイルを配布します。x86とx64の出力を混ぜず、両方の起動を対象環境で確認してください。
.csprojへ設定する場合
Microsoft.NET.Sdkの公式MSBuildプロパティでは、RuntimeIdentifierで対象を指定します。既存のPropertyGroupへ以下のように追加できます。NETCoreSdkRuntimeIdentifierを配布先指定として上書きする案内にはしません。
<PropertyGroup>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>false</SelfContained>
</PropertyGroup>
一つのプロジェクトから複数の配布先を作る場合は、発行プロファイルやコマンドでRIDを分けます。すでにPlatformTargetがx64固定、依存DLLがx64専用などの制約がある場合は、それも整合させる必要があります。RIDだけを変えればすべての依存が自動的にx86対応するわけではありません。
プロジェクトを複製して別々に保守するより、同じソースから配布先を明示する方法を検討します。
- 同一プロジェクトでプラットフォームを切り替えるだけにする。
- CI/CD 上で
win-x86とwin-x64の両方をビルドし、アーティファクトを分ける。
DLLをdotnetで起動する場合は、ホストを明示する
apphostを使わないフレームワーク依存の配布例です。
dotnet publish MyApp.csproj -c Release --self-contained false -p:UseAppHost=false -o publish-dll
dotnet MyApp.dll
Any CPUのDLLであっても、起動したdotnet.exeと同じプロセスのアーキテクチャで動きます。OSが自動的に両方のランタイムを比較して、アプリに最適なものを選ぶという意味ではありません。ネイティブDLLやWindows固有APIに依存するアプリでは、その条件も満たす必要があります。
利用者向け:x86とx64のランタイムを別々に確認する
dotnetコマンドの公式説明では、--list-runtimesは呼び出したdotnetのアーキテクチャに対応するランタイムを表示します。64ビットWindowsの標準インストール先では、PowerShellで次のように分けて確認できます。カスタム導入先ならパスを合わせてください。
& "C:\Program Files\dotnet\dotnet.exe" --list-runtimes
& "C:\Program Files (x86)\dotnet\dotnet.exe" --list-runtimes
片方のパスが存在しない場合は、その場所に導入されていない可能性があります。x64側で.NET 8が見つかっても、x86アプリの要件を満たすとは限りません。デスクトップアプリならMicrosoft.WindowsDesktop.App、通常のランタイムならMicrosoft.NETCore.Appなど、アプリが必要とする種類も確認します。
32ビット配布の確認項目
- 対象OSの版・エディションが.NETとアプリの対応範囲か。
- 起動するEXEまたはdotnet.exeがx86かx64か。
- WinForms/WPFなど必要なランタイムの種類とメジャーバージョンがあるか。
- ネイティブDLL・COM・データベースドライバーなどのビット数が合うか。
- 発行フォルダーを混ぜずに配布し、実際の32ビットプロセスで業務機能まで確認したか。
- x86ではアドレス空間などの制約があるため、大きなデータを扱う処理の動作を確認したか。
.NET 8のサポート期間も移行計画へ含める
Microsoftの.NETサポートポリシーでは、.NET 8のサポート終了は2026年11月10日です。現在利用する場合は最新の提供済みパッチを適用し、アプリの提供元または開発チームとサポートされる版への移行を検討します。後継のランタイムを入れるだけで.NET 8向けアプリが必ず動くとは限らないため、対象フレームワークと互換性を確認してください。

コメント