www.rolandk.de
- Aktuelle Themen zu .Net -
Achtung: Hier handelt es sich um meine alte Seite.
Die aktuelle ist unter folgendem Link erreichbar: www.rolandk.de/wp/
Home




















































C#-Scripting 3 - Debugging laufender C#-Scripts
Mittwoch, den 03. Oktober 2012 um 18:21 Uhr

 

Allgemeines

Am Ende des letzten Artikels besteht ein C#-Script Editor mit Syntax-Highlighting und Intellisense. Der Code kann direkt ausgeführt werden, doch ein wichtiges Feature fehlt noch: Das Debugging von kompilierten Code. Dieser Artikel zeigt, wie dieses doch nicht ganz so leichte Problem gelöst werden kann.

 

C#-Script dynamisch mit Debug-Informationen laden

Bevor das Debuggen möglich ist, müssen beim Kompilieren des C#-Codes auch die Debug-Informationen erstellt werden. Normalerweise stehen die in den *.pdb Dateien, die von Visual Studio typischerweise neben den *.dll und *.exe Dateien erzeugt werden. In unserem Fall entsteht aber keine Dll-Datei im Dateisystem, sondern wird direkt in den Speicher geladen. Zum Glück ist das kein Problem, denn die Debug-Informationen können genauso direkt mit erstellt und in den Speicher geladen werden. Es genügt, die im ersten Artikel dieser Serie beschriebene Methode Compile der Klasse CSharpScriptCompiler um eine Kleinigkeit zu erweitern.

  1. /// <summary>
  2. /// Compiles given source file.
  3. /// </summary>
  4. /// <param name="m_currentFile">The source file to be compiled.</param>
  5. public Action Compile(CSharpScriptFile m_currentFile)
  6. {
  7. //Set compiler parameters
  8. CompilerParameters compilerParameters = new CompilerParameters();
  9. compilerParameters.GenerateExecutable = false;
  10. compilerParameters.GenerateInMemory = true;
  11. compilerParameters.IncludeDebugInformation = true;
  12. compilerParameters.OutputAssembly = "ScriptedAssembly";
  13. compilerParameters.ReferencedAssemblies.AddRange(
  14. m_currentFile.ReferencedAssemblies.ToArray());

Neu ist hier die Zeile 11. Mit dem Flag IncludeDebugInformation werden die Debug-Informationen erzeugt, welche normalerweise in den Pdb-Dateien landen. Sinnvollerweise werden sie hier ähnlich wie die Assembly selbst auch direkt mit in den Speicher geladen. Fertig ist man damit aber leider noch nicht, denn wird jetzt bei aktiven Visual Studio Debugger im C#-Script eine Exception ausgelöst, erscheint nachfolgende Meldung.

 

 

Der Dateiname vowdyvs2.0.cs hilft hier nicht wirklich weiter. Was fehlt also noch? Um den C#-Script debuggen zu können, muss der kompilierte Code auch irgendwo auf der Festplatte liegen. Für dieses Beispiel habe ich einen relativ einfachen Vorgang dafür gewählt. Innerhalb der Methode Compile wird der C#-Script in eine temporäre Datei mit sprechendem Namen weggeschrieben und beim Kompilieren selbst wird darauf verwiesen. Nachfolgende Modifikation der Compile Methode erfüllt diese Aufgabe.

  1. /// <summary>
  2. /// Compiles given source file.
  3. /// </summary>
  4. /// <param name="m_currentFile">The source file to be compiled.</param>
  5. public Action Compile(CSharpScriptFile m_currentFile)
  6. {
  7. //Set compiler parameters
  8. CompilerParameters compilerParameters = new CompilerParameters();
  9. compilerParameters.GenerateExecutable = false;
  10. compilerParameters.GenerateInMemory = true;
  11. compilerParameters.IncludeDebugInformation = true;
  12. compilerParameters.OutputAssembly = "ScriptedAssembly";
  13. compilerParameters.ReferencedAssemblies.AddRange(
  14. m_currentFile.ReferencedAssemblies.ToArray());
  15.  
  16. //Write content to temporary code file
  17. string filePath = GetTemporaryFilePath("ScriptedAssembly");
  18. File.WriteAllText(filePath, m_currentFile.ScriptContent);
  19.  
  20. //Compile the code and return the result or throw an exception in case of an error
  21. CompilerResults results = m_codeCompiler.CompileAssemblyFromFile(
  22. compilerParameters,
  23. filePath);

Wichtig hier sind die Zeilen 17 und 18, da hier der C# Code in eine eigene Datei geschrieben wird. Die Methode GetTemporaryFilePath erzeugt einen Pfad auf eine noch nicht existierende Datei im temporären Ordner des aktuellen Nutzers. Der Name der Datei enthält sinnvollerweise den Namen des Scripts, hier also einfach "ScriptedAssembly". Danach wird wie vorher auch das Kompilieren angestoßen, jetzt allerdings mit der Methode CompileAssemblyFromFile. Das sorgt auch wieder dafür, dass der C#-Code in eine Dll übersetzt wird und die Debug-Informationen erzeugt werden - diesmal zeigen die Debug-Informationen aber nicht auf einen nicht sprechenden Dateinamen wie oben, sondern auf die selbst erzeugte C#-Datei. Provoziert man jetzt absichtlich einen Fehler im Script und ist etwa der Visual Studio Debugger aktiv, dann springt er auch direkt in die erzeugte Code-Datei, sobald eine unbehandelte Ausnahme auftritt.

 

 

Kostenlose Tools zum Debuggen

Obige Lösung hat noch ein großes Problem: Sie hängt davon ab, dass das Debuggen von einer fremden IDE - hier Visual Studio - abhängig ist. Mir persönlich ist aktuell auch keine einfache Möglichkeit bekannt, ein ähnliches Debugging Feature wie bei Visual Studio in einen eigenen Script-Editor einzubauen. Das braucht es aber eigentlich auch gar nicht. Ist Visual Studio mit C# auf einem Rechner nicht vorhanden, kann auch die kostenlose Visual Studio 2010 Shell verwendet werden. Sie hat zwar kein Syntax Highlighting für C#, bietet aber volle Debugging-Funktionen inklusive Anhängen an laufende Prozesse. Eine andere Alternative ist noch SharpDevelop, auf dessen Komponenten basiert auch diese Artikelserie. Auch dort ist es möglich, sich an einen laufenden Prozess anzuhängen und damit Script-Dateien zu debuggen.

 

Zusammenfassung

In diesem Artikel bin ich darauf eingegangen, wie C#-Script-Dateien zur Laufzeit gedebuggt werden können. Dieser Artikel bildet gleichzeitig auch den Abschluss dieser kurzen Artikelserie. Als Ergebnis steht jetzt ein C#-Script Editor mit Intellisense und dazu eine Möglichkeit, die laufenden Scripte debuggen zu können. Die Artikel haben auch gezeigt, dass dieses Vorhaben mit den Komponenten von SharpDevelop sehr einfach umzusetzen ist.

Quellen

  • AvalonEdit
    Artikel auf CodeProject, der die AvalonEdit Komponente sehr gut beschreibt.
  • SharpDevelop
    Die Komponenten dieser freien C#-IDE dienen als Hilfsmittel für das hier umgesetzte Programm.
  • Nuget
    Packetverwaltungssystem für Visual Studio, auf das in den Artikeln öfters verwiesen wird.
  • SharpDevelopCodeCompletion
    OpenSource-Projekt, welches die Umsetzung eines Intellisense innerhalb des AvalonEdit Controls deutlich vereinfacht.
  • Visual Studio 2010 Shell
    Kostenlose Version von Visual Studio, welche als reiner Debugger genutzt werden kann.
 

Kommentar hinzufügen

Ihr Name:
Kommentar: