Generieren von Quellcode aus .NET-Assemblys beim Debuggen
Wenn Sie eine .NET-Anwendung debuggen, stellen Sie möglicherweise fest, dass Sie Quellcode anzeigen möchten, den Sie nicht haben. Dies kann z. B. der Fall sein, um die Ausführung bei einer Ausnahme zu unterbrechen oder mithilfe der Aufrufliste zu einer Position im Quellcode zu navigieren.
Anmerkung
- Die Quellcodegenerierung (Dekompilation) ist nur für .NET-Anwendungen verfügbar und basiert auf dem Open Source-ILSpy Projekt.
- Dekompilierung ist nur in Visual Studio 2019 16.5 und höher verfügbar.
- Durch Anwenden des SuppressIldasmAttribute--Attributs auf eine Assembly oder ein Modul wird verhindert, dass Visual Studio die Dekompilierung versucht. Obwohl das Attribut in .NET 6 und höher veraltet ist, berücksichtigt Visual Studio das Attribut.
Quellcode generieren
Wenn Sie debuggen und kein Quellcode verfügbar ist, zeigt Visual Studio das Dokument "Nicht gefundene Quelle" an, oder wenn Sie keine Symbole für die Assembly haben, wird das "Keine Symbole geladen" Dokument angezeigt. Beide Dokumente verfügen über die Option Quellcode dekompilieren, mit der C#-Code für die aktuelle Position generiert wird. Der generierte C#-Code kann dann wie jeder andere Quellcode verwendet werden. Sie können den Code anzeigen, Variablen prüfen, Haltepunkte festlegen usw.
Keine Symbole geladen
In der folgenden Abbildung wird die Meldung Keine Symbole geladen gezeigt.
Quelle nicht gefunden
Die folgende Abbildung zeigt die Meldung Quelle nicht gefunden.
Code automatisch dekompilieren
Ab Visual Studio 2022, Version 17.7, unterstützt der Visual Studio-Debugger die Autodekompilierung von externem .NET-Code. Sie können autodekompilieren, wenn Sie in externen Code wechseln oder das Fenster "Aufrufstapel" verwenden.
Wenn Sie in extern implementierten Code eintreten, dekompiliert der Debugger ihn automatisch und zeigt den aktuellen Ausführungspunkt an. Wenn Sie in externen Code wechseln möchten, deaktivieren Sie Just My Code.
Sie können aus dem Fenster "Anrufliste" dekompilieren, ohne "Just My Code" zu deaktivieren.
So dekompilieren Sie automatisch über das Fenster „Aufrufliste“:
Wählen Sie beim Debuggen mit geöffneten Fenster „Aufrufstapel“ die Option Externen Code anzeigenaus.
Doppelklicken Sie im Fenster "Anrufstapel" auf einen beliebigen Stapelframe. Der Debugger dekompiliert den Code und navigiert dann direkt zum aktuellen Ausführungspunkt.
Der gesamte dekompilierte Code wird auch unter dem Knoten "Externe Quellen" im Projektmappen-Explorer angezeigt und erleichtert das Durchsuchen der externen Dateien bei Bedarf.
Sie können den dekompilierten Code debuggen und Haltepunkte festlegen.
Wenn Sie die automatische Dekompilierung von externem Code deaktivieren möchten, gehen Sie zu Extras > Optionen > Debuggen > Allgemein, und deaktivieren Sie Bei Bedarf automatisch auf Quelle dekompilieren (nur verwaltet).
Quellen für eine Assembly generieren und einbetten.
Zusätzlich zum Generieren von Quellcode für einen bestimmten Speicherort können Sie den gesamten Quellcode für eine bestimmte .NET-Assembly generieren. Um diese Aufgabe zu erledigen, wechseln Sie zum Module Fenster, öffnen Sie das Kontextmenü einer .NET-Assembly und wählen Sie dann den Befehl "Quelle dekompilieren in Symboldatei" aus. Visual Studio generiert eine Symboldatei für die Assembly und bettet die Quelle dann in die Symboldatei ein. In einem späteren Schritt können Sie eingebetteten Quellcode extrahieren.
Extrahieren und Anzeigen des eingebetteten Quellcodes
Sie können Quelldateien extrahieren, die in eine Symboldatei eingebettet sind, mithilfe des Befehls Quellcode extrahieren im Kontextmenü des fensters Module.
Die extrahierten Quelldateien werden als sonstige Dateiender Lösung hinzugefügt. Das Feature "Verschiedene Dateien" ist in Visual Studio standardmäßig deaktiviert. Sie können dieses Feature mit dem Kontrollkästchen Extras>Optionen>Umgebung>Dokumente>Sonstige Dateien im Projektmappen-Explorer anzeigen aktivieren. Wenn dieses Feature nicht aktiviert ist, können Sie den extrahierten Quellcode nicht öffnen.
Extrahierte Quelldateien werden in den verschiedenen Dateien im Projektmappen-Explorerangezeigt.
SourceLink
Für .NET-Bibliotheken oder für NuGet-Pakete, die für SourceLink aktiviert sind, können Sie auch in Quellcode wechseln, Haltepunkte festlegen und alle Features des Debuggers verwenden. Weitere Informationen finden Sie unter Aktivieren von Debugging und Diagnose mit Source Link und Verbesserung der Produktivität während der Debugging-Zeit mit Source Link.
Bekannte Einschränkungen
Erfordert Unterbrechungsmodus
Das Generieren von Quellcode mithilfe der Dekompilierung ist nur möglich, wenn sich der Debugger im Unterbrechungsmodus befindet und die Anwendung angehalten wird. Beispielsweise wechselt Visual Studio in den Unterbrechungsmodus, wenn er auf einen Haltepunkt oder eine Ausnahme trifft. Sie können Visual Studio ganz einfach dazu veranlassen, beim nächsten Ausführen Ihres Codes zu unterbrechen, indem Sie den Befehl "Alle unterbrechen" verwenden ().
Dekompilierungseinschränkungen
Das Generieren von Quellcode aus dem Zwischenformat (IL), das in .NET-Assemblys verwendet wird, hat einige Einschränkungen. Daher sieht der generierte Quellcode nicht wie der ursprüngliche Quellcode aus. Die meisten Unterschiede sind an Orten, an denen die Informationen im ursprünglichen Quellcode zur Laufzeit nicht benötigt werden. Beispielsweise werden Informationen wie Leerzeichen, Kommentare und die Namen lokaler Variablen zur Laufzeit nicht benötigt. Es wird empfohlen, die generierte Quelle zu verwenden, um zu verstehen, wie das Programm ausgeführt wird und nicht als Ersatz für den ursprünglichen Quellcode.
Debuggen von optimierten oder Releaseassemblys
Beim Debuggen von Code, der von einer Assembly dekompiliert wurde, die mithilfe von Compileroptimierungen kompiliert wurde, treten möglicherweise die folgenden Probleme auf:
- Breakpoints werden möglicherweise nicht immer an die entsprechende Quellcodeposition gebunden.
- Die schrittweise Ausführung endet möglicherweise nicht immer an der richtigen Position.
- Lokale Variablen weisen möglicherweise keine genauen Namen auf.
- Einige Variablen sind möglicherweise nicht für die Auswertung verfügbar.
Weitere Details finden Sie im GitHub-Problem: ICSharpCode.Decompiler-Integration in VS Debugger.
Dekompilierungszuverlässigkeit
Ein relativ kleiner Prozentsatz der Dekompilierungsversuche kann zu einem Fehler führen. Dieses Verhalten ist auf einen Sequenzpunkt-Nullverweisfehler in ILSpy zurückzuführen. Wir haben den Ausfall abgemildert, indem wir diese Probleme erkannt und den Dekompilierungsversuch kontrolliert abbrechen lassen haben.
Weitere Details finden Sie im GitHub-Problem: ICSharpCode.Decompiler-Integration in VS Debugger.
Einschränkungen mit asynchronem Code
Die Ergebnisse der Dekompilierung von Modulen mit async/await-Codemustern können unvollständig sein oder vollständig scheitern. Die ILSpy-Implementierung von async/await- und yield-Zustandsautomaten ist unvollständig.
Weitere Details finden Sie im GitHub-Issue: PDB Generator Status.
Nur mein Code
Mit der Einstellung Just My Code (JMC) kann Visual Studio System-, Framework-, Bibliotheks- und andere Nichtbenutzeraufrufe überspringen. Während einer Debugsitzung zeigt das Module Fenster an, welche Codemodule der Debugger als "Mein Code" (Benutzercode) behandelt.
Die Dekompilierung von optimierten oder Releasemodulen erzeugt Nichtbenutzercode. Wenn der Debugger beispielsweise die Ausführung von dekompiliertem Nichtbenutzercode unterbricht, wird das Fenster Keine Quelle angezeigt. Um "Nur mein Code" zu deaktivieren, navigieren Sie zu Tools>Optionen (oder Debug>Optionen) >Debuggen>Allgemein, und deaktivieren Sie dann "Nur mein Code aktivieren".
Extrahierte Quellen
Der aus einer Assembly extrahierte Quellcode weist die folgenden Einschränkungen auf:
- Der Name und speicherort der generierten Dateien kann nicht konfiguriert werden.
- Die Dateien werden von Visual Studio temporär und gelöscht.
- Die Dateien werden in einem einzelnen Ordner platziert, und alle Ordnerhierarchien, die die ursprünglichen Quellen hatten, werden nicht verwendet.
- Der Dateiname für jede Datei enthält einen Prüfsummenhash der Datei.
Generierter Code ist nur C#
Dekompilierung generiert nur Quellcodedateien in C#. Es gibt keine Option zum Generieren von Dateien in einer anderen Sprache.