針對 C++/WinRT 問題進行疑難排解Troubleshooting C++/WinRT issues

注意

如需安裝和使用 C++/WinRT Visual Studio 延伸模組 (VSIX) (提供專案範本支援) 的資訊,請參閱 C++/WinRT 的 Visual Studio 支援For info about installing and using the C++/WinRT Visual Studio Extension (VSIX) (which provides project template support) see Visual Studio support for C++/WinRT.

本主題是預先準備,這樣您就會立即知道;即使您還不需要。This topic is up front so that you're aware of it right away; even if you don't need it yet. 無論您是剪下新的程式碼或移植現有的應用程式,下面的疑難排解問題和解決方式表格可能對您會很有幫助。The table of troubleshooting symptoms and remedies below may be helpful to you whether you're cutting new code or porting an existing app. 如果您正在移植,且您急著想要儘快進入建置及執行專案的階段,您可以暫時將任何非必要的程式碼標成註解或移除,稍後再回來解決。If you're porting, and you're eager to forge ahead and get to the stage where your project builds and runs, then you can make temporary progress by commenting or stubbing out any non-essential code that's causing issues, and then returning to pay off that debt later.

如需常見問題清單,請參閱常見問題集For a list of frequently-asked questions, see Frequently-asked questions.

追蹤 XAML 問題Tracking down XAML issues

XAML 剖析例外狀況可能難以診斷 — 特別是如果例外狀況中的錯誤訊息沒有意義。XAML parse exceptions can be difficult to diagnose—particularly if there are no meaningful error messages within the exception. 請確定偵錯工具已設定為擷取第一個可能發生的例外狀況 (以嘗試並擷取早期剖析例外狀況)。Make sure that the debugger is configured to catch first-chance exceptions (to try and catch the parsing exception early on). 您可以在偵錯工具檢查例外狀況變數,以判斷 HRESULT 或訊息是否有任何有用的資訊。You may be able to inspect the exception variable in the debugger to determine whether the HRESULT or message has any useful information. 同時檢查 Visual Studio 的輸出視窗當中是否有 XAML 剖析器輸出的錯誤訊息。Also, check Visual Studio's output window for error messages output by the XAML parser.

如果您的應用程式終止,而您知道的唯一事項是在 XAML 標記剖析期間擲回未處理的例外狀況,則有可能是所參考 (藉由索引鍵) 的資源遺失的結果。If your app terminates and all you know is that an unhandled exception was thrown during XAML markup parsing, then that could be the result of a reference (by key) to a missing resource. 或者,可能是在 UserControl、自訂控制項或自訂版面配置面板內擲回例外狀況。Or, it could be an exception thrown inside a UserControl, a custom control, or a custom layout panel. 真的別無他法時,才採用二元分割法。A last resort is a binary split. 從「XAML 頁面」移除一半的標記,然後重新執行應用程式。Remove about half of the markup from a XAML Page and re-run the app. 這樣您就會知道錯誤是出在您所移除的那半部內 (無論如何,您現在都應該還原這個部分),還是出在您「未」移除的那半部內。You will then know whether the error is somewhere inside the half you removed (which you should now restore in any case) or in the half you did not remove. 不斷針對包含錯誤的那一半重複分割程序,直到您準確找出問題為止。Repeat the process by splitting the half that contains the error, and so on, until you've zeroed in on the issue.

徵兆和解決方式Symptoms and remedies

徵狀Symptom 補救方法Remedy
在執行階段期間擲回例外狀況,其 HRESULT 值為 REGDB_E_CLASSNOTREGISTERED。An exception is thrown at runtime with a HRESULT value of REGDB_E_CLASSNOTREGISTERED. 請參閱為什麼我會收到「類別未註冊」的例外狀況?See Why am I getting a "class not registered" exception?.
C++ 編譯器產生錯誤「'implements_type': 不是 '<投影類型>' 任何直接或間接基底類別的成員**」。The C++ compiler produces the error "'implements_type': is not a member of any direct or indirect base class of '<projected type>'". 您呼叫 make 實作類型的不完整命名空間名稱 (例如,MyRuntimeClass),且您尚未包含該類型的標頭時,便會發生此情況。This can happen when you call make with the namespace-unqualified name of your implementation type (MyRuntimeClass, for example), and you haven't included that type's header. 編譯器解譯 MyRuntimeClass 作為投影型別。The compiler interprets MyRuntimeClass as the projected type. 解決方案會為您的實作類型包含標頭 (例如,MyRuntimeClass.h)。The solution is to include the header for your implementation type (MyRuntimeClass.h, for example).
C++ 編譯器產生錯誤「嘗試參考被刪除的函式**」。The C++ compiler produces the error "attempting to reference a deleted function". 當您呼叫 make 且您作為範本參數傳遞的實作類型有 = delete 預設建構函式時,便會發生此情況。This can happen when you call make and the implementation type that you pass as the template parameter has an = delete default constructor. 編輯實作類型的標頭檔案,並將 = delete 變更為 = defaultEdit the implementation type's header file and change = delete to = default. 您也可以將建構函式新增至適用於執行階段類別的 IDL。You can also add a constructor into the IDL for the runtime class.
您已實作 INotifyPropertyChanged,但您的 XAML 繫結未更新 (且 UI 未訂閱 PropertyChanged)。You've implemented INotifyPropertyChanged, but your XAML bindings are not updating (and the UI is not subscribing to PropertyChanged). 請記得在 XAML 標記中的繫結運算式上設定 Mode=OneWay (或 TwoWay)。Remember to set Mode=OneWay (or TwoWay) on your binding expression in XAML markup. 請參閱 XAML 控制項;繫結一個 C++/WinRT 屬性See XAML controls; bind to a C++/WinRT property.
您把 XAML 項目控制項繫結到可觀察的集合,且在執行階段擲回例外狀況與訊息「參數不正確」。You're binding a XAML items control to an observable collection, and an exception is thrown at runtime with the message "The parameter is incorrect". 在您的 IDL 和實作中,宣告任何可觀察的集合作為類型 Windows.Foundation.Collections.IVectorIn your IDL and your implementation, declare any observable collection as the type Windows.Foundation.Collections.IVector. 但傳回實作 Windows.Foundation.Collections.IObservableVector 的物件,其中 T 為您的元素類型。But return an object that implements Windows.Foundation.Collections.IObservableVector, where T is your element type. 請參閱 XAML 項目控制項;繫結至 C++/WinRT 集合See XAML items controls; bind to a C++/WinRT collection.
C++ 編譯器產生一個錯誤的表單「'MyImplementationType_base<MyImplementationType>': 沒有適當的預設建構函式**」。The C++ compiler produces an error of the form "'MyImplementationType_base<MyImplementationType>': no appropriate default constructor available". 當您衍生自具有非一般建構函式的類型時,可能會發生這種情形。This can happen when you have derived from a type that has a non-trivial constructor. 您衍生的類型建構函式必須與需要基本類型建構函式的參數一起傳遞。Your derived type's constructor needs to pass along the parameters that the base type's constructor needs. 如需一個已執行的範例,請參閱從非一般建構函式衍生For a worked example, see Deriving from a type that has a non-trivial constructor.
C++ 編譯器產生錯誤「無法從 'const std::vector<std::wstring,std::allocator<_Ty>>' 轉換至 'const winrt::param::async_iterable<winrt::hstring> &'」。The C++ compiler produces the error "cannot convert from 'const std::vector<std::wstring,std::allocator<_Ty>>' to 'const winrt::param::async_iterable<winrt::hstring> &'". 您將 std::wstring 的 std::vector 傳遞到預期收到集合的 Windows 執行階段 API,便可能會發生此情況。This can happen when you pass a std::vector of std::wstring to a Windows Runtime API that expects a collection. 如需詳細資訊,請參閱標準 C++ 資料類型與 C++/WinRTFor more info, see Standard C++ data types and C++/WinRT.
C++ 編譯器產生錯誤「無法從 'const std::vector<winrt::hstring,std::allocator<_Ty>>' 轉換至 'const winrt::param::async_iterable<winrt::hstring> &'」。The C++ compiler produces the error "cannot convert from 'const std::vector<winrt::hstring,std::allocator<_Ty>>' to 'const winrt::param::async_iterable<winrt::hstring> &'". 當您將 winrt::hstring 的 std::vector 傳遞至預期收到集合的 Windows 執行階段 API 時,且您沒有將向量複製或移動到非同步被呼叫者,便會發生此情況。This can happen when you pass a std::vector of winrt::hstring to an asynchronous Windows Runtime API that expects a collection, and you've neither copied nor moved the vector to the async callee. 如需詳細資訊,請參閱標準 C++ 資料類型與 C++/WinRTFor more info, see Standard C++ data types and C++/WinRT.
開啟一個專案時,Visual Studio 產生此錯誤「未安裝專案的應用程式**」。When opening a project, Visual Studio produces the error "The application for the project is not installed". 如果您尚未開始,您需要從 Visual Studio 的 [新專案]**** 對話方塊中安裝 C++ 開發 Windows 通用工具If you haven't already, you need to install Windows Universal tools for C++ development from within Visual Studio's New Project dialog. 如果無法解決問題,則此專案可能相依於 C++/WinRT Visual Studio 擴充功能 (VSIX) (請參閱 C++/WinRT 的 Visual Studio 支援)。If that doesn't resolve the issue, then the project may depend on the C++/WinRT Visual Studio Extension (VSIX) (see Visual Studio support for C++/WinRT.
Windows 應用程式認證套件測試產生執行階段類別的錯誤之一「不是從 Windows 的基底類別衍生。所有可組合類別必須最終從 Windows 命名空間中的類別衍生」。The Windows App Certification Kit tests produce an error that one of your runtime classes "does not derive from a Windows base class. All composable classes must ultimately derive from a type in the Windows namespace". 從基底類別衍生的任何執行階段類別 (您在您的應用程式中宣告),都稱為「可組合」** 類別。Any runtime class (that you declare in your application) that derives from a base class is known as a composable class. 可組合類別的最終基底類別都必須是源自 Windows.* 命名空間的類別;例如,Windows.UI.Xaml.DependencyObjectThe ultimate base class of a composable class must be a type originating in a Windows.* namespace; for example, Windows.UI.Xaml.DependencyObject. 如需詳細資訊,請參閱 XAML 控制項;繫結至 C++/WinRT 屬性See XAML controls; bind to a C++/WinRT property for more details.
C++ 編譯器產生 EventHandler 或 TypedEventHandler 委派特製化的「T 必須為 WinRT 類型」錯誤。The C++ compiler produces a "T must be WinRT type" error for an EventHandler or TypedEventHandler delegate specialization. 請考慮改用 winrt::delegate<...T>Consider using winrt::delegate<...T> instead. 請參閱在 C++/WinRT 中撰寫事件See Author events in C++/WinRT.
C++ 編譯器產生 Windows 執行階段非同步作業特製化的「T 必須為 WinRT 類型」錯誤。The C++ compiler produces a "T must be WinRT type" error for a Windows Runtime asynchronous operation specialization. 請考慮改為傳回平行模式程式庫 (PPL) taskConsider returning a Parallel Patterns Library (PPL) task instead. 請參閱並行和非同步作業See Concurrency and asynchronous operations.
當您呼叫 winrt::xaml_typename時,C++ 編譯器會產生「T 必須為 WinRT 類型」錯誤。The C++ compiler produces a "T must be WinRT type" error when you call winrt::xaml_typename. 使用預估類型搭配 winrt::xaml_typename (例如,使用 BgLabelControlApp::BgLabelControl),而不是實作類型 (例如,請勿使用 BgLabelControlApp::implementation::BgLabelControl)。Use the projected type with winrt::xaml_typename (for example, use BgLabelControlApp::BgLabelControl), and not the implementation type(for example, don't use BgLabelControlApp::implementation::BgLabelControl). 請參閱 XAML 自訂 (範本化) 控制項See XAML custom (templated) controls.
C++ 編譯器產生「錯誤 C2220: 將警告視為錯誤處理 - 沒有產生 'object' 檔案**」。The C++ compiler produces "error C2220: warning treated as error - no 'object' file generated". 修正警告,或將 [C/C++] > [一般] > [將警告視為錯誤] 設定為 [否 (/WX-)]。Either correct the warning, or set C/C++ > General > Treat Warnings As Errors to No (/WX-).
您的應用程式當機,因為在終結物件後,呼叫了在 C++/WinRT 物件中處理的事件。Your app crashes because an event handler in your C++/WinRT object is called after the object has been destroyed. 請參閱使用事件處理委派安全地存取 this 指標See Safely accessing the this pointer with an event-handling delegate.
C++ 編譯器產生「錯誤 C2338:這僅適用於弱式參考資料支援」。The C++ compiler produces "error C2338: This is only for weak ref support". 您為將 winrt::no_weak_ref 標記結構作為範本引數傳遞至其基底類別的類型,要求一個弱式參考。You're requesting a weak reference for a type that passed the winrt::no_weak_ref marker struct as a template argument to its base class. 請參閱不使用弱式參考支援See Opting out of weak reference support.
C++ 連結器產生「錯誤 LNK2019:無法解析的外部符號」The C++ linker produces "error LNK2019: Unresolved external symbol" 請參閱為何連結器給我「LNK2019:無法解析的外部符號」錯誤?See Why is the linker giving me a "LNK2019: Unresolved external symbol" error?.
當 LLVM 和 Clang 工具鏈搭配使用 C++/WinRT 時,會產生錯誤。The LLVM and Clang toolchain produces errors when used with C++/WinRT. 針對 C++/WinRT,我們不支援 LLVM 和 Clang 工具鏈,但如果您想要模擬我們如何在內部使用它,則您可以嘗試實驗,如我可以使用 LLVM/Clang 來編譯 C++/WinRT 嗎?中所述的。We don't support the LLVM and Clang toolchain for C++/WinRT, but if you wanted to emulate how we use it internally, then you could try an experiment such as the one described in Can I use LLVM/Clang to compile with C++/WinRT?.
C++ 編譯器產生投影型別的「沒有適當的預設建構函式**」。The C++ compiler produces "no appropriate default constructor available" for a projected type. 如果您嘗試將執行階段類別物件的初始化延遲,或嘗試在相同專案中取用和實作執行階段類別,則您必須呼叫 std::nullptr_t 建構函式。If you're trying to delay the initialization of a runtime class object, or to consume and implement a runtime class in the same project, then you'll need to call the std::nullptr_t constructor. 如需詳細資訊,請參閱使用 C++/WinRT 取用 APIFor more info, see Consume APIs with C++/WinRT.
C++ 編譯器產生「錯誤 C3861: 'from_abi': 找不到識別碼**」,及其他源自 base.h 的錯誤。The C++ compiler produces "error C3861: 'from_abi': identifier not found", and other errors originating in base.h. 如果您是使用 Visual Studio 2017 (15.8.0 版或更新版本),且目標為 Windows SDK 10.0.17134.0 版 (Windows 10 1803 版),則您可能會看到此錯誤。You may see this error if you are using Visual Studio 2017 (version 15.8.0 or higher), and targeting the Windows SDK version 10.0.17134.0 (Windows 10, version 1803). 將 Windows SDK 的較新 (更一致) 版本設定為目標,或將專案屬性設定為 C/C++ > 語言 > 一致性模式:否 (此外,如果 /permissive- 顯示在專案屬性 C/C++ > 語言 > 命令列 的 其他選項 底下,請刪除它)。Either target a later (more conformant) version of the Windows SDK, or set project property C/C++ > Language > Conformance mode: No (also, if /permissive- appears in project property C/C++ > Language > Command Line under Additional Options, then delete it).
C++ 編譯器產生「錯誤 C2039:'IUnknown': 不是 '`global namespace'' 的成員」。The C++ compiler produces "error C2039: 'IUnknown': is not a member of '`global namespace''". 請參閱如何將您 C++/WinRT 專案的目標設定為 Windows SDK 的較新版本See How to retarget your C++/WinRT project to a later version of the Windows SDK.
C++ 連接器產生「錯誤 LNK2019: 無法解析的外部符號 _WINRT_CanUnloadNow@0 在函式 _VSDesignerCanUnloadNow@0 中被參考**」The C++ linker produces "error LNK2019: unresolved external symbol _WINRT_CanUnloadNow@0 referenced in function _VSDesignerCanUnloadNow@0" 請參閱如何將您 C++/WinRT 專案的目標設定為 Windows SDK 的較新版本See How to retarget your C++/WinRT project to a later version of the Windows SDK.
建置程序會產生錯誤訊息「C++/WinRT VSIX 不再提供專案的建置支援。請將專案參考加入 Microsoft.Windows.CppWinRT Nuget 套件」。The build process produces the error message The C++/WinRT VSIX no longer provides project build support. Please add a project reference to the Microsoft.Windows.CppWinRT Nuget package. Microsoft.Windows.CppWinRT NuGet 套件安裝到您的專案中。Install the Microsoft.Windows.CppWinRT NuGet package into your project. 如需詳細資訊,請參閱舊版 VSIX 擴充功能For details, see Earlier versions of the VSIX extension.
C++ 連接器產生「錯誤 LNK2019: 無法解析的外部符號」**,包含提及 winrt::impl::consume_Windows_Foundation_Collections_IVectorThe C++ linker produces error LNK2019: unresolved external symbol, with a mention of winrt::impl::consume_Windows_Foundation_Collections_IVector. C++/WinRT 2.0,如果您在 Windows 執行階段集合上使用範圍型 for,則您現在必須 #include <winrt/Windows.Foundation.Collections.h>As of C++/WinRT 2.0, If you're using a range-based for on a Windows Runtime collection, then you'll now need to #include <winrt/Windows.Foundation.Collections.h>.
C++ 編譯器產生「錯誤 C4002:函式類巨集引動過程 GetCurrentTime 有太多引數」。The C++ compiler produces "error C4002: Too many arguments for function-like macro invocation GetCurrentTime". 請參閱如何解決 GetCurrentTime 和/或 TRY 意義不明的狀況?See How do I resolve ambiguities with GetCurrentTime and/or TRY?.
C++編譯器會產生「錯誤 C2334:'{' 前面有非預期的權杖;略過顯示的函式主體**」。The C++ compiler produces "error C2334: unexpected token(s) preceding '{'; skipping apparent function body". 請參閱如何解決 GetCurrentTime 和/或 TRY 意義不明的狀況?See How do I resolve ambiguities with GetCurrentTime and/or TRY?.
C++編譯器會產生「winrt::impl::produce<D,I> 無法具現化抽象類別,因為遺漏 GetBindingConnector**」。The C++ compiler produces "winrt::impl::produce<D,I> cannot instantiate abstract class, due to missing GetBindingConnector". 您需要 #include <winrt/Windows.UI.Xaml.Markup.h>You need to #include <winrt/Windows.UI.Xaml.Markup.h>.
C++ 編譯器會產生「錯誤 C2039:'promise_type': 不是 'std::experimental::coroutine_traits' 的成員**」。The C++ compiler produces "error C2039: 'promise_type': is not a member of 'std::experimental::coroutine_traits'". 您的協同程式需要傳回非同步作業物件或 winrt::fire_and_forgetYour coroutine needs to return either an asynchronous operation object, or winrt::fire_and_forget. 請參閱並行和非同步作業See Concurrency and asynchronous operations.
您的專案會產生「模稜兩可的 'PopulatePropertyInfoOverride' 存取**」。Your project produces "ambiguous access of 'PopulatePropertyInfoOverride'". 當您在 IDL 中宣告一個基底類別,並在 XAML 標記中宣告不同基底類別時,就會發生此錯誤。This error can occur when you declare one base class in your IDL and a different base class in your XAML markup.
第一次載入 C++/WinRT 解決案會產生「專案 'MyProject.vcxproj' 組態 'Debug|x86' 的 Designtime 建置失敗。IntelliSense 可能無法使用。Loading a C++/WinRT solution for the first time produces "Designtime build failed for project 'MyProject.vcxproj' configuration 'Debug|x86'. IntelliSense might be unavailable.". 經過第一次建置之後,此 IntelliSense 問題就會解決。This IntelliSense issue will resolve after you build for the first time.
註冊委派時嘗試指定 winrt::auto_revoke 會產生 winrt::hresult_no_interface 例外狀況。Attempting to specify winrt::auto_revoke when registering a delegate produces a winrt::hresult_no_interface exception. 請參閱如果您的自動撤銷委派無法註冊See If your auto-revoke delegate fails to register.
在 C++/WinRT 應用程式中,當取用一個使用 XAML 的 C# Windows 執行階段元件時,編譯器會產生格式為 " 'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace' "—其中 MyNamespace 是 Windows 執行階段元件命名空間的名稱。In a C++/WinRT app, when consuming a C# Windows Runtime component that uses XAML, the compiler produces an error of the form "'MyNamespace_XamlTypeInfo': is not a member of 'winrt::MyNamespace'"—where MyNamespace is the name of the Windows Runtime component's namespace. 在取用 C++/WinRT 應用程式的 pch.h 中,視適當情況新增 #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—取代 MyNamespaceIn pch.h in the consuming C++/WinRT app, add #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—replacing MyNamespace as appropriate.

注意

如果本主題無法解答您的問題,則您可藉由造訪 Visual Studio C++ 開發人員社群,或在 Stack Overflow 上使用 c++-winrt 標籤來尋找說明。If this topic didn't answer your question, then you might find help by visiting the Visual Studio C++ developer community, or by using the c++-winrt tag on Stack Overflow.