Windows 8

Debuggen von Windows Store-Apps: Erste Schritte

Bruno Terkaly
Robert Evans

In den 1940er-Jahren trat in einem von Admiral Grace Hoppers Programmen ein Fehler auf, und sie entdeckte zwischen den Relais im Harvard Mark II eine Motte: der Begriff Bug (englisch für Insekt) wurde geprägt. Heute hat Debuggen natürlich nichts mehr mit Insekten zu tun; es handelt sich um den Prozess des Ermittelns und Behebens von Fehlern in Software.

Die aktuellen Programmiersprachen und Tools bieten den Entwicklern umfangreiche Unterstützung beim Schreiben von stabilem Code, aber vor logischen Fehlern gibt es keinen Schutz. Moderne Kompilierer können nur elementare Überprüfungen im Hinblick auf die Programmiersprachensyntax und die ordnungsgemäße Verwendung des Typensystems durchführen. Der Compiler ist keine große Hilfe dabei, das tatsächliche Verhalten der Anwendung zur Laufzeit zu bestimmen. An diesem Punkt sind Debuggingfähigkeiten unerlässlich. Der Schwerpunkt dieses Artikels ist das Debuggen von Windows Store-Apps. Außerdem werden einige der in diesem Bereich verwendeten Techniken betrachtet.

Wir verwenden Visual Studio 2013 Preview, aber diese Techniken funktionieren im Allgemeinen mit früheren Produktversionen. Sie müssen allerdings Ihre Umgebung vorbereiten, bevor Sie mit dem fortgeschrittenen Debuggen beginnen, das über das Debuggen allein in Visual Studio hinausgeht. Wir empfehlen Ihnen, die folgenden Ressourcen herunterzuladen und zu installieren:

Lebenszyklusverwaltung für Prozesse

Bei normalen Desktopanwendungen starten die Benutzer eine App, und diese wird ausgeführt, bis die Benutzer sie beenden. Die Anwendung wird auch dann weiter ausgeführt, wenn sie sich nicht im Vordergrund befindet. Windows Store-Apps sind in dieser Hinsicht etwas anders. Wenn eine App nicht im Vordergrund ist, hält ein Windows-Dienst – der Laufzeitbroker – alle Threads in der App an und aktiviert sie erst dann wieder, wenn die App im Vordergrund ist. Dieses neue Feature hilft dabei, die Gesamtleistung des Systems und die Akkulaufzeit zu bewahren. Sogar wenn die Benutzer eine App schließen, ist die Standardaktion unter Windows 8.1, die App in den angehaltenen Zustand zu versetzen, anstatt sie zu beenden. Wenn Sie die frühere Windows 8-Funktionalität bevorzugen, legen Sie „Windows.ApplicationModel.ClosePolicy.TerminateOnClose“ gleich TRUE fest.

Die Suspend- und Resume-Ereignisse werden an die App gesendet, wodurch Sie den Status speichern und abrufen oder nach Bedarf andere Aktionen ausführen können. Wenn eine App eine zu hohe Speicherbelastung verursacht oder zu viel Zeit zum Starten benötigt, beendet zudem der Laufzeitbroker die App und ihre gesamten Threads. Beim Debuggen von Apps deaktiviert Visual Studio automatisch die Lebenszyklusverwaltung für Prozesse (Process Lifecycle Management, PLM) für die fraglichen Apps. Dabei spielt es keine Rolle, ob Sie Ihre eigene App debuggen, oder ob Sie an eine installierte App anfügen (mithilfe von „Debuggen | Installiertes App-Paket debuggen“). PLM muss auf jeden Fall deaktiviert sein, da Sie die Anwendung sonst nicht ordnungsgemäß debuggen können. Der Grund dafür ist einfach: Der Laufzeitbroker könnte eingreifen und die Anwendung deaktivieren, bevor Sie sie korrekt debuggen können.

Für einige nicht in Visual Studio enthaltene Debugger, z. B. den Windows-Debugger (WinDbg) und Microsoft Console Debugger (CDB), ist es allerdings erforderlich, dass Sie PLM-Features manuell deaktivieren. Dazu bietet sich das PLMDebug-Tool an, das im Windows 8.1 SDK verfügbar ist. Das Befehlszeilentool PLMDebug enthält die Option „/enableDebug“, mit dem Sie PLM für ein bestimmtes .appx-Paket deaktivieren können. Um die spezifische ID des .appx-Pakets zu identifizieren, zeigen Sie alle installierten App-Pakete über den Windows PowerShell-Befehl „Get-AppxPackage“ oder mit Process Explorer an (wie später in diesem Artikel beschrieben). 

PLMDebug bietet einige nützliche Features. Sie können mit dem Tool zum Beispiel eine Vielzahl von Ereignissen an die App senden, darunter „Suspend“, „Resume“, „Terminate“, „Force-terminate“ und „Clean-terminate“. Auch das Anfügen eines Live-Debuggers ist möglich (wird aber in diesem Artikel nicht erläutert).

In Visual Studio können Sie auch Suspend- und Resume-Ereignisse auslösen. Dazu verwenden Sie die standardmäßig nicht angezeigte Symbolleiste „Debugspeicherort“. Fügen Sie die Symbolleiste hinzu, indem Sie „Ansicht | Symbolleisten | Debugspeicherort“ auswählen. Die Debugoptionen werden aktiviert, sobald Sie die App aktiv debuggen. In Abbildung 1 wird die Symbolleiste „Debugspeicherort“ in Visual Studio 2013 Preview dargestellt.

The Debug Location Toolbar
Abbildung 1: Symbolleiste „Debugspeicherort“

Hintergrundaufgaben

Viele Szenarios – wie beispielsweise das Aktualisieren einer Live-Kachel – können ohne eine Hintergrundaufgabe umgesetzt werden. Aber manchmal sind Hintergrundaufgaben notwendig, und sie stellen eine weitere Methode dar, um Code in der Windows Store-App aufgrund von bestimmten, von Ihnen definierten Systembedingungen implizit zu starten. Sie könnten zum Beispiel planen, für eine Ihrer Anwendungen Miniaturansichten im Hintergrund hinzuzufügen oder zu erstellen, aber nur dann, wenn das Gerät über das Netzteil betrieben wird. Mit dem Wartungstrigger können Sie einige Aufgaben anhand von Zeitintervallen und Systembedingungen starten und diese Aufgaben wiederholt ausführen. Der Code für Hintergrundaufgaben wird zwar in der App definiert, in den meisten Fällen aber von einem separaten Prozess namens „BackgroundTaskHost“ ausgeführt.

Eine Windows Store-App registriert ihre Hintergrundaufgaben bei der Hintergrundaufgaben-Infrastruktur auf Betriebssystemebene mithilfe der BackgroundTaskBuilder-Klasse. Die Hintergrundaufgabe wird als Klasse erstellt, welche die IBackgroundTask-Schnittstelle implementiert. Sie müssen nur die Run-Methode implementieren. Eine Hintergrundaufgabe muss genau einen Trigger haben, und sie muss mindestens eine Bedingung festlegen, die die genauen Umstände beschreibt, unter denen die Hintergrundaufgabe gestartet wird. Der Trigger wird mit der SetTrigger-Methode der BackgroundTaskBuilder-Klasse angegeben.

Visual Studio erleichtert das Ermitteln und Debuggen von registrierten Hintergrundaufgaben, da die deklarierten Hintergrundaufgaben der App mit der Symbolleiste „Debugspeicherort“ angezeigt und über die visuelle Schnittstelle in Visual Studio gestartet werden können. Diese Technik funktioniert für alle Hintergrundaufgaben mit Ausnahme von denen, die „ControlChannelTrigger“, „PushNotificationTrigger“ oder einen „SystemTrigger“ mit dem Triggertyp „SmsReceived“ verwenden. Weitere Informationen finden Sie im Whitepaper „Einführung in Hintergrundaufgaben“ unter aka.ms/O35jqc. Unter bit.ly/IZpfqNerhalten Sie außerdem ein gutes Codebeispiel.

Aktivierungen

Es gibt zahlreiche Methoden zum Starten der App, abhängig davon, was Sie implementiert haben, zum Beispiel „File“, „Protocol“, „PrintTaskSettings“ oder „ShareTarget“. Der ShareTarget-Aktivierungstyp ist beispielsweise dann aktiv, wenn ein Benutzer etwas aus einen anderen App für Ihre App freigibt.

Im Hinblick auf Aktivierungen gab es in Windows 8.1 einige Änderungen. Zum Beispiel ist die Search-Aktivierung jetzt veraltet; die Abwärtskompatibilität wird jedoch in gewissem Maße unterstützt. Es gibt außerdem einen neuen, innovativen Ansatz zum Starten anderer Anwendungen, die den Bildschirm gemeinsam mit Ihrer App verwenden. Das bedeutet, dass Sie den Bildschirm mit einem Browser teilen können, während Ihre App weiterhin aktiv bleibt. Weitere Informationen zu dieser Funktion finden Sie unter bit.ly/11ckVS3.

Um die Anwendung in Bezug auf diese Typen von Aktivierungen zu debuggen, wechseln Sie zunächst zu den Startaktionen in den Anwendungsprojekteigenschaften. Klicken Sie zuerst mit der rechten Maustaste im Visual Studio-Projektmappen-Explorer auf „ContosoCookbook“, und wählen Sie dann „Eigenschaften“ aus. Aktivieren Sie das Kontrollkästchen „Eigenen Code zunächst nicht starten, sondern debuggen“, wie in Abbildung 2 gezeigt. Wenn diese Einstellung aktiviert ist, können Sie die Anwendung debuggen und Haltepunkte im OnLaunched-Handler festlegen, der bei einer Aktivierung durch einen der anderen Aktivierungstypen ausgelöst wird. Durch diese Einstellung wird die Anwendung angewiesen, sich auf das Debuggen vorzubereiten, aber nicht tatsächlich zu starten, wenn Sie eine Debugger-Sitzung starten. Die Anwendung wartet einfach.

Setting Debugger Properties
Abbildung 2: Festlegen der Eigenschaften für den Debugger

Untersuchen einer ausgeführten Anwendung

Process Explorer bietet einige nützliche Features, mit denen Sie Einblick in die internen Abläufe einer ausgeführten Anwendung erhalten. Diese Features sehen wir uns anhand von einem Teil des Codes der App Kids Car Colors an, die Sie unter bit.ly/YnmAxT herunterladen können. Wechseln Sie zum Startbildschirm, und starten Sie die App Kids Car Colors und anschließend Process Explorer (wobei vorausgesetzt wird, dass Sie Process Explorer zuvor eingerichtet haben).

Erweitern Sie SVCHOST.EXE, um den Laufzeitbroker und alle ausgeführten Windows Store-Apps anzuzeigen, wie in Abbildung 3 gezeigt. Durch einen Rechtsklick auf KIDSCARCOLORS.EXE können Sie die Eigenschaften anzeigen, beispielsweise die Stammordnerinstallation.

Process Explorer from SysInternals
Abbildung 3: Sysinternals Process Explorer

Das Eigenschaftenfenster einer Anwendung in Process Explorer stellt eine Fülle von Informationen bereit. Wie in Abbildung 4 shows, gezeigt wird, können Sie auf der Registerkarte „Image“ den Speicherort einer gegebenen installierten App anzeigen. Sowohl integrierte Apps als auch aus dem Windows Store heruntergeladene Anwendungen verwenden immer den Installationspfad „[Stammordner]\Programme\Windows-Apps“.

Properties of the Kids Car Colors App
Abbildung 4. Eigenschaften der App Kids Car Colors

Auch die Registerkarte „.NET Performance“ ist sehr nützlich. Sie enthält grundlegende Informationen zu Leistungsindikatoren, darunter Heapgrößen, die Anzahl von Generation 0-Auflistungen und den Prozentsatz der in der Garbage Collection (GC) verbrachten Zeit. Anhand dieser Leistungsindikatoren können Sie bewerten, wie effektiv die GC ist, die dazu dient, Speicher freizugeben, wenn Objekte nicht mehr referenziert werden. Es kann notwendig sein, den Code einer Anwendung zu ändern, damit nicht benötigter Speicher besser freigegeben wird. Weitere Informationen zu .NET-Leistungsindikatoren finden Sie unter msdn.microsoft.com/library/w8f5kw2e.

Sie müssen ggf. den Eigentümer und die Berechtigungen des Ordners „C:\Programme\Windows-Apps“ ändern, damit Sie die Anwendungen darin anzeigen können.

In „C:\Programme\Windows-Apps“ sind parallele Ordner für jede der installierten Anwendungen enthalten. Jeder dieser Anwendungsordner hat eine Vielzahl von Informationen, wie im nächsten Abschnitt beschrieben wird.

Der Code

Wie erwähnt, können Sie zu den Installationsverzeichnissen der einzelnen Anwendungen wechseln und dort umfangreiche Informationen zur jeweiligen Anwendung finden, wie ggf. die gesamten MP3-Dateien, Bilder, XAML-Dateien und andere Ressourcen. Die XAML-Dateien für Windows 8.1-Anwendungen liegen jedoch als kompilierte Binärdateien vor, sodass sie nicht untersucht werden können. Es gibt aber eine Vielzahl von Tools, mit denen Sie solche ausführbaren Windows Store-App-Dateien dekompilieren können, die in C# und Visual Basic .NET geschrieben sind.

Wir dekompilieren hier KIDSCARCOLORS.EXE mit dem JustDecompile-Tool von Telerik. Dekompilieren ist ein Prozess, in dem mit einer Anwendungsbinärdatei lesbarer Quellcode generiert wird. Dazu navigieren Sie einfach zum Installationsordner der App wie zuvor erläutert, klicken mit der rechten Maustaste auf KIDSCARCOLORS.EXE und wählen dann „Öffnen mit“ und „JustDecompile“ aus. Wie in Abbildung 5 gezeigt, sehen Sie jetzt den genauen, vom Dekompilierer offenbarten Code. Das Datenmodell in der Anwendung kann leicht entschlüsselt und durchsucht werden. Mit JustDecompile können Sie auf einfache Weise verlorenen Quellcode wiederherstellen oder einen Blick in Assemblys werfen, um die Ursache eines externen Fehlers zu ermitteln. Das bedeutet, dass Sie den Quellcode von praktisch jeder installierten Windows Store-Anwendung anzeigen können.

Decompiling KidsCarColors.exe
Abbildung 5: Dekompilieren von KIDSCARCOLORS.EXE

Es ist bemerkenswert, wie viel Informationen mit diesem Tool verfügbar sind. Bei der Erstellung von Kids Car Colors hat es einige Mühe gemacht, bis der Ton gut funktioniert hat, wenn ein Kind auf die Autofarbe klickt. Aber jetzt wurde der gesamte Code verfügbar gemacht. Wenn Sie im Projekt-Explorer in JustDecompile zum ItemDetailPage-Objekt navigieren, können Sie genau ermitteln, wie die Audiodateien wiedergegeben werden: Abrufen der MP3-Datei aus dem lokalen Speicher, Instanziieren von verschiedenen „MediaElements“, Registrieren von Medienrückrufereignissen, Aufrufen von „SetSource“ usw. Jeder, der diesen Ansatz replizieren möchte, findet ihn hier, verfügbar gemacht für die ganze Welt.

JustDecompile stellt auf der Symbolleiste einige Schaltflächen bereit, darunter die Schaltfläche „Assembly List“ zum Erkunden der von der Anwendung festgelegten Verweise. Schon die Verweise, die eine Windows Store-Anwendung festgelegt hat, lassen erkennen, welche Funktionalität von der Anwendung verwendet wird. Sie sehen zum Beispiel, dass Kids Car Colors das Advertising SDK nutzt. Das macht Sinn, denn die App zeigt Werbung an. Theoretisch ist es allerdings möglich, einen Verweis zu einer nie genutzten Assembly festzulegen. Nehmen Sie einmal an, dass wir die Werbung in der App entfernt haben, aber vergessen haben, den Verweis auf die Assembly für das Advertising SDK zu löschen. Mit JustDecompile sehen Sie genau, welche Version ins Leere läuft, und wie der Code und die Verweise aussehen.

JustDecompile enthält auch ein Feature namens „Find Usages“, mit dem Sie den Visual Studio-Befehl „Alle Verweise suchen“ replizieren können. Klicken Sie einfach bei gedrückter STRG-TASTE auf ein beliebiges Namespace-, Type- oder Member-Element im dekompilierten Code, um eine Liste aller entsprechenden Codeverweise zu erhalten. Das kann eine enorme Hilfe sein, wenn Sie die Funktionsweise einer Anwendung erfahren möchten, Sie aber nicht über den Quellcode verfügen.

Zusammenfassung

Damit Sie als Windows Store-App-Entwickler möglichst effektiv arbeiten können, benötigen Sie gute Kenntnisse in Bezug auf das Debuggen von Anwendungen. Dieser Artikel enthält eine kurze Übersicht über einige Tools und Techniken, mit denen Sie Fehler in Ihrem Code ermitteln und beheben können. Einige der Techniken sind darüber hinaus dazu geeignet, die Funktionsweise von anderen Windows Store-Apps zu erkunden, sogar ohne über den Quellcode zu verfügen.

Bruno Terkaly arbeitet als Entwicklungsexperte für Microsoft. Seine fundierten Kenntnisse sind das Ergebnis langjähriger Programmierungserfahrung mit einer Vielzahl von Plattformen, Sprachen, Frameworks, SDKs, Bibliotheken und APIs. Er schreibt Code, Blogs und referiert live über die Erstellung von cloudbasierten Anwendungen, insbesondere mit der Windows Azure-Plattform. Lesen Sie seinen Blog unter blogs.msdn.com/b/brunoterkaly.

Robert Evans ist Premier Field Engineer und Technical Lead für Windows 8: Windows Store App Labs. Er ist Microsoft Certified Professional Developer und Windows 8 Dev Bootcamp Master Instructor. Evans hat Vorträge bei TechReady, GeekReady und The Tablet Show gehalten, und er war zusätzlich zu zahlreichen Windows 8 Hackathon-Veranstaltungen Gastgeber des Windows 8 Hardware Labs der Microsoft Build-Konferenz. Vor seiner Tätigkeit als Premier Field Engineer hat Evans 12 Jahre als Software Development Engineer bei Microsoft an verschiedenen Produkten wie beispielsweise Xbox Live, MSN und Mobile Engineering sowie im IT-Bereich von Microsoft gearbeitet. Er verfasst außerdem Beiträge für den Premier Field Engineering-Blog, den Sie unter aka.ms/Utg864.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Christophe Nasarre-Soulier (Microsoft)
Christophe Nasarre gehört dem Supportteam in der Entwicklung bei Microsoft an. Er hat seit 1996 als technischer Redakteur an zahlreichen Büchern mitgewirkt und Artikel für das MSDN Magazine verfasst.