UWP アプリの起動直後に「Could not load file or assembly ‘System.Runtime.WindowsRuntime…’(0x80131040)」が出て落ちる――この典型的なトラブルは、ほぼ例外なく System.Runtime.WindowsRuntime の“重複参照・バージョン競合”が原因です。本記事では、根本原因の理解から Visual Studio での具体的な削除手順、深掘り診断、再発防止までを一気通貫で解説します。提示の手順だけで復旧できるよう、実務ベースでまとめました。
症状(再現環境の例とエラーメッセージ)
対象は UWP アプリ BasicCoreApp.exe。起動時に次の例外が発生してアプリが停止します。
Could not load file or assembly
'System.Runtime.WindowsRuntime, Version=4.0.15.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089'.
The located assembly's manifest definition does not match the assembly reference.
(Exception from HRESULT: 0x80131040)
ポイントは「manifest definition does not match(参照と実体の不一致)」と HRESULT 0x80131040(アセンブリ バインディングの競合)。UWP では OS 付属の Windows SDK が System.Runtime.WindowsRuntime を提供しているため、プロジェクト側で同名アセンブリを追加すると衝突しやすくなります。
結論(最短解決手順)
時間がない場合は、以下の順に実施してください。多くの環境でこの手順だけで解決します。
- 余分な参照を削除
Visual Studio のソリューション エクスプローラーで該当プロジェクトを選択 → [参照](または [依存関係 > Assemblies])を開き、System.Runtime.WindowsRuntime(および「WindowsRuntime」を含む重複参照)があれば削除します。 - 不要な NuGet パッケージを削除
[NuGet パッケージの管理] → [インストール済み]で、System.Runtime.WindowsRuntimeやMicrosoft.Windows.SDK.Contractsを UWP プロジェクトから削除します(これらは UWP では基本不要)。 .csproj/.vbprojを直接確認
エディターでプロジェクト ファイルを開き、<Reference Include="System.Runtime.WindowsRuntime" … />または<PackageReference Include="System.Runtime.WindowsRuntime" … />、Microsoft.Windows.SDK.Contractsの記述が残っていないか点検し、残っていれば削除します。- ビルド中間物のクリーン
binとobjを削除し、ソリューションをクリーン → リビルドします。NuGet キャッシュも次のコマンドでクリアすると確実です。nuget locals all -clear dotnet nuget locals all --clear - Windows SDK と .NET Native ツールチェーンの更新
Visual Studio Installer で「ユニバーサル Windows プラットフォーム開発」ワークロードを最新化し、OS に合った最新の Windows 10/11 SDK と .NET Native(UWP 用)を入れてから再ビルドします。
なぜ起こるのか:UWP と System.Runtime.WindowsRuntime の関係
UWP は Windows Runtime(WinRT)API を利用するプラットフォームで、System.Runtime.WindowsRuntime は.NET と WinRT を橋渡しする重要アセンブリです。UWP ではこのアセンブリをWindows SDK が提供しているため、プロジェクト側で「同名アセンブリ」や「同機能の NuGet パッケージ」を追加すると、ビルド生成物に複数バージョンが混在し、起動時のバインディングで 0x80131040 が発生します。
よくある発生パターン
| パターン | 典型的な経路 | 何が起きるか | 対処の要点 |
|---|---|---|---|
| 直接参照の追加 | 「参照の追加」で System.Runtime.WindowsRuntime を明示的に追加 | OS 提供版と競合し、起動時に不一致 | 参照を削除(UWP では不要) |
| NuGet パッケージ経由 | Microsoft.Windows.SDK.Contracts を UWP に導入 | SDK 付属版とバージョン衝突 | パッケージをアンインストール |
| 共有ライブラリ経由 | .NET Standard ライブラリが上記パッケージを間接参照 | UWP 側にトランジティブで混入 | ライブラリ側を更新/条件付き参照に変更 |
| 古いテンプレート混在 | 古い UWP テンプレート(meta パッケージ)と新 SDK の混在 | 解決優先度の差で誤った版を採用 | ワークロード/SDK を揃えて再構成 |
Visual Studio での具体的な操作
参照の削除
- ソリューション エクスプローラーで UWP プロジェクトを選択。
- [依存関係] > [アセンブリ](または [参照])を展開。
System.Runtime.WindowsRuntime、WindowsRuntimeを含む参照があれば削除。
NuGet パッケージのアンインストール
- プロジェクトを右クリック → [NuGet パッケージの管理]。
- [インストール済み]タブで以下を探す:
・System.Runtime.WindowsRuntime
・Microsoft.Windows.SDK.Contracts - 見つかったらアンインストール。
コードや設定ファイルの直接編集
誤って残った記述を除去します。次のような要素は削除対象です。
<ItemGroup>
<PackageReference Include="System.Runtime.WindowsRuntime" Version="4.0.15" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.22621.1" />
</ItemGroup>
保存後、bin/obj を消去 → クリーン → リビルドを忘れずに。
深掘り診断:どこから混入しているか特定する
Package Manager Console で依存関係を洗い出す
Visual Studio の「ツール > NuGet パッケージマネージャー > パッケージ マネージャー コンソール」で次を実行すると、怪しいパッケージの混入源を素早く発見できます。
# プロジェクト内の依存関係から "windowsruntime" と "sdk.contracts" を含むものを検出
Get-Package -ProjectName "BasicCoreApp" -IncludeDependencies |
Where-Object { $_.Id -match "windowsruntime|sdk\.contracts" } |
Sort-Object Id, Version |
Format-Table Id, Version, ProjectName -Auto
MSBuild 詳細ログで解決結果を確認
ビルドの解決経路を把握したい場合は詳細ログを取得します。
# 開発者コマンド プロンプト等で
msbuild BasicCoreApp.sln /t:Restore,Build /v:detailed > build.log
build.log の ResolveAssemblyReferences セクションに、どのフォルダーから System.Runtime.WindowsRuntime が取られたかが記録されます。Windows SDK のパス(例:C:\Program Files (x86)\Windows Kits\10\...)ではなく、グローバル NuGet キャッシュ(%USERPROFILE%\.nuget\packages)から見つかっているなら競合確定です。
NuGet キャッシュ/中間物の完全クリア
キャッシュが原因で古い版を拾うことがあります。以下のコマンドで一掃してから再ビルドしてください。
nuget locals all -clear
dotnet nuget locals all --clear
実例:BasicCoreApp.exe を修正する
修正前(問題のある .csproj)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
修正後(余計な参照を除去)
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
この変更後、bin/obj を削除 → リビルドで起動できるようになります。
共有ライブラリが原因の場合の対処
UWP 本体ではなく、参照先の .NET Standard/PCL ライブラリが Microsoft.Windows.SDK.Contracts 等を間接参照して競合するケースがあります。次のいずれかで解消します。
- ライブラリの更新:UWP での使用を想定した新しい版を入手。
- 条件付き参照:ライブラリの
.csprojをマルチターゲット化し、UWP ターゲット(uap10.0.x)ではSystem.Runtime.WindowsRuntimeを参照しないよう条件分岐。<PropertyGroup> <TargetFrameworks>netstandard2.0;uap10.0.19041</TargetFrameworks> </PropertyGroup> - 呼び出し側での参照除去:UWP 側で該当パッケージを 敢えて導入しない(= OS 付属版を使う)。
開発環境の整合性チェック(再発防止)
| 項目 | 確認内容 | 推奨状態 |
|---|---|---|
| UWP ワークロード | Visual Studio Installer の構成 | 「ユニバーサル Windows プラットフォーム開発」を最新化 |
| Windows SDK | プロジェクトの TargetPlatformVersion | OS に合う安定版(例:10.0.19041 以降) |
| .NET Native ツールチェーン | UWP 用コンパイラ/パッケージが入っているか | 最新に更新 |
| 余計なパッケージ | System.Runtime.WindowsRuntime/Microsoft.Windows.SDK.Contracts | UWP プロジェクトには入れない |
| キャッシュ | NuGet グローバルパッケージの残骸 | nuget locals all -clear で定期的に整理 |
| CI/CD | ビルド環境ごとの差異 | packages.lock.json をコミットし依存を固定 |
トラブルシューティングの“落とし穴”と回避策
- 「バージョンを合わせれば良い」わけではない:UWP では OS 付属のアセンブリを使うのが鉄則。合わせるのではなく入れないのが正解です。
- ビルドは通るのに実行で落ちる:ビルド時に
objへコピーされた別バージョンが.appxに混入し、実行時に衝突します。bin/obj の削除で改善することが多いです。 - ARM64/Any CPU の設定:構成が複数ある場合、各構成で参照状態が一致しているか確認します(x86 では治るが ARM64 で落ちる等)。
- Desktop Bridge を併用している場合:WPF/WinForms 側が
System.Runtime.WindowsRuntimeを直接参照していないか確認。UWP コンテナーと重複すると不整合になります。
よくある質問(FAQ)
Q. どこで削除すれば良い?
A. Visual Studio の「参照/依存関係」および「NuGet パッケージ」が主な削除ポイントです。見当たらなければ .csproj を直接開き、前述の要素を取り除いてください。
Q. バージョンを変更すれば直りますか?
A. 変更より参照を無くすのが確実です。どうしても外部ライブラリの都合で必要な場合は、ライブラリ側をマルチターゲット化して UWP ではその参照を避ける設計に切り替えてください。
Q. 参照は見当たらないのに例外が出ます
A. トランジティブ(間接)依存の可能性があります。Package Manager Console の出力や MSBuild ログで混入源を特定し、ライブラリ側を更新または条件付き参照にしてください。
Q. CI では落ちるがローカルでは再現しません
A. ビルドホストの SDK/ワークロード差異や NuGet キャッシュが原因です。CI に UWP ワークロードと対象 SDK をインストールし、nuget locals all -clear を実行。依存の固定には packages.lock.json の採用が有効です。
再発防止の設計指針
- UWP プロジェクトでは OS 付属の WinRT 参照を活用:
System.Runtime.WindowsRuntimeを手動追加しない。 - 共有コードの分離:Windows 固有 API は
#if WINDOWS_UWPで分離し、共通部分は .NET Standard に閉じ込める。 - 依存の固定:
Directory.Packages.propsやpackages.lock.jsonを用いて環境差異を抑制。 - ビルド定期点検:SDK 更新後は必ずクリーンビルドし、起動テストを自動化(起動後の smoke test を CI に追加)。
最終チェックリスト(この順で確認)
- プロジェクトの「参照/依存関係」から
System.Runtime.WindowsRuntimeを削除した。 - UWP プロジェクトから
Microsoft.Windows.SDK.Contractsをアンインストールした。 .csprojから該当の<Reference>/<PackageReference>を除去した。bin/objを削除し、NuGet キャッシュをクリアした。- Windows SDK と .NET Native ツールチェーンを最新化した。
- 外部ライブラリがトランジティブに混入させていないか確認した。
まとめ
UWP での System.IO.FileLoadException(System.Runtime.WindowsRuntime 由来、0x80131040)は、OS 付属アセンブリとプロジェクト側の重複が原因です。解決の鍵は「余計な参照を入れない」こと。参照・パッケージの削除、プロジェクト ファイルの整理、bin/obj とキャッシュのクリーン、SDK/ツールチェーンの更新という定石を確実に踏めば、BasicCoreApp.exe は正常に起動するはずです。加えて、共有ライブラリの設計を見直し、UWP ターゲットでは外部の System.Runtime.WindowsRuntime を参照しないようにしておけば、同種の不具合は再発しません。
付録:コマンド&スニペット集(コピペ可)
怪しいパッケージを素早く洗い出す
# NuGet パッケージ一覧から "windowsruntime" と "sdk.contracts" をあぶり出す
Get-Package -ProjectName "BasicCoreApp" -IncludeDependencies |
Where-Object { $_.Id -match "windowsruntime|sdk\.contracts" } |
Sort-Object Id, Version |
Format-Table Id, Version -Auto
NuGet キャッシュを完全消去
nuget locals all -clear
dotnet nuget locals all --clear
詳細ログで参照解決を追跡
msbuild BasicCoreApp.sln /t:Restore,Build /v:detailed > build.log
削除すべき典型的な .csproj 記述
<PackageReference Include="System.Runtime.WindowsRuntime" Version="4.0.15" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.xxxxx.x" />
<Reference Include="System.Runtime.WindowsRuntime" />
この手順で解決できる理由(技術メモ)
- UWP の実行環境では、
System.Runtime.WindowsRuntimeは Windows SDK の一部として提供され、アセンブリ バインダーは OS 提供版を前提に解決します。 - プロジェクト配下(
.appx内)に同名アセンブリがあると、解決優先度や厳密バージョン一致の要件により不一致が検出され、0x80131040が発生します。 - よって余計な参照の排除とクリーンビルドが最も効果的な解決策になります。
実務 Tips
- 構成毎に検証:Debug x86 / x64 / ARM64 / Release を個別に起動確認する(構成違いで参照がズレることがある)。
- CI の再現性:
nuget.configでフィードを固定し、packages.lock.jsonをコミットして依存ブレを防ぐ。 - コード分岐の見える化:
#if WINDOWS_UWPのセクションを 1 ファイルに集約するなど、UWP 特有の参照を可視化する。

コメント