Como solucionar problemas de C++/WinRT

Observação

Para saber mais sobre como instalar e usar a Extensão do Visual Studio (VSIX) para C++/WinRT (que fornece suporte de modelo de projeto), confira Suporte do Visual Studio para C++/WinRT.

Este tópico é fornecido como precaução para que você fique atento a ele imediatamente, mesmo que você ainda não esteja precisando dessas informações. A tabela de sintomas de solução de problemas e soluções a seguir pode ser útil se você estiver recortando um novo código ou fazendo a portabilidade de um aplicativo existente. Se você estiver fazendo a portabilidade e estiver ansioso para avançar e chegar ao estágio de compilação e execução do projeto, poderá fazer um progresso temporário comentando ou eliminando qualquer código não essencial que esteja causando problemas e retornando para resolver esse problema mais tarde.

Para obter a lista de perguntas frequentes, confira Perguntas frequentes.

Como rastrear problemas de XAML

Exceções de análise XAML podem ser difíceis de diagnosticar, especialmente se não houver mensagens de erro significativas na exceção. Certifique-se de que o depurador esteja configurado para capturar exceções de primeira chance (para tentar e capturar a exceção de análise logo no início). Você pode inspecionar a variável de exceção no depurador para determinar se o HRESULT ou a mensagem tem informações úteis. Além disso, verifique na janela de saída do Visual Studio se há mensagens de erro de saída do analisador XAML.

Se o aplicativo for encerrado e tudo o que você sabe é que uma exceção sem tratamento foi lançada durante a análise da marcação XAML, isso pode ser resultado de uma referência (por chave) a um recurso ausente. Ou ela pode ser uma exceção lançada dentro de um UserControl, um controle personalizado ou um painel de layout personalizado. Um último recurso é uma divisão binária. Remova cerca da metade da marcação de uma página XAML e execute o aplicativo novamente. Em seguida, você saberá se o erro está em algum lugar dentro da metade removida (que agora você deverá restaurar em qualquer caso) ou na metade que você não removeu. Repita o processo dividindo a metade que contém o erro e assim por diante, até zerar o problema.

Sintomas e soluções

Sintoma Medida
Uma exceção é lançada em runtime com um valor HRESULT de REGDB_E_CLASSNOTREGISTERED. Confira Por que estou recebendo uma exceção de "classe não registrada"?.
O compilador C++ gera o erro "'implements_type': não é membro de qualquer classe base direta ou indireta de '<tipo projetado>'". Isso poderá acontecer quando você chamar make com o nome não qualificado de namespace do tipo de implementação (MyRuntimeClass, por exemplo) e não tiver incluído o cabeçalho desse tipo. O compilador interpreta MyRuntimeClass como o tipo projetado. A solução é incluir o cabeçalho do tipo de implementação (MyRuntimeClass.h, por exemplo).
O compilador C++ gera o erro "tentando referenciar uma função excluída". Isso poderá acontecer quando você chamar make e o tipo de implementação passado como parâmetro de modelo tiver um construtor padrão = delete. Edite o arquivo de cabeçalho do tipo de implementação e altere = delete para = default. Você também pode adicionar um construtor em IDL para a classe de runtime.
Você implementou INotifyPropertyChanged, mas suas associações XAML não estão sendo atualizadas (e a interface do usuário não está assinando PropertyChanged). Lembre-se de definir Mode=OneWay (ou TwoWay) em sua expressão de associação na marcação XAML. Confira Controles XAML; associar a uma propriedade C++/WinRT.
Você está associando um controle de itens XAML a uma coleção observável, e uma exceção é lançada em runtime com a mensagem "O parâmetro está incorreto". No IDL e na implementação, declare qualquer coleção observável como tipo Windows.Foundation.Collections.IVector<IInspectable>. Mas retorne um objeto que implementa Windows.Foundation.Collections.IObservableVector<T>, em que T é o tipo de elemento. Confira Controles de itens XAML; associar a uma coleção C++/WinRT.
O compilador C++ gera um erro do formulário "'MyImplementationType_base<MyImplementationType>': nenhum construtor padrão apropriado disponível". Isso poderá acontecer quando você fizer a derivação de um tipo que tem um construtor não trivial. O construtor do tipo derivado precisa passar os parâmetros que o construtor do tipo base precisa. Para obter um exemplo trabalhado, confira Como derivar de um tipo que tem um construtor não trivial.
O compilador C++ gera o erro "não é possível converter 'const std::vector<std::wstring,std::allocator<_Ty>>' em 'const winrt::param::async_iterable<winrt::hstring> &'". Isso poderá acontecer quando você passar um std::vector de std::wstring para uma API de Windows Runtime que espera uma coleção. Para saber mais, confira Tipos de dados C++ padrão e C++/WinRT.
O compilador C++ gera o erro "não é possível converter 'const std::vector<winrt::hstring,std::allocator<_Ty>>' em 'const winrt::param::async_iterable<winrt::hstring> &'". Isso poderá acontecer quando você passar um std::vector de winrt::hstring para uma API assíncrona do Windows Runtime que espera uma coleção e não tiver copiado nem movido o vetor para o computador chamado assíncrono. Para saber mais, confira Tipos de dados C++ padrão e C++/WinRT.
Ao abrir um projeto, o Visual Studio gera o erro "O aplicativo do projeto não está instalado". Se você ainda não tiver instalado as ferramentas Universais do Windows para desenvolvimento em C++ na caixa de diálogo Novo Projeto do Visual Studio, precisará fazê-lo. Se isso não resolver o problema, possivelmente o projeto dependerá da Extensão do Visual Studio (VSIX) do C++/WinRT (confira Suporte do Visual Studio para C++/WinRT).
Os testes do Kit de Certificação de Aplicativos Windows produzem um erro informando que uma das suas classes de tempo de execução "does not derive from a Windows base class. All composable classes must ultimately derive from a type in the Windows namespace". Qualquer classe de runtime (que você declara em seu aplicativo) que é derivada de uma classe base é conhecida como uma classe combinável. A classe base definitiva de uma classe combinável deve ser um tipo de origem em um namespace do Windows.*; por exemplo, Windows.UI.Xaml.DependencyObject. Para obter mais detalhes, confira Controles XAML; associar a uma propriedade C++/WinRT.
O compilador C++ gera o erro "T precisa ser do tipo WinRT" para uma especialização de delegado de EventHandler ou TypedEventHandler. Em vez disso, é recomendável o uso de winrt::delegate<...T>. Confira Criar eventos em C++/WinRT.
O compilador C++ gera o erro "T precisa ser do tipo WinRT" para uma especialização de operação assíncrona do Windows Runtime. Em vez disso, é recomendável retornar uma tarefa PPL (Parallel Patterns Library). Confira Simultaneidade e operações assíncronas.
O compilador C++ gera o erro "T precisa ser do tipo WinRT" quando você chama winrt::xaml_typename. Use o tipo projetado com winrt::xaml_typename (por exemplo, use BgLabelControlApp::BgLabelControl) e não o tipo de implementação (por exemplo, não use BgLabelControlApp::implementation::BgLabelControl). Confira Controles (modelo) personalizados XAML.
O compilador C++ gera "erro C2220: aviso tratado como erro - nenhum arquivo 'object' gerado". Corrija o aviso ou defina C/C++>Geral>Tratar Avisos como Erros como Não (/WX-) .
O aplicativo falha porque um manipulador de eventos no objeto C++/WinRT é chamado depois que o objeto é destruído. Confira Acessar com segurança o ponteiro isso com um representante de manipulação de eventos.
O compilador C++ gera "error C2338: This is only for weak ref support". Você está solicitando uma referência fraca para um tipo que passou o struct de marcador winrt::no_weak_ref como um argumento de modelo para sua classe base. Confira Como recusar o suporte de referência fraca.
O compilador C++ produz o erro "consume_Something: a função que retorna 'auto' não pode ser usada antes de ser definida" Confira C3779: Por que o compilador está exibindo um erro "consume_Something: a função que retorna 'auto' não pode ser usada antes de ser definida"?.
O vinculador C++ produz o "erro LNK2019: símbolo externo não resolvido" Confira Por que o vinculador fornece um erro "LNK2019: erro externo não resolvido"?.
A cadeia de ferramentas Clang e de LLVM produz erros quando usado com C++/WinRT. Não oferecemos suporte a cadeia de ferramentas Clang e de LLVM para C++/WinRT, mas se você quiser emular como podemos usá-lo internamente, então, você pode tentar um experimento, como aquele descrito em Posso usar Clang/LLVM para compilar com C++/WinRT?.
O compilador C++ produz "nenhum construtor padrão apropriado" para um tipo projetado. Se você estiver tentando atrasar a inicialização de um objeto de classe de runtime ou consumir e implementar uma classe de runtime no mesmo projeto, então precisará chamar o construtor std::nullptr_t. Para saber mais, confira Consumir APIs com C++/WinRT.
O compilador C++ produz o "erro C3861: 'from_abi': identificador não encontrado" e outros erros originados no base.h. Você pode ver este erro ao usar o Visual Studio 2017 (15.8.0 ou superior) visando o SDK do Windows 10.0.17134.0 (Windows 10, versão 1803). Você pode segmentar uma versão posterior (mais compatível) do SDK do Windows ou definir a propriedade do projeto C/C++>Linguagem>Modo de conformidade: No (Além disso, se /permissive-- for exibido na propriedade do projeto C/C++>Linguagem>Linha de Comando em Opções Adicionais, então o exclua).
O compilador C ++ produz o " erro C2039: 'IUnknown': não é membro do '`namespace global''". Confira Como redirecionar seu projeto do C++/WinRT para uma versão posterior do SDK do Windows.
O linker C++ produz o "erro LNK2019: símbolo externo não resolvido _WINRT_CanUnloadNow@0 mencionado na função _VSDesignerCanUnloadNow@0" Confira Como redirecionar seu projeto do C++/WinRT para uma versão posterior do SDK do Windows.
O processo de build produz a mensagem de erro O VSIX do C++/WinRT não oferece mais suporte ao build do projeto. Adicione uma referência de projeto ao pacote Microsoft.Windows.CppWinRT Nuget. Instale o pacote do NuGet Microsoft.Windows.CppWinRT em seu projeto. Para obter detalhes, confira Versões anteriores da extensão do VSIX.
O vinculador C++ produz error LNK2019: unresolved external symbol, com uma menção winrt::impl::consume_Windows_Foundation_Collections_IVector. A partir do C++/WinRT 2.0, se você estiver usando um for baseado em intervalo na coleção de Windows Runtime e, em seguida, você precisará de #include <winrt/Windows.Foundation.Collections.h>.
O compilador C++ produz o "erro C4002: Muitos argumentos para a invocação de macro do tipo função GetCurrentTime". Confira Como resolver ambiguidades com GetCurrentTime e/ou TRY?.
O compilador C++ produz o "erro C2334: tokens inesperados antes de '{'; ignorando o corpo aparente da função". Confira Como resolver ambiguidades com GetCurrentTime e/ou TRY?.
O compilador C++ produz "winrt::impl::produce<D,I> não pode criar uma instância da classe abstrata devido a GetBindingConnector ausente". Você precisa #include <winrt/Windows.UI.Xaml.Markup.h>.
O compilador C++ produz o "erro C2039: 'promise_type': não é um membro de 'std::experimental::coroutine_traits<void>'". Sua corrotina precisa retornar um objeto de operação assíncrona ou winrt::fire_and_forget. Confira Simultaneidade e operações assíncronas.
Seu projeto produz "acesso ambíguo de 'PopulatePropertyInfoOverride'". Esse erro pode ocorrer quando você declara uma classe base em seu IDL e outra classe base na marcação XAML.
Carregar uma solução de C++/WinRT pela primeira vez produz "Falha no build no tempo de design para o projeto 'MyProject.vcxproj' com a configuração 'Debug|x86'. O IntelliSense pode estar indisponível.". Esse problema com o IntelliSense será resolvido após você executar o build pela primeira vez.
Tentar especificar winrt::auto_revoke ao registrar um delegado produz uma exceção winrt::hresult_no_interface. Consulte Se o registro de seu delegado de revogação automática falhar.
Em um aplicativo C++/WinRT, ao consumir um componente do Windows Runtime com C# que usa o XAML, o compilador produz um erro no formato "'MyNamespace_XamlTypeInfo': não é um membro de 'winrt::MyNamespace'", em que MyNamespace é o nome do namespace do componente do Windows Runtime. Em pch.h no aplicativo C++/WinRT de consumo, adicione #include <winrt/MyNamespace.MyNamespace_XamlTypeInfo.h>substituindo MyNamespace conforme apropriado.
Em um projeto C++/WinRT no Visual Studio, o IntelliSense produz um erro no formato "erro E1696: não é possível abrir o arquivo de origem". Compile seu projeto recém-criado pelo menos uma vez. Em seguida, clique com o botão direito do mouse no editor de código-fonte >Examinar novamente>Examinar novamente o arquivo. Isso resolverá todos os erros do IntelliSense, incluindo o E1696.

Observação

Se este tópico não respondeu à sua dúvida, você poderá encontrar ajuda visitando a comunidade de desenvolvedores do Visual Studio C++ ou usando a marcação c++-winrt no Stack Overflow.