Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 22 Min.

Treiber + .NET?

Windows bietet verschiedene Möglichkeiten, mit Treibern zu interagieren – auch mit solchen für eigene Hardware. Etliches davon lässt sich aus .NET heraus nutzen.
© dotnetpro
Das Wort Treiber reicht aus, um vielen Entwicklerinnen und Entwicklern den Schweiß auf die Stirn zu treiben. Mit Treibern hat fast jeder täglich zu tun, entweder aus Anwendersicht im eigenen System oder aus Entwicklersicht, wenn es darum geht, Treiber zu entwickeln, zu testen und im Zuge einer Auslieferung auf einem System zu installieren. Im besten Fall läuft das alles reibungslos. Im schlechtesten Fall funktioniert die entsprechende Hardware nicht, die der Treiber ansteuert, oder es wird das gesamte System lahmgelegt.

.NET und Treiber

Die brennende Frage ist, wie gut sich die .NET-Welt und die Treiber-Welt vereinen lassen. Die kurze Antwort ist: Gar nicht.
So oder so treten zahlreiche Situationen auf, in denen zumindest Basiswissen zu Treibern unter Windows hilfreich ist. Und genau darum geht es in diesem Artikel, in Kombination mit Informationen und einem Minimum Viable Product (MVP) als Use-Case, um auf installierte Treiber in Windows zuzugreifen. Es geht nicht um die Entwicklung und den Test von Treibern, sondern konkreter um die Fehlersuche und die Wege, erkannte Fehler zu beheben. Der Artikel basiert auf einem praktischen Anwendungsfall, Treiberinstallationen auf Kundensystemen zu erkennen und vorhandene Fehler zu analysieren. Die Anforderungen waren darüber hinaus, im besten Fall Fehlersituationen in Kombination mit anderen Treibern zu finden. Diese Fehler sind zu korrigieren, indem Treiber gelöscht und neue installiert werden. Das soll alles in ein kleines Dienstprogramm gegossen werden, sodass die Bedienung aufseiten der Endkunden einfach und unkompliziert ist.Windows bietet einige Methoden an, um mit Treibern und dem Subsystem von Windows, dem Driver Store, zu interagieren. Diese werden wir in diesem Artikel über .NET ansprechen, allerdings nicht direkt aus .NET heraus, sondern über einen kleinen Umweg mit Drittprogrammen von Microsoft. Das ist manchmal etwas hakelig, lässt sich aber mittlerweile gut integrieren und ergibt eine simple, aber effiziente Lösung. Zudem ermöglichen diese Features, die Installation von Treibern direkt in .NET-Anwendungen zu integrieren, ohne extra Setup-Programme für diesen spezifischen Fall bauen zu müssen – ein klarer Vorteil in vielen Anwendungsszenarien.Der Artikel bietet somit einen Überblick über den Treiberspeicher in Windows, Treiberpakete und die beiden Werkzeuge PnPUtil sowie DevCon, um mit Geräten und Treibern zu arbeiten.

Herausforderungen und mögliche Lösungen

Bei der Arbeit mit Treibern unter Windows gibt es zahlreiche Herausforderungen und Wege, diesen zu begegnen. Zum Beispiel bei der Installation von Treibern, die zur eigenen Hardware gehören oder für Fremdhardware mitinstalliert werden müssen, damit die eigene Anwendung funktioniert. Ein gangbarer Weg ist es, das Setup-Programm für diese Treiber einfach mit auszuliefern und es vor oder nach der Installa­tion der eigenen Anwendung aufzurufen. Das funktioniert, und sofern wir uns auf die Rückmeldung dieser Setups verlassen können, ist das nicht zwingend ein schlechter Weg.Darüber hinaus besteht aber auch die Möglichkeit, die Treiber direkt mitzuliefern und über Windows-Bordmittel direkt aus der eigenen Anwendung heraus zu installieren. Das ermöglicht es zudem, ohne große Umwege Updates und eine Deinstallation ebendieser Treiber vorzunehmen. Auch eine Analyse ist möglich, welchen Statuscode Windows für einen bestimmten Treiber zurückgibt. Beispielsweise, ob dieser ordnungsgemäß arbeitet oder ob ein Problem vorliegt. Im letzteren Fall ist dann vielleicht eine Neuinstallation sinnvoll.Die genannten Beispiele sind konkrete Anwendungsfälle, die in der Demo-Anwendung realisiert sind. Das ist einfacher, wenn nicht auf ein extra Setup zurückgegriffen werden muss. Der manuelle Weg über den Geräte-Manager von Windows ist damit vielfach automatisierbar, was insbesondere dann sinnvoll ist, wenn die Anwender mit dem Prozedere nicht vertraut sind oder diese Eingriffe gar nicht vornehmen sollen. Zudem erspart dieses Vorgehen an vielen Stellen den Einsatz von externen (Drittanbieter-)Tools zur Fehleranalyse und Behebung ebendieser Fehler. Wieder eine Fehlerquelle weniger und mehr Kontrolle über den Prozess an sich.Das ist generell eine einfachere Möglichkeit, als die Installation selbst zu implementieren oder manuelle Eingriffe im Betriebssystem vornehmen zu müssen. Das ist zwar nicht immer zu vermeiden, aber wenn wir problemlos darum herumkommen, ist der Weg ein willkommener.

Was ist ein Treiberpaket?

Ein Treiberpaket besteht aus einer Reihe von Komponenten zur Unterstützung eines Geräts unter Windows. Für standardisierte Hardware gibt es zahlreiche standardisierte Treiber, sodass nicht immer eine Eigen- und Neuentwicklung notwendig ist. Für alle Geräte auf einem Windows-System sollte ein Treiberpaket installiert sein. Das System stellt eine Reihe generischer Treiberpakete zur Verfügung, die auf einigen Geräteklassen installiert werden können. In der Regel enthält ein Treiberpaket die Komponenten INF-Datei, Katalogdatei, Treiberdateien und andere Dateien. Zu diesen anderen Dateien gehören beispielsweise Einstellungen für die Kalibrierung der Hardware, ein Win32-Service oder ein Icon für das Gerät.
In diesem Artikel geht es konkret darum, Treiber in Windows zu suchen, zu analysieren und bei Bedarf zu deinstallieren – als abgeschlossener Workflow im Sinne einer Reparaturmaßnahme. Zudem werden die Anwendungsfälle abgedeckt, dass sich Treiber untereinander in die Quere kommen und wie Treiber in einer .NET-Anwendung mitgeliefert und direkt installiert werden können. Die Anwendungsfälle basieren sowohl auf Windows-Funktionen als auch auf manuellen Eingriffen, wie die Beispiele im Artikel zeigen.

Das Windows Driver Kit (WDK)

Wer einen Treiber entwickeln möchte, bekommt von Micro­soft Informationen dazu, was ein Treiber überhaupt ist [1], wie wir das korrekte Treiber-Modell auswählen [2] und wie wir mit der Entwicklung von Windows-Treibern starten können [3]. Insbesondere die Übersicht über die verschiedenen Treiber-Technologien [4] ist wichtig, denn Treiber ist nicht gleich Treiber. Ein guter Einstiegspunkt für diese Informationen und viele weitere ist die Entwickler-Dokumentation zum Thema Windows-Hardware.Für diese Themen ist das Windows Driver Kit (WDK) eine essenzielle Ressource. Die neueste Version ist das Windows 11 WDK, das sich auf allen Betriebssystemen ab Windows 7 und höher installieren und nutzen lässt, inklusive der Server-Varianten von Windows ab der Version 2008 bis 2022. Das WDK hat eine Abhängigkeit zu Visual Studio 2019 und dem Work­load Desktop development with C++, der mitinstalliert werden muss. Anschließend ist das Windows 11 SDK [5] notwendig, bevor das Windows 11 WDK heruntergeladen [6] und installiert werden kann. Alternativ existiert ein Stand-alone-Kommandozeilentool: das Enterprise WDK (EWDK). Enthalten sind die Visual Studio Build Tools, das SDK und das WDK. Ist alles installiert, stehen Templates für die Treiberentwicklung in Visual Studio 2019 zur Verfügung (siehe Bild 1).
Templates in Visual Studio 2019zur Treiberentwicklung mit C++(Bild 1) © Autor
Das Windows Driver Kit (WDK) bietet eine Reihe von Tools, die zum Entwickeln, Analysieren, Erstellen, Installieren und Testen eines Treibers notwendig sind. Das WDK enthält leistungsstarke Verifizierungstools, die helfen, Fehler im Treibercode während des Entwicklungsprozesses zu erkennen, zu analysieren und zu korrigieren. Viele dieser Tools lassen sich sehr früh im Entwicklungsprozess einsetzen, wo sie poten­ziell viel Zeit und Mühe einsparen können.Für alle Nutzer von Visual Studio 2022 gibt es beim Schreiben dieser Zeilen noch immer die schlechte Nachricht, dass die neueste Version der Entwicklungsumgebung nicht vom aktuellen WDK unterstützt wird. Dazu ist aktuell noch die Preview-Version notwendig, die exklusiv für Visual Studio 2022 verfügbar ist [7].Wer noch ein Treiberprojekt auf Basis des Windows Driver Kit 8.1 hat, sollte auf Version 10 migrieren. Microsoft bietet dazu einen Abschnitt [8] in der Dokumentation zur Konvertierung der Projekte von der alten auf die neue Version.

Windows 11 versus 10

Beim Wechsel auf Windows 11 haben sich einige Neuerungen ergeben, von offensichtlichen Dingen wie neuen Development Kits einmal abgesehen. Auch bei der Treiberentwicklung an sich gibt es einige Veränderungen, zum Beispiel bei Treibern für Kameras oder bei den sogenannten Human Interface Devices (HID) und Serial Peripheral Interfaces (SPI). Des Weiteren gibt es neue API-Seiten mit neuen API-Aufrufen. Eine eigene Seite in der Dokumentation [16] zur Treiberentwicklung unter Windows zählt alle Neuerungen auf.

Unterschiedliche Möglichkeiten im Überblick

Es gibt verschiedene Möglichkeiten, um mit Treibern zu interagieren: entweder schon bei der Entwicklung beziehungsweise beim Testen oder wenn bereits Treiber installiert sind. Diese Möglichkeiten umfassen unter anderem die Interak­tion mit INF-Dateien, das Verändern von Boot-Optionen, das Testen und Verifizieren von Treibern, Software-Tracing und das Signieren von Treibern.Im Zusammenhang mit INF-Dateien gibt es die Tools Stamp­inf, InfVerif und Inf2Cat. Damit lassen sich diese Da­teien beispielsweise aktualisieren, verifizieren und testen. Beim Thema des Signierens von Treibern existieren zahlreiche weitere Werkzeuge, wie zum Beispiel CertMgr, MakeCert und SignTool. Zu viele, um sie hier alle aufzuzählen und zu beschreiben.Für das Thema Testen von Treibern gibt es zwei weitere, sehr wichtige Tools, die im weiteren Verlauf des Artikels zum Einsatz kommen. Gemeint sind PnPUtil (pnputil.exe) [9] und die Windows Device Console DevCon (devcon.exe) [10]. Beides sind administrative Werkzeuge, um mit Treibern oder Geräten in Aktion zu treten. Beide sind wichtig, wenn wir Probleme mit Treibern herausfinden wollen, denn dann müssen wir sowohl mit eventuell installierten Treibern arbeiten als auch die Geräte selbst abfragen, welche Statusinformationen und Daten diese zu genutzten Treibern zurückliefern. Beide Tools werden noch genauer vorgestellt.

PnPUtil versus DevCon

Beide Tools überschneiden sich in gewissen Bereichen, was verständlich ist, denn beide müssen mit Geräten hantieren und zum Beispiel nach neuer Hardware suchen können. Dennoch gibt es entscheidende Unterschiede. Wer mit dem Treiberspeicher von Windows arbeiten muss, wird mit PnPUtil glücklich. Treiberpakete auflisten, suchen, hinzufügen und entfernen ist damit kein Problem. Wer Informationen über Geräte braucht, findet bei DevCon ein nützliches Tool. Damit lassen sich Geräte suchen, aktivieren, deaktivieren, installieren, konfigurieren und auch wieder löschen.

Der Windows Driver Store

Bevor sich der Artikel den beiden genannten Werkzeugen widmet, noch einige Infos zu einem wichtigen Konzept: dem Windows Driver Store. Ab Windows Vista ist der Driver Store eine vertrauenswürdige Sammlung von Inbox- und Drittanbieter-Treiberpaketen. Windows verwaltet diese Sammlung an einem sicheren Ort auf der lokalen Festplatte. Nur die Treiberpakete im Driver Store können auf einem Gerät installiert werden. Wird ein Treiberpaket in den Driver Store kopiert, werden alle zugehörigen Dateien kopiert. Dazu gehören die INF-Datei und alle Dateien, die von der INF-Datei referenziert werden. Alle Dateien im Treiberpaket werden als kritisch für die Geräteinstallation angesehen. Die INF-Datei muss auf alle für die Geräteinstallation erforderlichen Dateien verweisen, damit sie im Driver Store vorhanden sind. Verweist die INF-Datei auf eine Datei, die nicht im Treiberpaket enthalten ist, wird das Treiberpaket nicht in den Store kopiert.Der Vorgang des Kopierens eines Treiberpakets in den Driver Store wird als Staging bezeichnet. Ein Treiberpaket muss im Driver Store bereitgestellt werden, bevor das Paket zur Installation von Geräten verwendet werden kann. Daher sind die Bereitstellung eines Treiberpakets und die Installation ­eines Geräts zwei getrennte Vorgänge. Ein Treiberpaket wird für den Driver Store bereitgestellt, indem es verifiziert und validiert wird. Damit das Treiberpaket als vertrauenswürdig eingestuft wird, muss die INF-Datei eine CatalogFile-Direktive im Abschnitt Version enthalten, die den Dateinamen für eine Katalogdatei angibt, die mit der INF-Datei verknüpft ist. Bei der Validierung sind drei Schritte wichtig: Der aktuelle Benutzer benötigt die Berechtigung, das Treiberpaket zu installieren, die INF-Datei des Treiberpakets muss syntaktisch korrekt sein und alle Dateien, auf die in den INF-Dateien verwiesen wird, müssen im Treiberpaket vorhanden sein.Der Driver Store ist wichtig, da wir bei einem Fehler im Zusammenhang mit einem Gerät nicht nur den aktuellen Treiber deinstallieren und das Gerät entfernen müssen, sondern im Zweifel auch den Treiber aus dem Store entfernen müssen, damit dieser beim erneuten Anschließen nicht automatisch wieder installiert wird und die Probleme erneut beginnen. Auch das werden wir im weiteren Verlauf durchführen.

Das Tool pnputil.exe

Starten wir mit dem Tool PnPUtil, das als ausführbare Datei pnputil.exe zur Verfügung steht. Genauer genommen ist die Anwendung in jeder Version von Windows enthalten, beginnend mit Windows Vista. Das Tool befindet sich im Verzeichnis %windir%\system32, sodass kein separates PnPUtil-Download-Paket notwendig ist, weshalb auch keines zur Verfügung steht. Über die Eingabeaufforderung können wir ­direkt loslegen. Eine Empfehlung ist, die Konsole direkt mit Administratorrechten zu starten, weil viele Operationen an Treibern nur damit möglich sind.Über die Kommandozeile lassen sich so verschiedene Aktionen ausführen. PnPUtil ist unsere Anlaufstelle, wenn wir mit Treiberpaketen und dem Driver Store von Windows arbeiten möchten. Beispiele solcher Aktionen sind unter anderem das Hinzufügen eines Treiberpakets zum ­Treiberspeicher, die Installation eines Treiberpakets auf dem System oder das Löschen eines Treiberpakets aus dem Treiberspeicher. Zudem lassen sich alle Treiberpakete auflisten, die sich derzeit im Treiberspeicher befinden. Dabei werden nur Treiberpakete aufgelistet, die keine sogenannten Inbox-Pakete sind. Damit sind Pakete gemeint, die in der Standardinstallation von Windows oder einem Service Pack enthalten sind. Wir bekommen also die zusätzlich installierten Pakete aufgelistet.Die Arbeit mit dem Werkzeug ist denkbar einfach. Es gibt verschiedene Kommandos, die bestimmte Parameter und Schalter haben. Einige dieser Kommandos sind beispielsweise die folgenden:
  • pnputil /enum-drivers
  • pnputil /add-driver
  • pnputil /delete-driver
  • pnputil /export-driver
In der Regel ist eine INF-Datei anzugeben, damit PnPUtil weiß, welche Treiberinformationen gesucht werden. In der Dokumentation [11] dieser Kommandos sind die konkreten Windows-Versionen angegeben, unter denen die Operationen funk­tionieren. Das ist nicht unwichtig, weil es zum Teil erhebliche Unterschiede zwischen Versionen von Windows wie zum Beispiel Windows 10 Version 1607 und Version 2004 gibt. Listing 1 zeigt einen kurzen Ausschnitt aus der Ausgabe des /enum-drivers-Kommandos. Wir bekommen Informationen zu den installierten Treibern. Da das etliche sein können, kann auch die Ausgabe von PnPUtil recht umfangreich sein. Unter Windows 10 Version 1607 lässt sich zum Beispiel das folgende Kommando ausführen:
Listing 1: Ausschnitt aus der Rückgabe von /enum-drivers
Microsoft-PnP-Hilfsprogramm <br/><br/>Veröffentlichter <span class="hljs-string">Name:</span>    oem20.inf <br/><span class="hljs-string">Originalname:</span>            adafruitcircuitplayground<br/>                            .inf <br/><span class="hljs-string">Anbietername:</span>            Adafruit Industries LLC <br/><span class="hljs-string">Klassenname:</span>              Anschlüsse (COM & LPT) <br/>Klassen-<span class="hljs-string">GUID:</span>            {<span class="hljs-number">4</span>d36e978-e325<span class="hljs-number">-11</span>ce-bfc1-<br/>                            <span class="hljs-number">08002</span>be10318} <br/><span class="hljs-string">Treiberversion:</span>          <span class="hljs-number">02</span><span class="hljs-regexp">/25/</span><span class="hljs-number">2016</span> <span class="hljs-number">6.2</span><span class="hljs-number">.2600</span><span class="hljs-number">.0</span> <br/>Name des <span class="hljs-string">Signaturgebers:</span>  Adafruit Industries <br/><br/>Veröffentlichter <span class="hljs-string">Name:</span>    oem85.inf <br/><span class="hljs-string">Originalname:</span>            appleusb.inf <br/><span class="hljs-string">Anbietername:</span>            Apple, Inc. <br/><span class="hljs-string">Klassenname:</span>              USB-Geräte <br/>Klassen-<span class="hljs-string">GUID:</span>            {<span class="hljs-number">88</span>bae032<span class="hljs-number">-5</span>a81<span class="hljs-number">-49</span>f0-bc3d-<br/>                            a4ff138216d6} <br/><span class="hljs-string">Treiberversion:</span>          <span class="hljs-number">10</span><span class="hljs-regexp">/02/</span><span class="hljs-number">2020</span> <span class="hljs-number">486.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span> <br/>Name des <span class="hljs-string">Signaturgebers:</span>  Microsoft Windows Hardware <br/>                            Compatibility Publisher <br/><br/>Veröffentlichter <span class="hljs-string">Name:</span>    oem77.inf <br/><span class="hljs-string">Originalname:</span>            arduino-org.inf <br/><span class="hljs-string">Anbietername:</span>            Arduino Srl <br/>                            (www.arduino.org) <br/><span class="hljs-string">Klassenname:</span>              Anschlüsse (COM & LPT) <br/>Klassen-<span class="hljs-string">GUID:</span>            {<span class="hljs-number">4</span>d36e978-e325<span class="hljs-number">-11</span>ce-bfc1-<br/>                            <span class="hljs-number">08002</span>be10318} <br/><span class="hljs-string">Treiberversion:</span>          <span class="hljs-number">03</span><span class="hljs-regexp">/19/</span><span class="hljs-number">2015</span> <span class="hljs-number">1.1</span><span class="hljs-number">.1</span><span class="hljs-number">.0</span> <br/>Name des <span class="hljs-string">Signaturgebers:</span>  Arduino srl  
/add-driver treiber.inf /install /reboot 
Damit wird ein Treiberpaket, das durch die Datei treiber.inf angegeben ist, zum Treiberspeicher hinzugefügt. Diese Information ist wichtig, da ein Treiberpaket im Driver Store noch nicht bedeutet, dass dieser Treiber auch für ein Gerät installiert ist. Er kann ab jetzt verwendet werden, wird aber im Zweifel noch nicht aktiv genutzt. Dafür ist der Parameter /install zuständig. Dieser installiert oder aktualisiert den Treiber direkt für alle Geräte, die zum Treiber passen. Durch /reboot wird zudem angegeben, dass ein Neustart durchgeführt werden soll, wenn dieser nötig ist, um die Aktion abzuschließen. Die Dokumentation enthält zahlreiche Beispiele [12] für das Tool, ebenso wie eine Auflistung von Rückgabewerten. Einige dieser Beispiele nutzt unsere Demo-Anwendung.

Möglichkeiten über Windows-API-Aufrufe

Wer über die bisher genannten Möglichkeiten hinaus weitere Setup-Funktionen braucht, um zum Beispiel Treiberdaten zu verarbeiten und Installationen anzustoßen, kann die generellen Setup-Funktionen nutzen, um den Inhalt von INF-Dateien zu lesen und zu verarbeiten, den freien Speicherplatz zu berechnen, Dateien zu verschieben und Protokolldateien zu erstellen. Diese Funktionen sind Teil der Geräte- und Treiber-Installationen von Windows, die über das Windows API aufgerufen werden können. Ein guter Einstieg in das Thema ist die Roadmap [17] für die Geräte- und Treiber-Installation. Dort werden alle notwendigen Informationen zusammengefasst und wichtige Schritte beschrieben.

Das Tool devcon.exe

Das zweite Tool im Bunde ist die Windows Device Console oder kurz DevCon. Das Werkzeug steht als ausführbare Datei devcon.exe zur Verfügung, muss aber im Gegensatz zu PnPUtil zunächst heruntergeladen werden, da die Anwendung nicht zum Standard von Windows gehört. Wenn wir allerdings das Windows Driver Kit (WDK) zuvor installiert haben, dann können wir uns dort das Tool für 32 Bit und 64 Bit sowie für ARM herauspicken, zum Beispiel im Verzeichnis %WindowsSdkDir%\tools\x64\devcon.exe.DevCon ist primär für alle wichtig, die Windows-Treiber entwickeln und testen. Diese können DevCon verwenden, um zu überprüfen, ob ein Treiber korrekt installiert und konfiguriert ist, einschließlich der richtigen INF-Dateien, des Treiberstapels, der Treiberdateien und des Treiberpakets. Über die DevCon-Befehle wie aktivieren, deaktivieren, installieren, starten, stoppen und fortsetzen lassen sich zum Beispiel Skripte implementieren, um einen Treiber zu testen. Wir bekommen Informationen über die INF-Dateien, die zu einem Treiber gehören, zu Details eines Treiberpakets und zu dem Status eines Geräts. Insbesondere lässt sich das Tool dazu nutzen, die zu einem Gerät installierten Treiber herauszufinden, sodass im Fehlerfall weitere Analysen möglich sind. Auch das Starten, Stoppen, Aktualisieren und Entfernen von Geräten ist möglich. Wenn wir also mit PnPUtil einen Treiber im Treiberspeicher von Windows hinterlegt haben, lässt sich über DevCon der Treiber zu einem passenden Gerät installieren.Auch DevCon besitzt eine ganze Reihe von Kommandos mit verschiedenen Parametern und Schaltern. Einige dieser Kommandos sind die folgenden:
  • devcon hwids =ports
  • devcon status <ID>
  • devcon driverfiles <ID>
Mit dem ersten Befehl lassen sich alle Hardware-IDs, kompatiblen IDs und Geräte-Instanz-IDs anzeigen, die zu einer bestimmten Klasse gehören. Das wird durch das Gleichheitszeichen angegeben. In diesem Fall lassen wir uns alle Geräte zurückliefern, die in der Klasse Ports Device Setup vorhanden sind. Für die Demo-Anwendungen aus unserem Use-Case sind das genau die Geräte und Treiber, die wir überprüfen möchten. Die IDs der Geräte, die wir dann zurückbekommen, können wir für andere Kommandos nutzen, um die Abfragen auf die jeweiligen Geräte zu beschränken, etwa zum Status eines Geräts oder den installierten Treiberdateien. Alle Kommandos von DevCon sind in der Dokumentation [13] ordentlich aufgeführt und erläutert, ebenso wie zahlreiche Beispiele [14], falls wir nicht weiterkommen. Listing 2 zeigt die Ausgabe des ersten Beispiels mit der Abfrage zu den Ports. Die Daten können wir gut verarbeiten.
Listing 2: Die Abfrage von Ports über DevCon (Ausschnitt)
BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMF&lt;br/&gt;    G&amp;amp;0000\9&amp;amp;B7F0C03&amp;amp;0&amp;amp;000000000000_00000002 &lt;br/&gt;  Name: Standardmäßige Seriell-über-Bluetooth-&lt;br/&gt;    Verbindung (COM14) &lt;br/&gt;  Hardware IDs: &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb}_&lt;br/&gt;      LOCALMFG&amp;amp;0000 &lt;br/&gt;  Compatible IDs: &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb} &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb}_&lt;br/&gt;      GENERIC &lt;br/&gt;BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMF&lt;br/&gt;    G&amp;amp;000A\9&amp;amp;B7F0C03&amp;amp;0&amp;amp;001B10201C9C_C00000000 &lt;br/&gt;  Name: Standardmäßige Seriell-über-Bluetooth-&lt;br/&gt;    Verbindung (COM15) &lt;br/&gt;  Hardware IDs: &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb}_&lt;br/&gt;    LOCALMFG&amp;amp;000a &lt;br/&gt;  Compatible IDs: &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb} &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb}_&lt;br/&gt;      GENERIC &lt;br/&gt;BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMF&lt;br/&gt;    G&amp;amp;000A\9&amp;amp;B7F0C03&amp;amp;0&amp;amp;000D19038490_C00000000 &lt;br/&gt;  Name: Standardmäßige Seriell-über-Bluetooth-&lt;br/&gt;    Verbindung (COM11) &lt;br/&gt;  Hardware IDs: &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb}_&lt;br/&gt;      LOCALMFG&amp;amp;000a &lt;br/&gt;  Compatible IDs: &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb} &lt;br/&gt;    BTHENUM\{00001101-0000-1000-8000-00805f9b34fb}_ &lt;br/&gt;      GENERIC &lt;br/&gt;3 matching device(s) found.  

Die Demo-Anwendung und der Use-Case

Im Use-Case, der in einer Demo-Anwendung als Minimum Viable Product (MVP) gemündet ist, sollen bestimmte Treiber eines an einem COM-Port angeschlossenen Geräts identifiziert und mögliche Probleme ermittelt werden, zum Beispiel über den Status-Code des Geräts, der sich ebenfalls abfragen lässt. Die Informationen des betreffenden Geräts werden in einer Oberfläche angezeigt und ermöglichen es dem Benutzer, die Treiber zu korrigieren und, wenn nötig, die neueste Version zu installieren. Damit lassen sich viele der Fehler beheben, die ansonsten manuell zu korrigieren wären.Zudem ist in dem MVP die Möglichkeit enthalten, Pro­bleme mit der generischen „Seriell-über-Bluetooth-Verbindung“ zu beheben. Auch damit gibt es auf Kundensystemen des Projekts, in dessen Rahmen das MVP entstanden ist, diverse Probleme, die dann Einfluss auf die zuvor genannte Kunden-Hardware haben. Diese Probleme werden mit automatisierten Eingriffen in die Registry behoben. Bild 2 zeigt das MVP nach dem Start. Über die Schaltflächen kann nach Geräten und Treibern gescannt werden. Auch der Start der Reparatur und der Treiberinstallation ist möglich.
Das MVP der Anwendungzur Fehlerkorrektur der Treiberprobleme(Bild 2) © Autor
Die Anwendung ist mit der Windows Presentation Foun­dation unter .NET 6 und C# entstanden. Die Ausgabe ist eine­ Self-contained-Anwendung, die als einzelne Datei erzeugt wird und alle notwendigen Ressourcen und nativen Bibliotheken enthält und beim Start selbst entpackt. Als Entwicklungsumgebung kommt JetBrains Rider zum Einsatz. Im app.manifest der Anwendung fragt der Eintrag
&lt;requestedExecutionLevel level="requireAdministrator" 
  uiAccess="false" /&gt; 
beim Starten der Anwendung Administratorrechte an. Dadurch müssen wir im weiteren Verlauf diese Rechte nicht erneut anfragen. Wichtig ist es, JetBrains Rider für die Entwicklung ebenfalls mit Administratorrechten zu starten, da es ansonsten beim Starten der Anwendung im Debug-Modus nach einem erfolgreichen Build zu der Meldung „Mindestens ein Fehler ist aufgetreten“ kommt, was wenig hilfreich ist.In Bild 3 sind die Workflows für das Scannen, Reparieren und Installieren von Treibern im MVP zu sehen. Diese Schritte werden im Folgenden mit Code-Ausschnitten gezeigt und erläutert, worauf zu achten ist.
Der umgesetzte Workflowfür das Scannen, Reparieren und Installieren von Treibern im MVP(Bild 3) © Autor

Das Scannen nach Geräten

Um den Prozess für den Endkunden so einfach wie möglich zu halten, sollen die beiden Tools PnPUtil und DevCon innerhalb des MPV als .NET-Anwendung genutzt werden. Eine gute Möglichkeit bietet dazu die allseits bekannte Process-Klasse. Beide Tools befinden sich dabei als Ressourcen in der Anwendung und werden, wie zuvor beschrieben, während des Starts ausgepackt. Gemäß Workflow ist die Abfrage der Ports der erste Schritt:
devcon.exe hwids =ports 
Der Code für den Prozess-Start ist in Listing 3 zu sehen. Wir brauchen in diesem Fall keine Shell des Betriebssystems zu nutzen, sodass wir UseShellExecute auf false setzen können. Das Umlenken der Ausgabe bietet die Möglichkeit, die Ausgabe zeilenweise in einem DataReceived-Event zu erhalten. Listing 4 zeigt einen Ausschnitt der dazu notwendigen Implementierung. Wir bekommen die Daten Zeile für Zeile und prüfen zunächst, ob diese nicht leer sind. Anschließend werden die Informationen an einen StringBuilder angefügt, um diesen in einem Protokoll nutzen zu können. Die Auswertung der Rückgabe erfolgt direkt im DataReceived-Event, um ein Device-Objekt mit Leben füllen zu können. In Listing 5 ist ein Ausschnitt der Device-Klasse zu sehen. Damit die Daten im Event landen, ist zunächst der Prozess zu starten, um dann die Daten anzufordern. Das geschieht über die nachfolgenden drei Zeilen, die für jeden Prozess-Aufruf notwendig sind:
Listing 3: Prozess-Start für das Scannen der Ports
var devconHwIDs = new Process &lt;br/&gt;{ &lt;br/&gt;  StartInfo = &lt;br/&gt;  { &lt;br/&gt;    FileName = "devcon.exe", &lt;br/&gt;    UseShellExecute = false, &lt;br/&gt;    CreateNoWindow = true, &lt;br/&gt;    RedirectStandardOutput = true, &lt;br/&gt;    Arguments = "hwids =ports" &lt;br/&gt;  } &lt;br/&gt;};  
Listing 5: Die Datenklasse für ein Gerät
public class Device &lt;br/&gt;{ &lt;br/&gt;  public string Name { get; set; } &lt;br/&gt;  public string Port { get; set; } &lt;br/&gt;  public List&amp;lt;string&amp;gt; HardwareIDs { get; set; } &lt;br/&gt;  public List&amp;lt;string&amp;gt; CompatibleIDs { get; set; } &lt;br/&gt;  public Driver Driver { get; set; } &lt;br/&gt;  &lt;br/&gt;  public Device() &lt;br/&gt;  { &lt;br/&gt;    // ... &lt;br/&gt;  } &lt;br/&gt;}  
Listing 4: Prozess starten und auf Rückgabe warten
var output = new StringBuilder(); &lt;br/&gt;&lt;br/&gt;devconHwIDs.OutputDataReceived += (_, e) =&amp;gt; &lt;br/&gt;{ &lt;br/&gt;  if (!string.IsNullOrEmpty(e.Data)) &lt;br/&gt;  { &lt;br/&gt;    output.AppendLine(e.Data); &lt;br/&gt;    &lt;br/&gt;    // ... &lt;br/&gt;  } &lt;br/&gt;}; &lt;br/&gt;&lt;br/&gt;devconHwIDs.Start(); &lt;br/&gt;&lt;br/&gt;devconHwIDs.BeginOutputReadLine(); &lt;br/&gt;devconHwIDs.WaitForExit();  
devconHwIDs.Start(); 

devconHwIDs.BeginOutputReadLine(); 
devconHwIDs.WaitForExit(); 
Auf diese Weise haben wir, nachdem der Prozess-Aufruf abgeschlossen ist, die Daten aller gefundenen Geräte jeweils in einem Objekt verpackt und können damit weiterarbeiten.Im nächsten Schritt wird der Status desjenigen Geräts abgefragt, das uns für den aktuellen Anwendungsfall ganz konkret interessiert. Wenn das Gerät vorhanden und mit dem System verbunden ist, tauchen die Daten bei der vorherigen Abfrage der Ports auf. In Listing 6 ist der Code für den Prozess-Start abgebildet. Wir nutzen das folgende Kommando von DevCon:
Listing 6: Abfrage des Gerätestatus
var devconDeviceStatus = new Process &lt;br/&gt;{ &lt;br/&gt;  StartInfo = &lt;br/&gt;  { &lt;br/&gt;    FileName = "devcon.exe", &lt;br/&gt;    UseShellExecute = false, &lt;br/&gt;    CreateNoWindow = true, &lt;br/&gt;    RedirectStandardOutput = true, &lt;br/&gt;    Arguments = $"status {device.HardwareIDs[0]}" &lt;br/&gt;  } &lt;br/&gt;};  
devcon status &lt;Hardware-ID&gt; 
Die Hardware-ID kommt dabei aus dem Device-Objekt, das wir zuvor für alle Objekte gefüllt haben. Ein solcher konkreter Aufruf sieht damit wie folgt aus:
devcon status "USB\VID_10C4&amp;PID_85E3&amp;REV_0100" 
Dieser Aufruf liefert beispielsweise die Daten zurück, die in Listing 7 abgebildet sind. Der Eintrag <Name> ist ein Platzhalter für den konkreten Hardware-Namen. Die Verarbeitung erfolgt wie beim vorherigen Process-Aufruf auch.
Listing 7: Der abgefragte Status eines Geräts
USB\VID_10C4&amp;amp;PID_85E3\0001 &lt;br/&gt;  Name: &amp;lt;Name&amp;gt; (COM6) &lt;br/&gt;  The device has the following problem: 39 &lt;br/&gt;1 matching device(s) found.  
Bei diesem Aufruf ist der Status von Interesse. Im besten Fall bekommen wir die Zeichenkette „Driver is running“ zurückgeliefert. Ist etwas nicht in Ordnung, wird ein Fehlercode in der Form „The device has the following problem: 39“ ausgegeben. Die Status-Codes fasst Microsoft in der Dokumentation [15] zum Geräte-Manager zusammen. Die Nummer 39 aus dem Beispiel zuvor bedeutet, dass der Treiber für das angeschlossene Gerät nicht korrekt geladen werden konnte. Ein typischer Fehlerfall, den wir korrigieren möchten.Eine weitere wichtige Information ist, welche Treiberda­teien für ein Gerät installiert wurden. Das erledigt das Kommando driverfiles für uns. Ein Aufruf mit der konkreten Hardware-ID aus den vorherigen Beispielen sieht wie folgt aus:
devcon driverfiles "USB\VID_10C4&amp;PID_85E3&amp;REV_0100" 
Das Ergebnis für das konkrete Beispiel ist in Listing 8 zu finden. Diese Ausgabe bietet uns zahlreiche Informationen. Die Variable <Name> ist wieder ein Platzhalter für den Gerätenamen. Die Ausgabe verrät uns noch weitere wichtige Daten. Zum Beispiel, dass der Treiber aus der INF-Datei C:\WINDOWS\INF\oem78.inf installiert wurde. Wer also schon einmal INF-Dateien nach einem Treiber durchsucht hat, um die Installationsquelle zu finden, kann sich das auf diese Weise ersparen. Zudem bekommen wir die Information, welche weiteren Treiberdateien installiert wurden, inklusive vollständigem Pfad. Wenn wir Zugriff auf diese Dateien brauchen, bekommen wir sie hier auf dem Silbertablett präsentiert. Diese genannten Daten werden in einem Driver-Objekt gespeichert, dessen Klasse in Listing 9 zu sehen ist. Ein Driver-Objekt ist einem Device-Objekt zugeordnet.
Listing 8: Infos zu installierten Treibern eines Geräts
USB\VID_10C4&amp;amp;PID_85E3\0001 &lt;br/&gt;  Name: &amp;lt;Name&amp;gt; (COM3) &lt;br/&gt;  Driver installed from C:\WINDOWS\INF\oem78.inf &lt;br/&gt;      [silabser.Dev]. 3 file(s) used by driver: &lt;br/&gt;    C:\WINDOWS\system32\DRIVERS\silabser.sys &lt;br/&gt;    C:\WINDOWS\system32\DRIVERS\silabenm.sys &lt;br/&gt;    C:\WINDOWS\system32\WdfCoinstaller01009.dll &lt;br/&gt;1 matching device(s) found.  
Listing 9: Die Driver-Klasse für die Daten zu einem Treiber
public class Driver &lt;br/&gt;{ &lt;br/&gt;  public string Name { get; set; } &lt;br/&gt;  public string Status { &lt;br/&gt;    get; set; } &lt;br/&gt;  public int StatusCode { &lt;br/&gt;    get; set; } &lt;br/&gt;&lt;br/&gt;  public string InstalledFrom { &lt;br/&gt;    get; set; } &lt;br/&gt;  public string DriverName { &lt;br/&gt;    get; set; } &lt;br/&gt;  public int DriverFileCount { &lt;br/&gt;    get; set; } &lt;br/&gt;  public List&amp;lt;string&amp;gt; DriverFiles { &lt;br/&gt;    get; set; } &lt;br/&gt;  &lt;br/&gt;  public Driver() &lt;br/&gt;  { &lt;br/&gt;    // ... &lt;br/&gt;  } &lt;br/&gt;}  

Das Reparieren von Treibern

Wer gar nicht an dem Treiber-Status oder den Treiberdateien interessiert ist, kann die vorherigen beiden Schritte durchaus überspringen. Vor einer eventuellen Reparaturmaßnahme den Status einer Hardware zu prüfen ist aber sicherlich keine schlechte Idee.Die Reparatur im hier beschriebenen MVP sieht so aus, dass wir zunächst das Gerät entfernen. Wenn es noch verbunden ist, löschen wir es auf diese Weise aus der Liste der verbundenen und installierten Geräte. Die Aktion ist mit dem Entfernen des Geräts aus dem Geräte-Manager vergleichbar. In Listing 10 ist der Code des Process-Aufrufs zu sehen. Ein wichtiger Unterschied ist, dass wir jetzt ein Terminal von Windows brauchen und damit UseShellExecute auf true ist. Deshalb kommen wir auch nicht mehr so einfach an die Rück­gabedaten heran. Zudem muss der Aufruf mit Verb = “runas“ implementiert sein, was bedeutet, dass der Aufruf mit Administratorrechten durchzuführen ist. Ein konkreter Aufruf mit Hardware-ID sieht wie folgt aus:
Listing 10: Die Daten eines Process-Objekts zum Löschen eines Geräts
var devconRemoveDriver = &lt;br/&gt;    new Process &lt;br/&gt;{ &lt;br/&gt;  StartInfo = &lt;br/&gt;  { &lt;br/&gt;    FileName = "devcon.exe", &lt;br/&gt;    UseShellExecute = true, &lt;br/&gt;    CreateNoWindow = true, &lt;br/&gt;    WindowStyle = ProcessWindowStyle&lt;br/&gt;      .Hidden, &lt;br/&gt;    Verb = "runas", &lt;br/&gt;    Arguments = $"remove {id}" &lt;br/&gt;  } &lt;br/&gt;};  
devcon remove "USB\VID_10C4&amp;PID_85E3" 
Wir nutzen eine andere Hardware-ID, die für einen Aufruf mit dem Kommando remove notwendig ist. Wenn der Aufruf funktioniert hat, bekommen wir eine Rückgabe, die wie folgt aufgebaut ist:
USB\VID_10C4&amp;PID_85E3\0001        : Removed 
1 device(s) were removed. 
Es werden uns noch einmal die Hardware-ID und die konkrete Instanz zurückgemeldet und dazu die Information, ob das Gerät entfernt werden konnte oder nicht. Im Geräte-Manager taucht das Gerät damit auch nicht mehr auf. Aber hier liegt der Knackpunkt: Die Treiber sind noch immer vorhanden. Wenn es das Ziel ist, die Treiber zu korrigieren, zum Beispiel durch ein Update oder eine Neuinstallation, ist dieses Ziel noch nicht erreicht.Dazu verwenden wir das Tool PnP­Util. Dieses können wir wie bisher üblich in einem Process-Aufruf nutzen, um weitere Aktionen auszuführen. Ein Ausschnitt des Aufrufs ist in Listing 11 zu sehen. Der vollständige Aufruf des Befehls lautet:
Listing 11: Das Löschen eines Treibers aus dem Treiberspeicher von Windows
var pnputilDeleteDriver = &lt;br/&gt;    new Process &lt;br/&gt;{ &lt;br/&gt;  StartInfo = &lt;br/&gt;  { &lt;br/&gt;    FileName = "pnputil.exe", &lt;br/&gt;    // ... &lt;br/&gt;    Arguments = "/delete-driver &lt;br/&gt;      treiber\\hsoftvcp.inf &lt;br/&gt;      /uninstall" &lt;br/&gt;  } &lt;br/&gt;};  
pnputil /delete-driver treiber\
  hsoftvcp.inf /uninstall 
In diesem Fall brauchen wir keine spezielle Hardware-ID, denn wir beziehen uns mit diesem Aufruf auf eine konkrete INF-Datei. Diese enthält die Informationen, welcher Treiber gelöscht werden soll.Das Treiber-Unterverzeichnis wird vom MVP selbstständig beim Start angelegt, denn der notwendige Hardware-Treiber wird direkt mitgeliefert. Dadurch existieren die Informationen, die zum Löschen des Treibers aus dem Treiberspeicher notwendig sind, ebenso wie die Infos, die für eine Installa­tion benötigt werden.

Die Installation von neuen Treibern

Diese Installation erfolgt in zwei Schritten. Zum einen scannt das Programm nach neuen Geräten. Das ist einer der Fälle, die sowohl von PnPUtil als auch DevCon abgedeckt werden. Der konkrete Befehl lautet wie folgt:
pnputil /scan-devices 
Dieser wird, wie bisher üblich, in einem­ Process-Aufruf ausgeführt. Dadurch sucht Windows nach neuen Geräten. Ist zum jetzigen Zeitpunkt noch ein Treiber im Treiberspeicher vorhanden, installiert Windows diesen automatisch – auch dann, wenn er nicht funktionieren sollte. Daher ist ein vorheriges Löschen wichtig. Die Installation des Treibers geschieht anschließend über folgenden Aufruf:
pnputil /add-driver treiber\\
  hsoftvcp.inf /install 
Der Befehl bezieht sich erneut auf die konkrete INF-Datei im Unterverzeichnis und nutzt nun die Kombination von /add-driver und /install, um das Treiberpaket nicht nur im Treiberspeicher von Windows zu hinterlegen, sondern direkt für ein Gerät zu nutzen, das im vorherigen Scan-Durchlauf erkannt wurde. Läuft alles problemlos durch, haben wir die Treiber für ein neues Gerät installiert.In der Praxis hat sich dieses Vorgehen bewährt. Das MVP erkennt zuverlässig Fehler von installierten Treibern beziehungsweise den verbundenen Geräten, löscht die Geräte und Treiber und installiert Letztere erneut. Die Installation des Treibers basiert auf einem fertigen Installationsprogramm des Herstellers. Anstatt das Setup-Tool mit auszuliefern und aufrufen zu müssen, werden die Treiberdateien als Ressource in den MVP integriert und beim Starten der Anwendung automatisch entpackt. Das sind spezielle Treiberdateien wie silabenm.sys, silabser.sys und WdfCoInstaller01009.dll, jeweils für x86 und x64, sowie hsoftvcp.cat und hsoftvcp.inf als essenzielle Dateien für ein Treiberpaket.

Manuelle Möglichkeiten über die Windows-Registry

Neben den eher automatischen Lösungen über die beiden Tools gibt es zahlreiche Wege, um Fehlern mit Treiber durch manuelle Eingriffe in die Registry zu begegnen. Auch das ist für einen Fall in das MVP eingebaut worden. Konkret geht es erneut um den Code-39-Fehler, der bereits zuvor im Artikel erläutert wurde. Einen solchen Treiber zu haben, der nicht geladen werden kann, weil er zum Beispiel beschädigt ist oder fehlt, ist ein häufiges Problem, auch bei den ebenfalls schon angesprochenen „Standardmäßigen Seriell-über-Blue­tooth-Verbindungen“ (siehe Bild 4).
Screenshot des Geräte-Managersunter Windows 10 mit weiteren COM-Ports(Bild 4) © Autor
Ein häufiger Grund für den Code 39 sind nicht korrekt installierte oder migrierte Filtertreiber. Das tritt bei CD- und DVD-Geräten auf, aber ebenso bei COM-Verbindungen. ­Eine Möglichkeit ist, diese sogenannten UpperFilters- oder LowerFilters-Einträge aus der Registry zu löschen. In Bild 5 sind verschiedene Einträge zu sehen, die dafür wichtig sind.
Die betreffenden Einträgein der Windows-Registrierung(Bild 5) © Autor
Der folgende Eintrag zeigt beispielsweise auf die Schlüssel, die mit den Ports zu tun haben:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
  Control\Class\{4d36e978-e325-11ce-bfc1-08002be10318} 
Gibt es dort die Einträge UpperFilters und/oder LowerFilters, kann deren Löschen bei der Fehlerbehebung des Codes 39 helfen. Beispielsweise ist der folgende Eintrag vorhanden, wenn es sich um das CD- oder DVD-Laufwerk handelt, das Probleme bereitet:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\
  Control\Class\{4D36E965-E325-11CE-BFC1-08002BE10318} 
Bei dem vorherigen Eintrag zu den Ports ist es wichtig, da­rauf zu achten, dass es den Eintrag mit dem Namen Class vom Typ REG_SZ und den Daten Ports gibt. Dann sind wir an der richtigen Stelle. Gibt es hier einen UpperFilters- oder LowerFilters-Eintrag, dann dürfen diese gelöscht werden.Nach einem anschließenden Windows-Neustart ist der Code 39 dann häufig korrigiert. Im Zweifel kann es auch nicht schaden, die aktuellen Treiber noch einmal neu zu installieren und einen weiteren Neustart einzulegen. Da der Zugriff auf die Windows-Registrierung über die Klasse Registry nicht sonderlich aufwendig ist, lässt sich eine Prüfung auf diese Weise gut implementieren.

Fazit

Über die beiden Werkzeuge PnPUtil und DevCon lassen sich zahlreiche Operationen bezogen auf Treiber, den Treiberspeicher von Windows und angeschlossene Geräte durchführen. Das MVP hat gezeigt, dass beide Tools problemlos in eine .NET-Anwendung integriert werden können, sodass der Ablauf fest vorgegeben ist und eine nette Oberfläche weitere Informationen für den Endkunden bereitstellen kann. Das ist in vielen Szenarien nicht unwichtig. Alternativ lässt sich der gezeigte Workflow auch in einem Skript abbilden, wenn es weniger aufwendig sein soll.Das MVP ist bereits im Testbetrieb bei zahlreichen Kunden und wird in Zukunft zusätzliche Erweiterungen erhalten, um auch für andere Fehlersituationen, Treiber und Geräte gerüstet zu sein. Ebenso ist die Integration beider Werkzeuge eine gute Idee, wenn zum Beispiel Treiber zu einer eigenen Anwendung installiert werden sollen. Das lässt sich dann nämlich direkt mit erledigen, ohne extra Setup-Programme, womöglich sogar noch von Drittanbietern, in den eigenen Installationsprozess einbinden zu müssen.Der Artikel hat erste Einblicke gegeben, wie die Tools PnP­Util und DevCon genutzt werden können, welche Kommandos es darin gibt und wie die Daten aussehen, die zurückkommen. Die verlinkten Dokumentationen von Microsoft enthalten noch viele weitere Informationen und Beispiele, da in ­einem einzelnen Artikel nicht alles angesprochen werden kann. Wer also mit Treibern und Hardware-Geräten umgehen können muss, sollte einen Blick auf die beiden Werkzeuge werfen, bevor über eine vollständige eigene Lösung nachgedacht wird.
Projektdateien herunterladen

Fussnoten

  1. Informationen zu Treibern, http://www.dotnetpro.de/SL2209Treibersuche1
  2. Auswahl eines Treiber-Modells, http://www.dotnetpro.de/SL2209Treibersuche2
  3. Einstieg in Windows-Treiber, http://www.dotnetpro.de/SL2209Treibersuche3
  4. Übersicht über verschiedene Treiber-Technologien, http://www.dotnetpro.de/SL2209Treibersuche4
  5. Download des Windows 11 SDK, http://www.dotnetpro.de/SL2209Treibersuche5
  6. Download des Windows 11 WDK, http://www.dotnetpro.de/SL2209Treibersuche6
  7. Preview-Version des WDK für Visual Studio 2022, http://www.dotnetpro.de/SL2209Treibersuche7
  8. Konvertierung von WDK 8.1 auf WDK 10, http://www.dotnetpro.de/SL2209Treibersuche8
  9. Informationen zum Tool PnPUtil, http://www.dotnetpro.de/SL2209Treibersuche9
  10. Informationen zum Tool DevCon, http://www.dotnetpro.de/SL2209Treibersuche10
  11. Kommandos von PnPUtil, http://www.dotnetpro.de/SL2209Treibersuche11
  12. Beispiele zu PnPUtil, http://www.dotnetpro.de/SL2209Treibersuche12
  13. Kommandos von DevCon, http://www.dotnetpro.de/SL2209Treibersuche13
  14. Beispiele zu DevCon, http://www.dotnetpro.de/SL2209Treibersuche14
  15. Status-Codes des Windows-Geräte-Managers, http://www.dotnetpro.de/SL2209Treibersuche15
  16. Änderungen in der Treiber-Entwicklung zwischen Windows 10 und 11, http://www.dotnetpro.de/SL2209Treibersuche16
  17. Roadmap zur Geräte- und Treiber-Installation unter Windows, http://www.dotnetpro.de/SL2209Treibersuche17

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

Mehr Code, weniger Scrollen
Wie der BenQ RD280U und die RD-Serie die Produktivität von Entwicklern steigern (Sponsored Post)
3 Minuten
24. Jun 2025
UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige