Windows SDK 10.0.26100.0 へ更新後、Win32 C++ で XAML Islands を使うと「E1696: cannot open source file winrt/UwpApplication.h」等の赤線に悩まされがちです。本記事は “ヘッダーが無い” ように見える原因を仕組みから解きほぐし、最短で解決する手順・正しいインクルード・生成ヘッダーの扱い・NuGet 運用までを実務目線で整理しました。
結論(最短の回答)
- UwpApplication.h は不要。XAML Islands の最小構成では使いません。インクルード行は削除します。
- interop ヘッダーと C++/WinRT 投影ヘッダーは別物。
windows.ui.xaml.hosting.desktopwindowxamlsource.hはwinrt/配下には存在しません。 - “ヘッダーが無い” は SDK 欠落ではなく、生成前/未読込みが原因。一度ビルド → Rescan Solution で IntelliSense を更新。
- cppwinrt.exe の版ズレは NuGet で解消。 Microsoft.Windows.CppWinRT を追加し、統一された生成環境に。
- リンク エラーには
windowsapp.libを追加。 未追加だと RoGetActivationFactory 未解決になります。
問題の背景:なぜ「ヘッダーが無い」と見えるのか
Visual Studio のエディタが示す E1696 は、IntelliSense 専用の別プロセスがファイルを見つけられなかったときに発生します。XAML/WinRT の C++ 投影ヘッダー(winrt/<Namespace>.h)は、ビルド時に cppwinrt.exe が .winmd メタデータから自動生成します。つまり:
- 初回ビルド前は
winrt/*が存在しないため、エディタは赤線を付けやすい。 - ビルド後も、IntelliSense のインデックスが更新されていなければ赤線が残る。
このため「ヘッダーが SDK から欠落した」という推測は多くの場合誤りです。正解はビルドして生成させること、そしてIntelliSense キャッシュの再読み込み
XAML Islands の最小インクルード(正しい形)
Win32 C++ で XAML Islands を最小構成で使う場合、以下のヘッダー群で十分です。
// Win32 基本
#include <windows.h>
// C++/WinRT 基本ユーティリティ(check_hresult など)
#include
// C++/WinRT 投影(Namespaces は PascalCase)
#include
#include
#include
#include
#include
#include // WindowsXamlManager など
// interop(winrt/ ではない/小文字・ドット区切り)
#include
// リンク(RoGetActivationFactory 等)
#pragma comment(lib, "windowsapp")
UwpApplication.h は旧サンプル由来の内部ヘッダーで、XAML Islands の最小構成には必要ありません。見つからない場合は削除が正解です。
interop ヘッダーと投影ヘッダーの違い
| 種類 | 例 | 役割 | 所在 |
|---|---|---|---|
| interop ヘッダー | windows.ui.xaml.hosting.desktopwindowxamlsource.h | Win32 HWND と XAML ツリーを結びつける COM インターフェイス群(IDesktopWindowXamlSourceNative など) | Windows SDK の um 配下(winrt/ ではない) |
| 投影ヘッダー | winrt/Windows.UI.Xaml.*.h | C++/WinRT が .winmd から生成する、言語投影(.NET の using に相当) | ビルド時に中間フォルダーへ生成(例:Generated Files/winrt) |
“ヘッダーが無い” ときに確認する 3 ステップ
- 一度ビルドして生成ヘッダーを作る(Debug/x64 など構成に注意)。
- ビルドが通っているのに赤線が消えない場合は、メニュー > Project > Rescan Solution を実行。
- それでも消えない場合は、プロジェクトの Windows SDK Version が 10.0.26100.0 を指しているか、インクルード パスに独自設定が被っていないかを確認。
対処の要点(表で再整理)
| ポイント | 詳細 |
|---|---|
| ① UwpApplication.h は不要 | XAML Islands の最小構成には含みません。#include <winrt/UwpApplication.h> は削除。 |
| ② interop と投影は別 | DesktopWindowXamlSource の interop は windows.ui.xaml.hosting.desktopwindowxamlsource.h。winrt/ では見つかりません。 |
| ③ “欠落” ではなく “未生成/未読込み” | 投影ヘッダーはビルドで生成されます。ビルド→Rescan Solution が第一選択肢。 |
| ④ NuGet で C++/WinRT を揃える | Microsoft.Windows.CppWinRT を導入すると、プロジェクト間で cppwinrt.exe の版を統一でき、IntelliSense の見え方も安定します。 |
| ⑤ 追加 SDK は不要 | 10.0.26100.0 で「欠けた」のではなく、参照方法の問題。インクルード修正と生成手順で解決します。 |
症状 ⇔ 原因 ⇔ 即効対処(早見表)
| 症状 | 主な原因 | 即効対処 |
|---|---|---|
<winrt/UwpApplication.h> が見つからない | XAML Islands では不要 | インクルードを削除 |
<winrt/Windows.UI.Xaml.Hosting.DesktopWindowXamlSource.h> が見つからない | interop ヘッダーを winrt/ で探している | #include <windows.ui.xaml.hosting.desktopwindowxamlsource.h> に修正 |
| ビルド成功なのにエディタだけ赤線 | 生成ヘッダーを IntelliSense が未読込み | Rescan Solution を実行 |
| 型や API が補完候補に出ない | cppwinrt.exe の版ズレ/参照 .winmd 不整合 | NuGet で Microsoft.Windows.CppWinRT を導入、クリーン&ビルド |
unresolved external symbol __imp_RoGetActivationFactory | windowsapp.lib 未リンク | リンカーに windowsapp.lib を追加(または #pragma comment(lib, "windowsapp")) |
| 起動時に XAML 作成で失敗/例外 | COM アパートメントが MTA | winrt::init_apartment(winrt::apartment_type::single_threaded)(既定の init_apartment() でも可) |
正しい初期化順序(XAML Islands)
- STA に入る: C++/WinRT の
winrt::init_apartment()は既定で single_threaded(STA)。XAML は UI スレッドが STA であることが前提です。 - WindowsXamlManager を初期化:
WindowsXamlManager::InitializeForCurrentThread()を最初に呼び、スレッドに XAML を紐付けます。 - DesktopWindowXamlSource を作成:
as<IDesktopWindowXamlSourceNative>()で interop を取り出してAttachToWindow。 - 子 HWND を取得:
get_WindowHandleで XAML Island のハンドルを受け取り、SetWindowPos等でレイアウト。 - コンテンツを設定: ボタンや Grid 等を作成して
DesktopWindowXamlSource::Contentに渡す。
実用サンプル(最小のウィンドウ+ボタン)
#include <windows.h>
#include <winrt/base.h>
#include <winrt/Windows.UI.Xaml.h>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <winrt/Windows.UI.Xaml.Hosting.h>
#include <windows.ui.xaml.hosting.desktopwindowxamlsource.h>
#pragma comment(lib, "windowsapp")
using namespace winrt;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Hosting;
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static DesktopWindowXamlSource s_xamlSource{ nullptr };
static HWND s_islandHwnd{ nullptr };
switch (msg)
{
case WM_CREATE:
{
// STA(既定)で初期化
init_apartment();
// XAML をこのスレッドに初期化(スコープを生かす)
static WindowsXamlManager s_wxm{ WindowsXamlManager::InitializeForCurrentThread() };
// XAML Island 作成
s_xamlSource = DesktopWindowXamlSource{};
auto interop = s_xamlSource.as<IDesktopWindowXamlSourceNative>();
check_hresult(interop->AttachToWindow(hWnd));
check_hresult(interop->get_WindowHandle(&s_islandHwnd));
// XAML ツリー
StackPanel panel;
panel.Margin(Thickness{ 12 });
TextBlock tb;
tb.Text(L"XAML Islands (Windows.UI.Xaml)");
tb.Margin(Thickness{ 0,0,0,8 });
Button btn;
btn.Content(box_value(L"Click me"));
btn.Click([](IInspectable const&, RoutedEventArgs const&)
{
MessageBoxW(nullptr, L"Button clicked!", L"XAML Islands", MB_OK);
});
panel.Children().Append(tb);
panel.Children().Append(btn);
s_xamlSource.Content(panel);
return 0;
}
case WM_SIZE:
if (s_islandHwnd)
{
RECT rc{};
GetClientRect(hWnd, &rc);
SetWindowPos(s_islandHwnd, nullptr, 0, 0,
rc.right - rc.left, rc.bottom - rc.top,
SWP_SHOWWINDOW);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
int APIENTRY wWinMain(HINSTANCE hInst, HINSTANCE, LPWSTR, int nCmdShow)
{
const wchar_t* kClass = L"IslandsSampleWnd";
WNDCLASSW wc{};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInst;
wc.lpszClassName = kClass;
RegisterClassW(&wc);
HWND hWnd = CreateWindowExW(0, kClass, L"XAML Islands Sample",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 480,
nullptr, nullptr, hInst, nullptr);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
MSG msg{};
while (GetMessageW(&msg, nullptr, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return (int)msg.wParam;
}
ポイント: WindowsXamlManager はスレッド単位で初期化され、存続期間中は破棄しないのが安定運用のコツです。上記では static で保持しています。
ビルド設定チェックリスト
- C++ 言語標準: C++20 以上(最新の MSVC なら
/std:c++20。古い環境でコルーチンを使うなら/awaitが必要な場合あり)。 - Windows SDK Version:
10.0.26100.0を選択。 - リンク:
windowsapp.libを追加(赤字の未解決シンボル対策)。 - マルチバイト/Unicode: Unicode を推奨(
wWinMain/MessageBoxWを使用)。 - 構成とプラットフォーム: x64/Debug 等、生成ヘッダーの出力先が構成に依存する点を意識。
生成ヘッダーの所在と扱い
C++/WinRT の投影ヘッダーは、ビルドごとに 中間フォルダーへ生成されます(例:$(IntDir)\Generated Files\winrt)。手でプロジェクトに追加する必要はありません。エディタがこの生成先を追従できず赤線が残るケースでは、以下を試してください。
- Rescan Solution の実行。
- 一旦 Clean → Rebuild。
- IntelliSense の Translation Unit が壊れている場合、Visual Studio の再起動。
NuGet で統一する:Microsoft.Windows.CppWinRT
環境やチーム内で cppwinrt.exe の版が混在すると、IntelliSense だけ赤線・ビルドは通る、といった症状が出やすくなります。プロジェクトに Microsoft.Windows.CppWinRT を導入しておくと、ソリューション全体で生成ツールとインクルードの挙動が揃い、“見える世界” と “ビルドの世界” の差が小さくなります。
よくあるつまずきと落とし穴(実践ノウハウ)
- (落とし穴)STA でなく MTA にしてしまう: XAML は STA が前提です。
init_apartment()を UI スレッド先頭で呼びます。 - interop の大文字小文字: Windows はファイル名の大文字小文字に寛容ですが、正しい識別のため
windows.ui.xaml.hosting.desktopwindowxamlsource.hの表記を守りましょう。 - WinUI 3 と混同: XAML Islands は
Windows.UI.Xaml系。Microsoft.UI.Xaml(WinUI 3 / Windows App SDK)とは別系統です。このページの手順は Islands 向けです。 - 生成物をソース管理に入れる: 投影ヘッダーは生成物です。通常はリポジトリに含めません。
- 複数プロジェクトの相互参照: .winmd を参照する順序や依存関係で生成順が前後する場合、Rebuild で解消することがあります。
“欠けているヘッダーを追加したい” と感じたら読む確認項目
- 本当に必要な機能か: XAML Islands の基本 UI(Button、TextBlock、Grid 等)は
Windows.UI.Xamlの投影ヘッダーだけで足ります。 - interop だけ特別:
DesktopWindowXamlSourceまわりの COM インターフェイスは投影外。windows.ui.xaml.hosting.desktopwindowxamlsource.hを素直に使う。 - 生成ヘッダーの起点: 使いたい API の .winmd が参照されているか確認。プロジェクト設定や NuGet の参照ミスで生成対象から外れていないかを見直す。
ビルドログで cppwinrt.exe の実行を確認する
原因切り分けの最短ルートは、詳細ログで cppwinrt.exe の呼び出しを確認することです。MSBuild の出力レベルを「詳細」に上げてビルドすると、コマンドラインと生成先が表示され、.winmd → winrt ヘッダー生成の流れが追えます。ここに出てこない場合は、参照の不足またはビルド ターゲットの無効化が疑われます。
CMake プロジェクトの場合の要点
- コンパイル オプション:
/std:c++20を設定。必要に応じて/permissive-、/bigobj。 - リンク:
windowsapp.libを明示。 - 生成: CMake では Microsoft.Windows.CppWinRT のパッケージ連携や
cppwinrtのカスタムコマンドで .winmd から投影を生成する手もあります。最初は Visual Studio の MSBuild プロジェクトで流れを掴むとスムーズです。
デバッグ時のチェックポイント
- 初期化順番:
init_apartment()→WindowsXamlManager::InitializeForCurrentThread()→DesktopWindowXamlSource→AttachToWindow→get_WindowHandle→Contentの順を崩さない。 - ウィンドウ サイズ:
WM_SIZEで子 HWND(XAML Island)のサイズを親クライアント領域に追従させる。 - 破棄順: Island の HWND を破棄する前に XAML コンテンツの参照を外すと安全。
よくある質問(FAQ)
Q. UwpApplication.h を見つけたいのですが?
A. XAML Islands の現行手順では不要です。古いサンプルが用いているだけで、10.0.26100.0 で「消えた」わけではありません。削除して前述の最小インクルードに置き換えるのが最短です。
Q. ビルドは通るのにエディタだけ赤いのはバグですか?
A. 多くは IntelliSense のキャッシュ未更新です。Rescan Solution とクリーン/再ビルドで改善します。NuGet の導入で生成ツールの版を統一するのも有効です。
Q. DesktopWindowXamlSource が見つからない/未定義になります。
A. winrt/Windows.UI.Xaml.Hosting.h(投影)と windows.ui.xaml.hosting.desktopwindowxamlsource.h(interop)の両方が必要です。片方だけでは不足します。
Q. WinUI 3(Microsoft.UI.Xaml)の Islands にも同じですか?
A. 本記事は Windows.UI.Xaml ベースの XAML Islands を前提にしています。WinUI 3/Windows App SDK とは仕組み・パッケージが異なるため、手順も異なります。
トラブルを未然に防ぐチェックリスト(配布用)
- [ ] UwpApplication.h をインクルードしていない
- [ ] interop は
windows.ui.xaml.hosting.desktopwindowxamlsource.h - [ ] ビルド後に Rescan Solution を実施
- [ ] NuGet: Microsoft.Windows.CppWinRT を導入
- [ ] リンク: windowsapp.lib を追加
- [ ] COM アパートメントは STA(
init_apartment())
まとめ
Windows SDK 10.0.26100.0 の環境で「ヘッダーが無い」と見える問題の正体は、SDK 欠落ではなく生成ヘッダーの扱いと interop/投影の取り違えです。不要な UwpApplication.h を外し、正しいインクルードに修正し、一度ビルド→Rescan Solution。さらに Microsoft.Windows.CppWinRT でツールチェーンを揃えれば、XAML Islands の導入は滑らかに進みます。上のサンプルとチェックリストを土台に、必要な UI 要素(Windows.UI.Xaml.Controls のほか Controls.Primitives、Windows.UI.Popups など)を目的に応じて追加していけば、Win32 C++ から安全に XAML をホストできます。
付録:用途別の追加インクルード例
| 用途 | 追加インクルード | 備考 |
|---|---|---|
| ボタンの詳細(ToggleButton 等) | #include <winrt/Windows.UI.Xaml.Controls.Primitives.h> | Primitives 系コントロール |
| コンテンツ ダイアログ | #include <winrt/Windows.UI.Xaml.Controls.h> | ContentDialog は Controls 内 |
| ポップアップ | #include <winrt/Windows.UI.Popups.h> | MessageDialog 等 |
| メディア関係 | #include <winrt/Windows.UI.Xaml.Media.h> | Brush、Transform など |
付録:プロパティシートのおすすめ設定
- 全般 > Windows SDK Version: 10.0.26100.0
- C/C++ > 言語: C++ 言語標準 C++20、モジュール未使用なら特に設定不要
- リンカー > 入力: 追加の依存ファイルに
windowsapp.libを追加 - 高度な設定: 最適化や
/DEBUG:FASTLINKは任意
これだけ覚える(要点の再掲)
- UwpApplication.h は使わない(削除)。
- interop は
windows.ui.xaml.hosting.desktopwindowxamlsource.h、投影はwinrt/Windows.UI.Xaml.*。 - ビルド後に Rescan Solution(IntelliSense を信じ過ぎない)。
- NuGet で C++/WinRT を揃える(ツールの版ズレをなくす)。
windowsapp.libをリンク(典型的なリンク エラー回避)。- STA(
init_apartment())で始める(XAML の大前提)。

コメント