C++/WinRT に関する問題のトラブルシューティング

注意

C++/WinRT Visual Studio Extension (VSIX) (プロジェクト テンプレート サポートを提供) のインストールと使用については、C++/WinRT の Visual Studio サポートに関するページをご覧ください。

このトピックは、すぐに認識していただくための先行情報です。まだ情報を必要としていない場合にも役立ちます。 症状のトラブルシューティングおよび対処法に関する以下の表は、新しいコードを作成しているか既存のアプリを移植しているかにはかかわらず役立つ可能性があります。 移植中であり、進展させてプロジェクトのビルドおよび実行の段階に達することを急いでいる場合は、問題を引き起こしている重要でないコードをコメントアウトまたはスタブアウトして、一時的に進展させることができます。その後、元に戻って、未処理の作業を完了させます。

よく寄せられる質問の一覧については、よく寄せられる質問に関する記事をご覧ください。

XAML に関する問題の検出

XAML 解析例外は診断が難しい場合があります。特に、わかりやすいエラー メッセージが例外に含まれていない場合は、診断が難しくなります。 デバッガーが初回例外をキャッチするように構成されていることを確認してください (早い段階で解析例外のキャッチを試行するため)。 デバッガーで例外変数を調べて、HRESULT やメッセージ内に有用な情報があるかどうかを確認できます。 また、XAML パーサーを使って、Visual Studio の出力ウィンドウを調べて、エラー メッセージの出力を確認することもできます。

アプリが終了し、XAML マークアップの解析中に処理不能な例外がスローされたことのみがわかっている場合は、存在しないリソースへの (キーによる) 参照の結果である可能性があります。 または、UserControl、カスタム コントロール、カスタム レイアウト パネルの内部で例外がスローされたことも考えられます。 最終手段として、バイナリ分割を使うことができます。 XAML ページからマークアップのおよそ半分を削除し、アプリを再実行します。 これによって、エラーが削除した半分で発生しているか (いずれの場合でも、削除した部分はここで元に戻す必要があります)、または削除しなかった半分で発生しているかがわかります。 問題が特定されるまで、エラーを含む半分をさらに分割するプロセスを繰り返します。

症状と解決方法

症状 修正
実行時に REGDB_E_CLASSNOTREGISTERED の HRESULT 値で例外がスローされます。 "クラスが登録されていません" という例外が発生するのはなぜですか?」を参照してください。
C++ コンパイラが、"'implements_type': は、'<プロジェクションされた型>' の直接的または間接的な基底クラスのメンバーではありません" というエラーを生成します。 これは、実装型 (たとえば MyRuntimeClass) の未修飾名前空間名を使用して、その型のヘッダーを含めずに make を呼び出すと発生する可能性があります。 コンパイラは、MyRuntimeClass をプロジェクションされた型として解釈します。 解決策は、実装型のヘッダーを含めることです (たとえば MyRuntimeClass.h)。
C++ コンパイラが、"削除された関数を参照しようとしています" というエラーを生成します。 これは、make を呼び出し、テンプレート パラメーターとして渡す実装型の既定のコンストラクターが = delete である場合に発生する可能性があります。 実装型のヘッダー ファイルを編集し、 = delete= default に変更してください。 ランタイム クラスの IDL にコンストラクターを追加することもできます。
INotifyPropertyChanged を実装しましたが、XAML バインドが更新されません (そのため、UI が PropertyChanged にサブスクライブしません)。 XAML マークアップのバインド式で必ず Mode=OneWay (または TwoWay) を設定してください。 「XAML コントロール: C++/WinRT プロパティへのバインド」を参照してください。
XAML アイテム コントロールを監視可能なコレクションにバインドしていますが、実行時に "パラメーターが正しくありません" というメッセージで例外がスローされます。 IDL および実装で、監視可能なコレクションを型 Windows.Foundation.Collections.IVector<IInspectable> として宣言します。 ただし、Windows.Foundation.Collections.IObservableVector<T> を実装するオブジェクトを返します。T は要素型です。 「XAML アイテム コントロール: C++/WinRT コレクションへのバインド」を参照してください。
C++ コンパイラが、"'MyImplementationType_base<MyImplementationType>': 使用可能な適切な既定コンストラクターがありません" という形式のエラーを生成します。 これは、非自明なコンストラクターを持つ型から派生させた場合に発生する可能性があります。 派生型のコンストラクターは、基本型のコンストラクターが必要とするパラメーターを渡す必要があります。 実証済みの例については、「非自明なコンストラクターを持つ型からの派生」を参照してください。
C++ コンパイラが、「'const std::vector<std::wstring,std::allocator<_Ty>>' から 'const winrt::param::async_iterable<winrt::hstring> &' に変換できません」というエラーを生成します。 これは、コレクションを予期している Windows ランタイム API に std::wstring の std::vector を渡すときに発生する可能性があります。 詳細については、「標準的な C++ のデータ型と C++/WinRT」を参照してください。
C++ コンパイラが、「'const std::vector<winrt::hstring,std::allocator<_Ty>>' から 'const winrt::param::async_iterable<winrt::hstring> &' に変換できません」というエラーを生成します。 これは、コレクションを予期している非同期 Windows ランタイム API に winrt::hstring の std::vector を渡すときに、非同期呼び出し先へのベクトルのコピーも移動も行っていない場合に発生する可能性があります。 詳細については、「標準的な C++ のデータ型と C++/WinRT」を参照してください。
プロジェクトを開くときに、Visual Studio が "プロジェクトのアプリケーションはインストールされていません" というエラーを生成します。 まだ行っていない場合は、Visual Studio の [新しいプロジェクト] ダイアログから C++ での開発用の Windows ユニバーサル ツールをインストールする必要があります。 それでも問題が解決しない場合は、プロジェクトが C++/WinRT Visual Studio Extension (VSIX) に依存している可能性があります (C++/WinRT の Visual Studio サポートに関するページを参照してください)。
Windows アプリ認定キットのテストで、ランタイム クラスの 1 つについて、次のようなエラーが発生します。"Windows 基底クラスから派生しません。すべての構成可能クラスは最終的に、Windows 名前空間内の型から派生する必要があります"。 基底クラスから派生する任意のランタイム クラス (アプリケーション内で宣言) は構成可能クラスと呼ばれます。 構成可能クラスの最終的な基底クラスは、Windows.* 名前空間からの型でなければなりません (例: Windows.UI.Xaml.DependencyObject)。 詳細情報については、「XAML コントロール: C++/WinRT プロパティへのバインド」を参照してください。
C++ コンパイラにより、EventHandler または TypedEventHandler のデリゲート特殊化に関して "T は WinRT 型である必要があります" というエラーが生成されます。 代わりに winrt::d elegate< ..T> を使用することを考慮してください。 「C++/WinRT でのイベントの作成」を参照してください。
C++ コンパイラにより、Windows ランタイムの非同期操作の特殊化に関して "T は WinRT 型である必要があります" というエラーが生成されます。 代わりに、並列パターン ライブラリ (PPL) の task を返すことを考慮してください。 「同時実行操作と非同期操作」を参照してください。
winrt::xaml_typename を呼び出すと、C++ コンパイラによって "T は WinRT 型である必要があります" というエラーが生成されます。 winrt::xaml_typename により、投影された型を使用し (たとえば BgLabelControlApp::BgLabelControl を使用する)、実装型を使用しないようにします (たとえば BgLabelControlApp::implementation::BgLabelControl を使用しない)。 XAML カスタム (テンプレート化) コントロールに関するページをご覧ください。
C++ コンパイラが、"エラー C2220: 警告がエラーとして扱われました - 'オブジェクト' ファイルは生成されませんでした" を生成します。 警告を解決するか、または[C/C++]>[全般]>[警告をエラーとして扱う][いいえ (/WX-)] に設定します。
オブジェクトが破棄された後で C++/WinRT オブジェクトのイベント ハンドラーが呼び出されるため、アプリがクラッシュします。 イベント処理デリゲートで this ポインターに安全にアクセスする」を参照してください。
C++ コンパイラが、 "error C2338: これは弱参照サポート専用です" を生成します。 テンプレート引数として winrt::no_weak_ref マーカー構造体を基底クラスに渡した型の弱参照を要求しています。 「弱参照サポートの除外」を参照してください。
C++ コンパイラーにより、"consume_Something: 'auto' を返す関数を、定義より前に使用することはできません" が生成されます。 C3779: コンパイラーに "consume_Something: 'auto' を返す関数を、定義より前に使用することはできません" というエラーが発生するのはなぜですか。」を参照してください。
C++ リンカーで次のエラーが発生します。"エラー LNK2019: 外部シンボルは未解決です" リンカーで "LNK2019: 外部シンボルは未解決です" というエラーが発生するのはなぜですか?」を参照してください。
C++/WinRT と共に使用した場合、LLVM と Clang のツールチェーンでエラーが生成されます。 C++/WinRT では LLVM と Clang のツールチェーンはサポートされていませんが、内部でどのように使用されているかエミュレートしたい場合は、「LLVM/Clang を使用して C++/WinRT でコンパイルすることはできますか」に記載されているような実験を試してみることができます。
C++ コンパイラーで、投影された型に対して "既定のコンストラクターがありません" が生成されます。 ランタイム クラス オブジェクトの初期化を遅らせたり、同じプロジェクト内のランタイム クラスを使用および実装したりしようとしている場合は、std::nullptr_t コンストラクターを呼び出す必要があります。 詳細については、「C++/WinRT での API の使用」を参照してください。
C++ コンパイラで、"エラー C3861: 'from_abi': 識別子が見つかりません" と、base.h から発生する他のエラーが生成されます。 このエラーは、Visual Studio 2017 (バージョン 15.8.0 以上) を使用しており、Windows SDK バージョン 10.0.17134.0 (Windows 10 バージョン 1803) を対象としている場合に発生することがあります。 Windows SDK のより新しい (より準拠度の高い) バージョンを対象とするか、プロジェクト プロパティ [C/C++]>[言語]>[準拠モード:いいえ] に設定します (また、/permissive- がプロジェクト プロパティ [C/C++]>[言語]>[コマンド ライン] ([追加オプション] の下) に表示される場合は、削除してください)。
C++ コンパイラで "エラー C2039: 'IUnknown': は '`グローバル名前空間'' のメンバーではありません" が生成されます。 C++/WinRT プロジェクトのターゲットを Windows SDK のより新しいバージョンに変更する方法」を参照してください。
C++ リンカーで "エラー LNK2019: 未解決の外部シンボル _WINRT_CanUnloadNow@0 が関数 _VSDesignerCanUnloadNow@0 で参照されました" が生成されます。 C++/WinRT プロジェクトのターゲットを Windows SDK のより新しいバージョンに変更する方法」を参照してください。
ビルド プロセスで、エラー メッセージ "The C++/WinRT VSIX no longer provides project build support. Please add a project reference to the Microsoft.Windows.CppWinRT Nuget package" (C++/WinRT VSIX ではもうプロジェクト ビルド ポートは提供されていません。Microsoft.Windows.CppWinRT Nuget パッケージにプロジェクト参照を追加してください) が生成されます。 Microsoft.Windows.CppWinRT NuGet パッケージを自分のプロジェクトにインストールします。 詳細については、「VSIX 拡張機能の以前のバージョン」を参照してください。
C++ リンカーが、winrt::impl::consume_Windows_Foundation_Collections_IVector に言及して、"エラー LNK2019: 外部シンボルは未解決です" を生成します。 C++/WinRT 2.0 の時点で、Windows Runtime コレクションで範囲ベースの for を使用している場合は、#include <winrt/Windows.Foundation.Collections.h> を実行する必要があります。
C++ コンパイラで次のエラーが発生します。"エラー C4002: 関数に似たマクロ呼び出し 'GetCurrentTime' の引数が多すぎます"。 GetCurrentTime および TRY でのあいまいさを解決するにはどうすればよいですか?」を参照してください。
C++ コンパイラで次のエラーが発生します。"エラー C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます"。 GetCurrentTime および TRY でのあいまいさを解決するにはどうすればよいですか?」を参照してください。
C++ コンパイラで次のエラーが発生します。"winrt::impl::produce<D,I> cannot instantiate abstract class, due to missing GetBindingConnector" ('winrt::impl::produce': GetBindingConnector がないため、抽象クラスをインスタンス化できません)。 #include <winrt/Windows.UI.Xaml.Markup.h> が必要です。
C++ コンパイラが、"エラー C2039: 'promise_type': 'std::experimental::coroutine_traits<void>' のメンバーではありません" というエラーを生成します。 コルーチンでは、非同期操作オブジェクトまたは winrt::fire_and_forget を返す必要があります。 「同時実行操作と非同期操作」を参照してください。
プロジェクトで "'PopulatePropertyInfoOverride' へのアクセスがあいまいです" が発生します。 このエラーは、IDL で宣言した 1 つの基底クラスが XAML マークアップの基底クラスと異なると、発生する場合があります。
C++/WinRT ソリューションを初めて読み込むと、"プロジェクト 'MyProject.vcxproj'、構成 'Debug|x86' のデザイン時のビルドに失敗しました。IntelliSense が使用できない可能性があります。" というエラーが発生します。 この IntelliSense の問題は、初めてのビルドの後で解決されます。
デリゲートを登録するときに winrt::auto_revoke を指定しようとすると、winrt::hresult_no_interface 例外が発生します。 自動取り消しのデリゲートの登録が失敗する場合」を参照してください。
C++/WinRT アプリで、XAML を使用する C# Windows ランタイム コンポーネントを使用すると、"'MyNamespace_XamlTypeInfo' は 'winrt::MyNamespace' のメンバーではありません" という形式のエラーがコンパイラによって生成されます。"この MyNamespace" は、Windows ランタイム コンポーネントの名前空間の名前です。 使用する側の C++/WinRT アプリの pch.h で、#include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h> を追加します。必要に応じて "MyNamespace" を置き換えます。
Visual Studio の C++/WinRT プロジェクトでは、IntelliSense によって "エラー E1696: ソース ファイルを開くことができません" という形式のエラーが生成されます。 新しく作成したプロジェクトを少なくとも 1 回コンパイルしてください。 次に、ソース コード エディターの [再スキャン] を右クリックし、[ファイルの再スキャン] を選びます。 これにより、E1696 を含むすべての IntelliSense エラーが解決されます。

注意

このトピックで質問の答えが見つからなかった場合は、Visual Studio C++ 開発者コミュニティにアクセスするか、c++-winrt タグを Stack Overflow で使用することでヘルプが得られる場合があります。