Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'estensione Visual Studio C++/WinRT (VSIX) consente di usare la visualizzazione di debug nativa di Visual Studio (natvis) per i tipi proiettati di C++/WinRT. Questo offre un'esperienza simile al debug C#.
Note
Per altre info su C++/WinRT Visual Studio Extension (VSIX), vedi Visual Studio supporto per C++/WinRT e VSIX.
Abilitazione di Natvis
Natvis viene attivato automaticamente per una compilazione di debug perché WINRT_NATVIS viene definito quando viene definito il simbolo _DEBUG .
Ecco come scegliere di attivarlo per una build di rilascio.
- Compilare il codice con il simbolo WINRT_NATVIS definito. In questo modo viene esportata una funzione WINRT_abi_val , che fornisce il punto di ingresso per il visualizzatore di debug per valutare i valori delle proprietà nel processo di destinazione.
- Generare un PDB completo. Questo perché il visualizzatore di debug usa l'analizzatore di espressioni C++ Visual Studio, che a sua volta richiede definizioni simboliche per i tipi di proprietà visualizzati.
- Un tipo visualizzato deve segnalare una classe di runtime o un'interfaccia definita nei metadati individuabili. Questa operazione viene eseguita tramite l'implementazione di IInspectable::GetRuntimeClassName.
Dato quanto sopra, il visualizzatore di debug funziona meglio con Windows tipi di sistema per i quali i metadati sono disponibili nella C:\Windows\System32\WinMetadata cartella . Tuttavia, può anche supportare i tipi definiti dall'utente e il debug remoto, a condizione di individuare correttamente i file .winmd.
Uso di metadati personalizzati
Il visualizzatore di debug cerca i metadati definiti dall'utente (.winmd file) insieme al processo .exe. Usa un algoritmo simile a quello di RoGetMetaDataFile, cercando sottostringhe successive del nome di tipo completamente qualificato. Ad esempio, se il tipo visualizzato è Contoso.Controls.Widget, il visualizzatore cerca, in sequenza, per:
- Contoso.Controls.Widget.winmd
- Contoso.Controls.winmd
- Contoso.winmd
Debug remoto con metadati personalizzati
Quando si esegue il debug remoto, il processo .exe non è locale, quindi la ricerca di metadati personalizzati (menzionati nella sezione precedente) ha esito negativo. In tal caso, il visualizzatore torna a usare una cartella cache locale (%TEMP%) per un file .winmd appropriato. Se ne trova uno, registra le dimensioni e la data del file e quindi cerca nella destinazione di debug remoto lo stesso .winmd insieme al file binario. Se necessario, il file remoto viene scaricato, aggiornando la cache locale. Questa strategia garantisce che la cache locale sia sempre aggiornata .winmd , oltre a fornire un mezzo per memorizzare manualmente nella cache un oggetto .
winmd se non è possibile trovare in remoto (ad esempio, se la distribuzione F5 non l'ha inserita).
Per un esempio del comportamento di memorizzazione nella cache, vedere la sezione Risoluzione dei problemi di seguito.
Risoluzione dei problemi
Il visualizzatore di debug usa l'analizzatore di espressioni C++ Visual Studio per richiamare la funzione WINRT_abi_val esportata per ottenere i valori delle proprietà. In genere, il visualizzatore può rilevare eccezioni non gestite e degradarsi normalmente, visualizzando "<Oggetto non inizializzato o informazioni non disponibili>" in Visual Studio finestre Espressioni di controllo.
Ciò è utile quando il visualizzatore tenta di valutare una variabile locale al di fuori dell'ambito di durata, ad esempio prima della costruzione. In alcuni contesti, ad esempio unit test, viene installato un filtro eccezioni non gestito. Ciò può causare l'interruzione del processo quando si verifica un errore dell'analizzatore di espressioni C++. Per evitare errori, il visualizzatore effettua diverse chiamate VirtualQuery in WINRT_abi_val.
Diagnostica
Se una proprietà non viene visualizzata correttamente, attivare la diagnostica Natvis dettagliata in Visual Studio (Strumenti>Opzioni>Debug>Finestra di output>Messaggi di diagnostica Natvis) e quindi controllare la finestra Output per individuare eventuali errori Natvis.
L'estratto seguente mostra diversi tentativi di individuare un file .winmd, seguiti dal download dal target remoto alla cartella della cache locale e quindi dal caricamento di tale file .winmd.
Natvis C++/WinRT: Looking for C:\Users\...\AppData\Local\DevelopmentFiles\ffcddd4f-cfc0-44cb-b736-0b2d026def77VS.Debug_x64....\Consoso.Controls.Widget.winmd
Natvis C++/WinRT: Looking for C:\Users\...\AppData\Local\DevelopmentFiles\ffcddd4f-cfc0-44cb-b736-0b2d026def77VS.Debug_x64....\Consoso.Controls.winmd
Natvis C++/WinRT: Downloading C:\Users\...\AppData\Local\DevelopmentFiles\ffcddd4f-cfc0-44cb-b736-0b2d026def77VS.Debug_x64....\Consoso.Controls.winmd
Natvis C++/WinRT: Loaded C:\Users\...\AppData\Local\Temp\Consoso.Controls.winmd
Se il visualizzatore non riesce a trovare un .winmd file, viene generato questo errore:
Natvis C++/WinRT: Could not find metadata for Consoso.Controls.Widget
Esistono vari altri scenari di errore che generano messaggi diagnostici.
Se i metadati sono disponibili, la diagnostica di output mostrerà molte chiamate simili alla seguente:
Natvis C++/WinRT: WINRT_abi_val(*(::IUnknown**)0x32dd4ffc18, L"{96369F54-8EB6-48F0-ABCE-C1B211E627C3}", 0).s,sh
Natvis C++/WinRT: WINRT_abi_val(*(::IUnknown**)0x32dd4ffc18, L"{AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90}", -2).s,sh
Il primo è una chiamata a IStringable.ToString per ottenere la rappresentazione di stringa di un tipo complesso (valore di visualizzazione non espanso).
Il secondo è una chiamata a IInspectable::GetRuntimeClassName per riflettere sulle proprietà del tipo.
Le chiamate successive a WINRT_abi_val sono valutazioni di proprietà per ogni interfaccia individuata nel tipo.
Richiamo di WINRT_abi_val
È possibile usare le finestre di comando di Visual Studio Immediate/Command per richiamare direttamente WINRT_abi_val per risolvere i problemi.
Ad esempio, data una variabile proiettata stringable, è possibile valutarne IStringable.ToString nel modo seguente:
>? WINRT_abi_val((::IUnknown*)&stringable, L"{96369F54-8EB6-48F0-ABCE-C1B211E627C3}", 0).s,sh
L"string"