Bewerken

Delen via


Troubleshooting C++/WinRT issues

Note

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.

Tracking down XAML issues

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). You may be able to inspect the exception variable in the debugger to determine whether the HRESULT or message has any useful information. Also, check Visual Studio's output window for error messages output by the XAML parser.

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. 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. 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
An exception is thrown at runtime with a HRESULT value of REGDB_E_CLASSNOTREGISTERED. See Why am I getting a "class not registered" exception?.
The C++ compiler produces the error "'implements_type': is not a member of any direct or indirect base class of '<projected type>'". 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. The compiler interprets MyRuntimeClass as the projected type. The solution is to include the header for your implementation type (MyRuntimeClass.h, for example).
The C++ compiler produces the error "attempting to reference a deleted function". This can happen when you call make and the implementation type that you pass as the template parameter has an = delete default constructor. Edit the implementation type's header file and change = delete to = default. You can also add a constructor into the IDL for the runtime class.
You've implemented INotifyPropertyChanged, but your XAML bindings are not updating (and the UI is not subscribing to PropertyChanged). Remember to set Mode=OneWay (or TwoWay) on your binding expression in XAML markup. See XAML controls; bind to a C++/WinRT property.
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". In your IDL and your implementation, declare any observable collection as the type Windows.Foundation.Collections.IVector<IInspectable>. But return an object that implements Windows.Foundation.Collections.IObservableVector<T>, where T is your element type. See XAML items controls; bind to a C++/WinRT collection.
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.
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> &'". This can happen when you pass a std::vector of std::wstring to a Windows Runtime API that expects a collection. For more info, see Standard C++ data types and C++/WinRT.
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> &'". 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. For more info, see Standard C++ data types and C++/WinRT.
When opening a project, Visual Studio produces the error "The application for the project is not installed". If you haven't already, you need to install Windows Universal tools for C++ development from within Visual Studio's New Project dialog. 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.
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. The ultimate base class of a composable class must be a type originating in a Windows.* namespace; for example, Windows.UI.Xaml.DependencyObject. See XAML controls; bind to a C++/WinRT property for more details.
The C++ compiler produces a "T must be WinRT type" error for an EventHandler or TypedEventHandler delegate specialization. Consider using winrt::delegate<...T> instead. See Author events in C++/WinRT.
The C++ compiler produces a "T must be WinRT type" error for a Windows Runtime asynchronous operation specialization. Consider returning a Parallel Patterns Library (PPL) task instead. See Concurrency and asynchronous operations.
The C++ compiler produces a "T must be WinRT type" error when you call winrt::xaml_typename. 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). See XAML custom (templated) controls.
The C++ compiler produces "error C2220: warning treated as error - no 'object' file generated". Either correct the warning, or set C/C++ > General > Treat Warnings As Errors to No (/WX-).
Your app crashes because an event handler in your C++/WinRT object is called after the object has been destroyed. See Safely accessing the this pointer with an event-handling delegate.
The C++ compiler produces "error C2338: This is only for weak ref support". 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.
The C++ compiler produces "consume_Something: function that returns 'auto' cannot be used before it is defined" See C3779: Why is the compiler giving me a "consume_Something: function that returns 'auto' cannot be used before it is defined" error?.
The C++ linker produces "error LNK2019: Unresolved external symbol" See Why is the linker giving me a "LNK2019: Unresolved external symbol" error?.
The LLVM and Clang toolchain produces errors when used with 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?.
The C++ compiler produces "no appropriate default constructor available" for a projected type. 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. For more info, see Consume APIs with C++/WinRT.
The C++ compiler produces "error C3861: 'from_abi': identifier not found", and other errors originating in base.h. You may see this error if you are using Visual Studio 2017 (version 15.8.0 or later), and targeting the Windows SDK version 10.0.17134.0 (Windows 10, version 1803). 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).
The C++ compiler produces "error C2039: 'IUnknown': is not a member of '`global namespace''". See How to retarget your C++/WinRT project to a later version of the Windows SDK.
The C++ linker produces "error LNK2019: unresolved external symbol _WINRT_CanUnloadNow@0 referenced in function _VSDesignerCanUnloadNow@0" See How to retarget your C++/WinRT project to a later version of the Windows SDK.
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. Install the Microsoft.Windows.CppWinRT NuGet package into your project. For details, see Earlier versions of the VSIX extension.
The C++ linker produces error LNK2019: unresolved external symbol, with a mention of winrt::impl::consume_Windows_Foundation_Collections_IVector. 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>.
The C++ compiler produces "error C4002: Too many arguments for function-like macro invocation GetCurrentTime". See How do I resolve ambiguities with GetCurrentTime and/or TRY?.
The C++ compiler produces "error C2334: unexpected token(s) preceding '{'; skipping apparent function body". See How do I resolve ambiguities with GetCurrentTime and/or TRY?.
The C++ compiler produces "winrt::impl::produce<D,I> cannot instantiate abstract class, due to missing GetBindingConnector". You need to #include <winrt/Windows.UI.Xaml.Markup.h>.
The C++ compiler produces "error C2039: 'promise_type': is not a member of 'std::experimental::coroutine_traits<void>'". Your coroutine needs to return either an asynchronous operation object, or winrt::fire_and_forget. See Concurrency and asynchronous operations.
Your project produces "ambiguous access of 'PopulatePropertyInfoOverride'". This error can occur when you declare one base class in your IDL and a different base class in your XAML markup.
Loading a C++/WinRT solution for the first time produces "Designtime build failed for project 'MyProject.vcxproj' configuration 'Debug|x86'. IntelliSense might be unavailable.". This IntelliSense issue will resolve after you build for the first time.
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.
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. In pch.h in the consuming C++/WinRT app, add #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>—replacing MyNamespace as appropriate.
In a C++/WinRT project in Visual Studio, IntelliSense produces an error of the form "error E1696: cannot open source file". Compile your newly created project at least once. Then right-click in the source code editor > Rescan > Rescan File. That will resolve all IntelliSense errors, including E1696.

Note

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.