Windows-Fehlercodes lesen — die dreischichtige Struktur von Win32-Fehlern, HRESULT und NTSTATUS
· Aktualisiert am: · Go Komura · Windows, Fehlercodes, HRESULT, NTSTATUS, Win32 API, Fehleruntersuchung, Debugging, Windows-Entwicklung
Änderungsverlauf (Erstfassung, veröffentlicht am 20. Aug 2026)
- Erstveröffentlichung
Diesen Artikel zitieren(DOI (registriertes Archiv): 10.5281/zenodo.22176033)
Die folgenden DOIs verweisen auf bereits archivierte Versionen, die vom aktuellen Text abweichen können. Verwenden Sie die URL dieser Seite, um auf den aktuellen Text zu verweisen.
Go Komura (2026). Windows-Fehlercodes lesen — die dreischichtige Struktur von Win32-Fehlern, HRESULT und NTSTATUS. KomuraSoft LLC. https://comcomponent.com/de/blog/windows-error-codes-win32-hresult-ntstatus/
- DOI (registriertes Archiv)
- 10.5281/zenodo.22176033
- DOI (zuletzt registrierte Version)
- 10.5281/zenodo.22176034
„Auf dem App-Bildschirm erschien der Fehler 0x80004005. Was bedeutet das?“ — In der Störungsuntersuchung ist das eine klassische Frage. Wer die Zahl so sucht, erhält Maßnahmen für unzusammenhängende Situationen: Windows Update, freigegebene Ordner, VBA, Datenbankverbindungen.
Die Suchergebnisse zerstreuen sich, weil 0x80004005 (E_FAIL) ein generischer Code ist, der nur „Fehlschlag ohne nähere Angaben“ bedeutet. 0x80070005 dagegen lässt sich zerlegen in „Win32-Fehlernummer 5 = Zugriff verweigert, als HRESULT umgepackt“. Ähnlich aussehende Codes tragen unterschiedliche Informationsmengen.
Windows hat drei Systeme — Win32-Fehlercodes, HRESULT und NTSTATUS — und ein Code wird umgewandelt, wenn er eine Schicht überschreitet. Untersuchungen werden schneller, wenn Sie Zahlen nicht auswendig lernen, sondern „welche Schicht, wer ihn zurückgegeben hat“ und „was der Code vor dem Umpacken war“ unterscheiden.
Dieser Artikel ist ein Praxisleitfaden für IT-Verantwortliche in kleinen und mittleren Unternehmen und für Entwickler von Windows-Anwendungen. Gestützt auf Microsoft Learn und die öffentliche Spezifikation [MS-ERREF] vom August 2026 verbindet er der Reihe nach, wie man die drei Systeme unterscheidet, ein HRESULT zerlegt, den Bezug zu .NET-Ausnahmen und die Suche mit err.exe und PowerShell.
1. Zuerst das Fazit
Zuerst halten Sie die folgenden drei Punkte fest.
- Die Schreibweise angleichen und das Codesystem erkennen. Win32-Fehlercodes, HRESULT und NTSTATUS sind getrennte Systeme. Dezimal und Hexadezimal sind verschiedene Schreibweisen desselben Werts, und ein HRESULT erscheint manchmal als vorzeichenbehaftete negative Zahl. Gleichen Sie zuerst auf acht Hexadezimalstellen und lesen Sie zusammen mit der API, die ihn zurückgegeben hat, und dem Ort, an dem er angezeigt wurde.123
- 0x8007xxxx zerlegen; bei E_FAIL zur Kontextuntersuchung übergehen. 0x80070005 ist ein HRESULT mit FACILITY_WIN32 (7), und die unteren 16 Bit sind 5 = ERROR_ACCESS_DENIED. 0x80004005 (E_FAIL) dagegen ist ein „nicht näher bezeichnetes Fehlschlagen“, und der Code allein grenzt die Ursache nicht ein.456
- Die Bedeutung des Codes zusammen mit dem fehlgeschlagenen Vorgang und dem Ziel untersuchen. Derselbe Fehler 5 hat Ursachen von ACL über Rechteerhöhung bis Sicherheitssoftware. Das Ziel von Fehler 2 kann eine abhängige DLL sein, und eine gehaltene Datei erscheint als Fehler 32. Haben Sie den Namen, gehen Sie mit Protokollen und Process Monitor zu „welche API ist woran gescheitert“.1
Als Werkzeuge unterscheiden Sie das in Windows eingebaute certutil -error und net helpmsg, PowerShells Win32Exception, err.exe auf der Entwicklungsmaschine und WinDbgs !error während der Abbildanalyse.789 Auch wenn daraus bereits eine .NET-Ausnahme geworden ist, lässt sich das ursprüngliche HRESULT über Exception.HResult nachverfolgen.10
Lesen nach Ziel
| Was Sie wissen wollen | Zu lesender Abschnitt |
|---|---|
| Den Code vor Ihnen erkennen und sofort nachschlagen | In Kapitel 2 die Schreibweise angleichen, dann zu den Befehlen in Kapitel 7 und dem Ablauf in Kapitel 8 |
| Fehlschläge von Win32-APIs korrekt protokollieren | GetLastError und FormatMessage in Kapitel 3, P/Invoke in Abschnitt 6.3 |
| Das Verhältnis von 0x80004005, 0x80070005 und .NET-Ausnahmen verstehen | Zerlegung von HRESULT in Kapitel 4, COM und .NET in Kapitel 6 |
| Absturzcodes wie 0xC0000005 nachschlagen | NTSTATUS und STOP-Codes in Kapitel 5, WinDbg in Abschnitt 7.4 |
| Häufige Verwechslungen in der Untersuchung vermeiden | Die Fehldeutungen in Kapitel 9 |
In einem Satz ist das Muster einer Windows-Fehlercode-Untersuchung „die Schreibweise auf Hex angleichen → bestimmen, welcher Schicht der Code angehört → zerlegen und den wesentlichen Code herausnehmen → zusammen mit dem Kontext lesen“.
In der Abbildung kennzeichnet eine durchgezogene Linie eine stets geltende Beziehung und eine gestrichelte Linie eine bedingte (die Bedingungen stehen bei jeder Beziehung auf der Detailseite). Die vollständige Liste der Beziehungen (18 insgesamt, mit Beleg und Sicherheitsgrad) und die Definitionen der wichtigsten Konzepte sind auf der Detailseite der Wissenskarte (auf Japanisch) zusammengestellt. Daten: JSON-LD / Turtle
2. Windows hat drei Fehlercodesysteme
Zuerst das Gesamtbild. Dieselbe Zahl liest sich anders, je nachdem, als Wert welchen Systems sie übergeben wurde. Die wichtigsten Zurückgeber und das typische Aussehen stehen so nebeneinander.
| System | Wichtigster Zurückgeber | Typisches Aussehen | Repräsentatives Beispiel |
|---|---|---|---|
| Win32-Fehlercode | Win32-API (GetLastError), Exit-Code eines Befehls |
Kleine Dezimalzahl (0–15999) | 5 = ERROR_ACCESS_DENIED |
| HRESULT | COM-Komponente, Shell, Installer, viele Frameworks | Achtstelliges Hex beginnend mit 0x8 oder eine negative Dezimalzahl | 0x80004005 = E_FAIL |
| NTSTATUS | Kernel, Treiber, native API (ntdll) | Fehler sind achtstelliges Hex beginnend mit 0xC | 0xC0000005 = STATUS_ACCESS_VIOLATION |
Das „Aussehen“ in dieser Tabelle ist ein Anhalt, um das System zu suchen. Wie die Entscheidungstabelle in Kapitel 8 verwenden Sie es als ersten Kandidaten und gleichen mit der API oder Komponente ab, die ihn zurückgegeben hat.
Historisch stapelten sie sich: Win32-Fehlercodes, die Nummern aus MS-DOS erbten, NTSTATUS im Inneren des NT-Kernels und HRESULT, entworfen bei der Einführung von COM, um Erfolg/Fehlschlag und Ursprung in 32 Bit zu packen.
Unter aktuellem Windows ist die Umwandlung NTSTATUS des Kernels → Win32-Fehlercode → HRESULT der COM-Schicht Alltag. Von dem Code, den Sie in der oberen Schicht sehen, zur unteren Schicht zurückzugehen, ist die Grundlage der Untersuchung.114
flowchart TB
accTitle: Umwandlungsfluss über die drei Systeme
accDescr: Der Kernel gibt ein NTSTATUS zurück, das Win32-Subsystem wandelt es in einen Win32-Fehlercode um, und die COM-Schicht packt es weiter als HRESULT um
kernel["Kernel und Treiber"] --> nt["NTSTATUS (Fehler sind 0xC…)"]
nt -->|Win32-Subsystem wandelt um| win["Win32-Fehlercode (etwa 5)"]
win -->|COM-Schicht packt um| hr["HRESULT (0x8007xxxx)"]
Abbildung 1: Umwandlungsfluss über die Schichten. Das NTSTATUS des Kernels wird zum Win32-Fehler und weiter als HRESULT umgepackt.
2.1. Dezimal und Hexadezimal umlesen lernen
Bevor Sie das System bestimmen, beseitigen Sie Schwankungen der Schreibweise. Derselbe Code erscheint als Dezimal, Hexadezimal oder vorzeichenbehaftete negative Zahl.
| Angezeigter Wert | Derselbe Wert in anderer Schreibweise | Bedeutung |
|---|---|---|
| Fehler 5 | 0x5 | ERROR_ACCESS_DENIED |
| Fehler 1223 | 0x4C1 | ERROR_CANCELLED |
| 0x80070005 | -2147024891 | dasselbe HRESULT |
In PowerShell lesen Sie in einer Zeile um.
# Dezimal → Hexadezimal
'0x{0:X8}' -f 1223 # 0x000004C1
'0x{0:X8}' -f -2147024891 # 0x80070005 (negativ = HRESULT nach Hex)
# Hexadezimal → Dezimal
0x4C1 # 1223
Sehen Sie eine negative Dezimalzahl, die mit „-214…“ beginnt, wandeln Sie sie reflexartig ins Hexadezimal um. Allein das verringert das Verlaufen am Eingang der Untersuchung deutlich.
flowchart TB
accTitle: Drei Erscheinungsformen desselben Codes
accDescr: Die Dezimalzahl Fehler 5, das Hexadezimal 0x5 und die unteren 16 Bit von 0x80070005 zeigen alle ERROR_ACCESS_DENIED
d["Dezimalschreibweise „Fehler 5“"] --> same["ERROR_ACCESS_DENIED"]
h["Hexadezimalschreibweise „0x5“"] --> same
l["Untere 16 Bit von 0x80070005"] --> same
same -.-> memo["Nur die Schreibweise unterscheidet sich, der Code ist derselbe"]
Abbildung 2: Dezimal, Hexadezimal und die unteren 16 Bit eines HRESULT sind nur andere Schreibweisen desselben Codes.
3. Win32-Fehlercodes — GetLastError und FORMAT_MESSAGE
3.1. Grundverhalten von GetLastError
Zuerst den Rückgabewert prüfen, dann den letzten Fehler speichern
Viele Win32-APIs wie CreateFile zeigen den Fehlschlag am Rückgabewert (FALSE, NULL, INVALID_HANDLE_VALUE und Ähnliches) und hinterlassen die Einzelheiten im threadsicheren „letzten Fehlercode“. Bei APIs dieses Musters holen Sie ihn unmittelbar nach dem festgestellten Fehlschlag mit GetLastError.12
Wie der Fehler geholt wird, prüfen Sie jedoch je API. RegOpenKeyEx etwa gibt den Fehlercode selbst als Rückgabewert zurück, nicht den letzten Fehler. Behandeln Sie das getrennt von Beispielen, die GetLastError verwenden.13
Beim Einsatz von GetLastError gelten die folgenden zwei Punkte.12
- Unmittelbar nach dem Fehlschlag lesen. Schieben Sie einen anderen API-Aufruf (etwa eine Protokollfunktion) dazwischen, kann dieser Aufruf den letzten Fehlercode überschreiben.
- Sich nicht auf den Wert bei Erfolg verlassen. Manche APIs setzen den letzten Fehlercode bei Erfolg auf 0, andere fassen ihn nicht an. Grundsatz ist, den Fehlschlag am Rückgabewert zu prüfen und dann zu lesen.
sequenceDiagram
accTitle: GetLastError unmittelbar nach dem Fehlschlag lesen
accDescr: Nach dem Fehlschlag am Rückgabewert holen Sie den letzten Fehlercode unmittelbar mit GetLastError, ohne einen anderen API-Aufruf dazwischenzuschieben
participant app as App
participant api as Win32 API
app->>api: CreateFile-Aufruf
api-->>app: Rückgabewert des Fehlschlags
app->>api: GetLastError
api-->>app: Code 5
Note over app: Ein anderer API-Aufruf dazwischen kann überschreiben
Abbildung 3: Den letzten Fehlercode unmittelbar nach dem Fehlschlag lesen. Ein anderer API-Aufruf dazwischen kann überschreiben.
Den gespeicherten Code zusammen mit der Meldung ins Protokoll schreiben
Die Meldungszeichenfolge zum Code holen Sie mit FormatMessage und dem Flag FORMAT_MESSAGE_FROM_SYSTEM. Die Reihenfolge ist: zuerst den Code speichern, danach in eine Zeichenfolge wandeln.1
#include <windows.h>
#include <stdio.h>
void PrintLastError(const wchar_t* apiName)
{
DWORD code = GetLastError(); // Unmittelbar nach dem Fehlschlag (keine andere API dazwischen)
wchar_t message[512] = L"";
FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, code, 0, message, 512, nullptr);
wprintf(L"%s failed: %lu (0x%08lX) %s", apiName, code, code, message);
}
Im Protokoll einer eigenen App Dezimal und Hexadezimal zusammen mit dem Meldungstext zu hinterlassen beschleunigt die spätere Untersuchung.
flowchart TB
accTitle: Aus dem Code die Meldung holen und ins Protokoll schreiben
accDescr: Mit FormatMessage und dem Flag FORMAT_MESSAGE_FROM_SYSTEM die Meldungszeichenfolge zum Fehlercode holen und im Protokoll Dezimal, Hexadezimal und den Meldungstext hinterlassen
code["Fehlercode (Beispiel: 5)"] --> fm["Zeichenfolge mit FormatMessage holen"]
fm --> msg["Meldungstext"]
msg --> log["Ins Protokoll schreiben"]
log -.-> both["Dezimal, Hexadezimal und Text nebeneinander"]
Abbildung 4: Einen Fehlercode mit FormatMessage in eine Meldungszeichenfolge wandeln und im Protokoll Dezimal, Hexadezimal und den Text nebeneinander hinterlassen.
3.2. Häufige Codes in der Praxis
Win32-Fehlercodes sind im Bereich 0–15999 definiert; Microsoft Learn hat die vollständige Liste.1 In der Störungsuntersuchung begegnen Ihnen wiederholt die folgenden.
| Dezimal | Hex | Symbol | Bedeutung |
|---|---|---|---|
| 2 | 0x2 | ERROR_FILE_NOT_FOUND | Die angegebene Datei wurde nicht gefunden |
| 3 | 0x3 | ERROR_PATH_NOT_FOUND | Der angegebene Pfad wurde nicht gefunden |
| 5 | 0x5 | ERROR_ACCESS_DENIED | Zugriff verweigert |
| 32 | 0x20 | ERROR_SHARING_VIOLATION | Ein anderer Prozess verwendet das Ziel, Zugriff nicht möglich |
| 87 | 0x57 | ERROR_INVALID_PARAMETER | Der Parameter ist falsch |
| 122 | 0x7A | ERROR_INSUFFICIENT_BUFFER | Der übergebene Puffer ist zu klein |
| 998 | 0x3E6 | ERROR_NOACCESS | Ungültiger Zugriff auf eine Speicherstelle |
| 1223 | 0x4C1 | ERROR_CANCELLED | Der Vorgang wurde vom Benutzer abgebrochen |
Leicht zu verwechseln sind Nummer 5 und Nummer 998. 998 (ERROR_NOACCESS) ist kein „Zugriff verweigert“, sondern die Win32-Darstellung einer Speicherzugriffsverletzung. Es ist die Gestalt, in die das später behandelte NTSTATUS STATUS_ACCESS_VIOLATION auf der Win32-Schicht umgewandelt wird.
1223 (ERROR_CANCELLED) erscheint etwa, wenn Sie im UAC-Erhöhungsdialog „Nein“ wählen. Lesen Sie ihn nicht einfach als Störung, sondern als Code, der anzeigt, dass der Vorgang „abgebrochen“ wurde.
flowchart TB
accTitle: Fehler 998 und 5 sind verschieden
accDescr: 998 ist die Speicherzugriffsverletzung, in die eine NTSTATUS-Zugriffsverletzung auf der Win32-Schicht umgewandelt wurde, und bedeutet etwas anderes als 5, das Zugriff verweigert
nt["NTSTATUS 0xC0000005"] -->|Umwandlung auf die Win32-Schicht| e998["Fehler 998 (ERROR_NOACCESS)"]
e998 -.-> m1["Bedeutung: Speicherzugriffsverletzung"]
e5["Fehler 5 (Zugriff verweigert)"] -.-> m2["Rechteproblem. Etwas anderes als 998"]
Abbildung 5: Fehler 998 ist die auf die Win32-Schicht umgewandelte NTSTATUS-Zugriffsverletzung und etwas anderes als 5, Zugriff verweigert.
3.3. Derselbe Code ändert die Bedeutung mit dem Kontext
Die repräsentativen Codes zu kennen reicht nicht, um die Ursache zu bestimmen. Der Code lehrt nur die „Art des Fehlschlags“; danach bleibt, was Sie untersuchen.
| Code | Was sich mit dem Kontext ändert | Was Sie als Nächstes prüfen |
|---|---|---|
| Fehler 5 (Zugriff verweigert) | Unzureichende NTFS-ACL, Schreiben in einen geschützten Bereich ohne Administratorrechte, Blockade durch Antivirus oder AppLocker, unzureichende Rechte eines Dienstkontos und mehr | Welche API den Zugriff auf welches Ziel verweigert bekommen hat |
| Fehler 2 (Datei nicht gefunden) | Nicht unbedingt die angegebene Datei; eine implizit geladene abhängige DLL, eine Einstellungsdatei an einem anderen Ort durch 32-/64-Bit-Registrierungsumleitung, ein Pfad, dessen Umgebungsvariable nicht expandiert wurde, und mehr | „Welche Datei“ nicht gefunden wurde |
| Fehler 32 (Freigabeverletzung) | Ein anderer Prozess verwendet das Ziel | „Welcher Prozess“ es hält |
flowchart TB
accTitle: Die Ursache von Fehler 5 entscheidet der Kontext
accDescr: Auch bei demselben Zugriff verweigert gibt es mehrere Ursachkandidaten wie unzureichende ACL oder fehlende Administratorrechte, und es ist nötig zu bestimmen, welche API woran gescheitert ist
e5["Fehler 5 (Zugriff verweigert)"] --> c1["Unzureichende ACL"]
e5 --> c2["Keine Administratorrechte"]
e5 --> c3["Blockade durch Sicherheitssoftware"]
e5 --> c4["Unzureichende Dienstechte"]
c1 --> next["Mit Procmon das fehlgeschlagene Ziel bestimmen"]
c2 --> next
c3 --> next
c4 --> next
Abbildung 6: Der Code lehrt nur die „Art des Fehlschlags“. Fehler 5 hat mehrere Ursachkandidaten, und das Ziel muss bestimmt werden.
Das Werkzeug, das „welche API gegen welchen Objektnamen welchen Resultatwert zurückgegeben hat“ misst, ist Process Monitor. Die Bedienung behandelt „Process Monitor (ProcMon) Praxisleitfaden“ ausführlich. Die Bedeutung des Fehlercodes nachzuschlagen und das fehlgeschlagene Ziel zu bestimmen, betrachten Sie als zwei Räder desselben Wagens.
4. HRESULT — die in 32 Bit gepackte Struktur lesen
4.1. Bit-Layout
HRESULT packt Erfolg/Fehlschlag, Ursprung und Detailcode in einen 32-Bit-Wert. Wenn Sie zuerst am S-Bit Erfolg/Fehlschlag, an Facility den Ursprung und an Code das Detail sehen, folgen die späteren Zerlegungsbeispiele leichter. Das Layout der öffentlichen Spezifikation [MS-ERREF] ist das folgende.2
| Bitposition | Name | Bedeutung |
|---|---|---|
| 31 | S | Schweregrad. 0 = Erfolg, 1 = Fehlschlag |
| 30 | R | Reserviert (beim NTSTATUS-Mapping Teil des Schweregrads) |
| 29 | C | Customer-Bit. 1, wenn der Code nicht von Microsoft definiert ist |
| 28 | N | 1, wenn ein NTSTATUS-Wert in den HRESULT-Raum abgebildet wurde |
| 27 | X | Reserviert (0) |
| 26–16 | Facility | Facility-Code, der den Ursprung angibt (11 Bit) |
| 15–0 | Code | Detailcode innerhalb der Facility (16 Bit) |
Ist das höchstwertige S-Bit 1, also ein HRESULT, dessen Hexadezimalschreibweise mit 0x8 oder höher beginnt, ein Fehlschlag. Als vorzeichenbehaftete 32-Bit-Ganzzahl angezeigt wird er negativ — das ist der Ursprung des erwähnten „-214…“.
flowchart TB
accTitle: Zusammenhang von S-Bit und negativer Anzeige
accDescr: Ein fehlgeschlagenes HRESULT hat das höchstwertige S-Bit 1, beginnt daher im Hexadezimal mit 0x8 oder höher und wird als vorzeichenbehaftete 32-Bit-Ganzzahl negativ
s["S-Bit = 1 (Fehlschlag)"] --> hex["Hexadezimal beginnt mit 0x8 oder höher"]
hex --> neg["Vorzeichenbehaftete Anzeige wird negativ"]
neg --> back["Eine negative Zahl zuerst ins Hexadezimal wandeln und dann lesen"]
Abbildung 7: Ein fehlgeschlagenes HRESULT hat das S-Bit 1, beginnt daher mit 0x8 oder höher und wird in vorzeichenbehafteter Anzeige negativ.
Facility ist ein Anhalt, welche Unterlage Sie als Nächstes aufschlagen
Repräsentative Facility-Werte sind die folgenden. 7 bedeutet Umpacken eines Win32-Fehlers, 4 eine Definition je Schnittstelle — so lesen Sie sie auseinander.5
| Facility | Wert | Hexadezimales Aussehen | Bedeutung |
|---|---|---|---|
| FACILITY_NULL | 0 | 0x8000xxxx | Weit gemeinsam genutzte Codes (E_FAIL, E_UNEXPECTED und Ähnliches) |
| FACILITY_RPC | 1 | 0x8001xxxx | Von RPC stammend |
| FACILITY_ITF | 4 | 0x8004xxxx | Fehler der Schnittstellendefinition (die Bedeutung hängt von der Schnittstelle ab) |
| FACILITY_WIN32 | 7 | 0x8007xxxx | Umpacken eines Win32-Fehlercodes |
| FACILITY_WINDOWS | 8 | 0x8008xxxx | Zusätzliche von Microsoft definierte Schnittstellen |
4.2. 0x80004005 und 0x80070005 zerlegen
Zwei ähnlich aussehende Codes vergleichen wir, getrennt nach S, Facility und Code.
| Abzulesendes Feld | 0x80004005 | 0x80070005 |
|---|---|---|
| S | 1 (Fehlschlag) | 1 (Fehlschlag) |
| Facility | 0 (FACILITY_NULL) | 7 (FACILITY_WIN32) |
| Code | 0x4005 | 0x0005 = 5 |
| Definition | E_FAIL: nicht näher bezeichnetes Fehlschlagen | E_ACCESSDENIED: Zugriff verweigert |
| Nächste Untersuchung | Die zurückgebende Komponente und begleitende Protokolle untersuchen | Als Win32-Fehler 5 den verweigerten Vorgang und das Ziel untersuchen |
0x80004005 grenzt die Ursache am Code allein nicht ein. Facility ist (0x80004005 >> 16) & 0x7FF = 0, der generische Code E_FAIL von FACILITY_NULL. Er trägt nicht mehr als „Unspecified failure“ (nicht näher bezeichnetes Fehlschlagen), deshalb verlagern Sie nach der Zerlegung den Schwerpunkt der Untersuchung auf „welche Komponente ihn zurückgegeben hat“ und „ob Ereignisprotokoll und App-Protokoll zur selben Zeit Einzelheiten enthalten“.6
0x80070005 lässt sich bis zum Win32-Fehler 5 zurückverfolgen. Facility = 7, Code = 5, also der als HRESULT umgepackte ERROR_ACCESS_DENIED. Der Alias E_ACCESSDENIED hat denselben Wert.6
Auch beim selben „Fehlschlag“ unterscheidet sich die Informationsmenge nach der Zerlegung. Legen Sie E_FAIL nicht als Zugriff verweigert fest; wählen Sie die nächste Untersuchung nach dem zurückgekommenen Wert.
flowchart TB
accTitle: Zerlegung von 0x80004005 und 0x80070005
accDescr: 0x80004005 ist der generische Code E_FAIL von FACILITY_NULL ohne Detail und sollte zur Kontextuntersuchung übergehen; 0x80070005 ist FACILITY_WIN32, das Umpacken von Win32-Fehler 5, Zugriff verweigert
a["0x80004005"] --> af["Facility = 0 (FACILITY_NULL)"]
af --> ac["Code = 0x4005 → E_FAIL"]
ac --> ax["Nicht näher bezeichnetes Fehlschlagen. Zur Kontextuntersuchung"]
b["0x80070005"] --> bf["Facility = 7 (FACILITY_WIN32)"]
bf --> bc["Code = 0x0005 → 5"]
bc --> bx["ERROR_ACCESS_DENIED"]
Abbildung 8: Auch beim selben „Fehlschlag“ unterscheidet sich die Informationsmenge nach der Zerlegung. 0x80070005 lässt sich bis zum Win32-Fehler 5 zurückverfolgen.
4.3. Das wichtigste Muster: 0x8007xxxx = HRESULT_FROM_WIN32
Einen Win32-Fehlschlag als HRESULT umpacken
Damit eine untere Schicht einen Win32-Fehler an eine COM-Methode oder die .NET-Laufzeit weitergeben kann, die ein HRESULT zurückgibt, gibt es in winerror.h HRESULT_FROM_WIN32. Im folgenden Beispiel eines Fehlschlagcodes stehen der Win32-Fehler in den unteren 16 Bit, 7 in Facility und 1 im S-Bit.4
flowchart TB
accTitle: Verhalten von HRESULT_FROM_WIN32
accDescr: Einen Win32-Fehlercode in den unteren 16 Bit ablegen, Facility auf 7 und das S-Bit auf 1 setzen und ein HRESULT 0x8007xxxx zusammenbauen
win["Win32-Fehlercode (Beispiel: 5)"] --> low["In den unteren 16 Bit ablegen"]
low --> fac["Facility auf 7 setzen"]
fac --> sbit["S-Bit auf 1 setzen"]
sbit --> hr["0x80070005"]
Abbildung 9: HRESULT_FROM_WIN32 legt den Win32-Fehler in den unteren 16 Bit ab und setzt Facility = 7 und das S-Bit.
ERROR_ACCESS_DENIED (5) --HRESULT_FROM_WIN32--> 0x80070005
ERROR_SHARING_VIOLATION (32) --HRESULT_FROM_WIN32--> 0x80070020
ERROR_INVALID_PARAMETER (87) --HRESULT_FROM_WIN32--> 0x80070057 (= E_INVALIDARG)
ERROR_OUTOFMEMORY (14) --HRESULT_FROM_WIN32--> 0x8007000E (= E_OUTOFMEMORY)
Rückwärts lesen: die unteren 16 Bit herausnehmen
Den ursprünglichen Win32-Fehler aus 0x8007xxxx lesen Sie in PowerShell, indem Sie die unteren 16 Bit herausnehmen.
0x80070005 -band 0xFFFF # 5 → ERROR_ACCESS_DENIED
0x80072EE7 -band 0xFFFF # 12007 → ERROR_INTERNET_NAME_NOT_RESOLVED (WinINet)
Wie das zweite Beispiel zeigt, sind auch WinINet- und WinHTTP-Fehler (12000er-Bereich) im Raum der Win32-Fehlercodes definiert,1 deshalb zerlegen Sie netzwerkbezogene 0x8007xxxx nach demselben Verfahren. „Bei 0x8007 die unteren vier Stellen ins Dezimal wandeln“ sich einzuprägen ist die wichtigste praktische Fertigkeit, die dieser Artikel mitgeben soll.
Bei 0x8004xxxx zur Unterlage der zurückgebenden Komponente gehen
Dieselbe Lesart dürfen Sie nicht unverändert auf 0x8004xxxx (FACILITY_ITF) anwenden. Hier unterscheidet sich, wer die Bedeutung definiert, je Schnittstelle, deshalb kann derselbe 32-Bit-Wert je nach Zurückgeber etwas anderes bedeuten.5
Ein ungewohntes 0x8004xxxx entscheiden Sie nicht allein mit einer allgemeinen Suche; schlagen Sie es in der Dokumentation der Komponente nach, die es zurückgegeben hat (Bibliothek, Treiber-SDK, Serverprodukt).
flowchart TB
accTitle: 0x8007 und 0x8004 ändern, wie Sie nachschlagen
accDescr: 0x8007xxxx von FACILITY_WIN32 liest sich durch mechanische Zerlegung der unteren 16 Bit; 0x8004xxxx von FACILITY_ITF hat je Schnittstelle einen anderen Definitionsgeber, deshalb schlagen Sie in der Unterlage der zurückgebenden Komponente nach
hr{"Welche Facility?"} -->|7, WIN32| w["Untere 16 Bit ins Dezimal"]
hr -->|4, ITF| i["Die Bedeutung unterscheidet sich je Zurückgeber"]
w --> ww["Als Win32-Fehler lesen"]
i --> ii["In der Unterlage des Zurückgebers nachschlagen"]
Abbildung 10: 0x8007xxxx lässt sich mechanisch zerlegen; 0x8004xxxx schlagen Sie in der Unterlage der zurückgebenden Komponente nach.
5. NTSTATUS — Codes der Kernelschicht und die Welt der Abstürze
5.1. Layout und Severity
NTSTATUS ist der 32-Bit-Code, den Kernel, Gerätetreiber und native APIs von ntdll verwenden; das Layout ähnelt HRESULT, ist aber nicht dasselbe.3
| Bitposition | Name | Bedeutung |
|---|---|---|
| 31–30 | Sev | Schweregrad. 00 = Erfolg, 01 = Information, 10 = Warnung, 11 = Fehler |
| 29 | C | Customer-Bit |
| 28 | N | Reserviert (0, damit die Abbildung auf HRESULT möglich bleibt) |
| 27–16 | Facility | Facility (12 Bit) |
| 15–0 | Code | Detailcode |
Der große Unterschied zu HRESULT ist, dass der Schweregrad 2 Bit hat und es vier Arten gibt: Erfolg, Information, Warnung, Fehler. An der ersten Hexadezimalziffer entspricht etwa 0xC… einem Fehler (11), 0x8… einer Warnung (10), 0x4… einer Information (01) und 0x0 bis 0x3… dem Erfolg.
Deshalb dürfen Sie allein am Aussehen „beginnt mit 0x8“ nicht auf einen HRESULT-Fehlschlag schließen. Das NTSTATUS 0x80000003 (STATUS_BREAKPOINT) ist eine Breakpoint-Ausnahme, und der Schweregrad ist „Warnung“, nicht „Fehler“.314
flowchart TB
accTitle: NTSTATUS lässt sich an der ersten Ziffer nach Art lesen
accDescr: Weil der Schweregrad 2 Bit hat, liest sich NTSTATUS an der ersten Hexadezimalziffer: 0xC Fehler, 0x8 Warnung, 0x4 Information, 0x0 bis 0x3 Erfolg
head{"Erste Hexadezimalziffer?"} -->|0xC| e["Fehler"]
head -->|0x8| w["Warnung"]
head -->|0x4| i["Information"]
head -->|0x0–0x3| s["Erfolg"]
w -.-> ex["Beispiel: 0x80000003 ist eine Warnung"]
Abbildung 11: NTSTATUS lässt sich an der ersten Hexadezimalziffer nach Art lesen. 0x80000003 ist „Warnung, nicht Fehler“.
5.2. Wo Sie ihm begegnen — Ausnahmecode, STOP-Code, Ereignisprotokoll
Die Orte, an denen Sie NTSTATUS begegnen, trennen wir in Ausnahmecode, STOP-Code und Process Monitor.
Der Ausnahmecode eines Anwendungsabsturzes
Der im Ereignisprotokoll unter „Application Error (Ereignis-ID 1000)“ aufgezeichnete „Exception code: 0xc0000005“ ist ein NTSTATUS. Repräsentative Werte, die Sie bei Absturz oder Startfehler sehen, sind die folgenden.14
| Wert | Symbol | Bedeutung |
|---|---|---|
| 0xC0000005 | STATUS_ACCESS_VIOLATION | Zugriffsverletzung (unzulässiger Speicherzugriff) |
| 0xC0000135 | STATUS_DLL_NOT_FOUND | Eine benötigte DLL fehlt, Start nicht möglich |
| 0xC00000FD | STATUS_STACK_OVERFLOW | Stacküberlauf |
| 0xC0000374 | STATUS_HEAP_CORRUPTION | Heap-Beschädigung |
Der STOP-Code eines Bluescreens ist ein anderes System
STOP-Codes (Bug-Check-Codes) sehen ähnlich aus, sind aber ein eigenes Nummernsystem, getrennt von NTSTATUS, etwa 0x0000009F (DRIVER_POWER_STATE_FAILURE). Verwenden Sie die eigene Referenz.15
Wichtig ist zu trennen: „0xC0000005 ist NTSTATUS, STOP 0x9F ist ein Bug-Check-Code“, und einen STOP-Code nicht in der NTSTATUS-Tabelle nachzuschlagen.
In Process Monitor erscheint er in der Spalte Result
NAME NOT FOUND und ACCESS DENIED in der Result-Spalte von Procmon sind Anzeigenamen des NTSTATUS, das der Kernel zurückgegeben hat (STATUS_OBJECT_NAME_NOT_FOUND bzw. STATUS_ACCESS_DENIED). Hier beobachten Sie den Fehlschlag der Datei-E/A im Wortschatz von NTSTATUS und können die Schichtenabbildung nachvollziehen, nach der er als Win32-Fehler bei der App ankommt.
flowchart TB
accTitle: Ausnahmecode und STOP-Code auseinanderlesen
accDescr: Den Ausnahmecode im Ereignisprotokoll als NTSTATUS lesen, den STOP-Code eines Bluescreens in der eigenen Referenz der Bug-Check-Codes nachschlagen
q{"Wo erschien der Code?"} -->|Ausnahmecode| nt["Als NTSTATUS lesen"]
q -->|STOP-Code| bc["In der Tabelle der Bug-Check-Codes nachschlagen"]
nt -.-> n1["Beispiel: 0xC0000005"]
bc -.-> b1["Beispiel: 0x0000009F"]
Abbildung 12: Der Ausnahmecode im Ereignisprotokoll ist NTSTATUS, der STOP-Code eines Bluescreens ein anderes System. Schlagen Sie nicht in der falschen Tabelle nach.
Die Untersuchung hinter dem Ausnahmecode, also Erfassung und Analyse eines Absturzabbilds, behandeln „Einführung in das Sammeln von Windows-Absturzabbildern“ und „Absturz-Dumps mit WinDbg + SOS lesen“.
5.3. Verhältnis zu HRESULT — N-Bit und RtlNtStatusToDosError
Es gibt zwei Wege, NTSTATUS an ein anderes System zu übergeben. Die Abbildung auf HRESULT und die Umwandlung in einen Win32-Fehler denken Sie getrennt.
| Weg | Was geschieht | Beispiel |
|---|---|---|
| Abbildung in den HRESULT-Raum | Mit HRESULT_FROM_NT das N-Bit (0x10000000) setzen | 0xC0000005 → 0xD0000005 |
| Umwandlung in einen Win32-Fehler | Mit RtlNtStatusToDosError in die zugehörige Nummer umwandeln | STATUS_ACCESS_VIOLATION → ERROR_NOACCESS (998) |
Bei der Abbildung auf HRESULT setzen Sie das N-Bit und bringen den NTSTATUS-Wert in den HRESULT-Raum. Deshalb ist das Verfahren: ein mit 0xD beginnendes HRESULT das N-Bit entfernen und als NTSTATUS lesen.2
Bei der Umwandlung in einen Win32-Fehler verwenden Sie RtlNtStatusToDosError in ntdll. Werte ohne Zuordnung werden ERROR_MR_MID_NOT_FOUND.11 0xC0000005 wird zu 998, STATUS_OBJECT_NAME_NOT_FOUND (0xC0000034) zu ERROR_FILE_NOT_FOUND (2). Der reiche Wortschatz der Kernelseite wird auf der Win32-Schicht manchmal auf grobe Klassen gerundet, deshalb lesen Sie vor und nach der Umwandlung getrennt.
flowchart TB
accTitle: Zwei Brücken von NTSTATUS zu anderen Schichten
accDescr: NTSTATUS gelangt auf zwei Wegen in andere Schichten: Abbildung in den HRESULT-Raum durch Setzen des N-Bits und Umwandlung in einen Win32-Fehlercode durch RtlNtStatusToDosError
nt["NTSTATUS (0xC0000005)"] -->|N-Bit setzen| hr["HRESULT (0xD0000005)"]
nt -->|RtlNtStatusToDosError| win["Win32-Fehler 998 (ERROR_NOACCESS)"]
win -.-> memo["Ohne Zuordnung: ERROR_MR_MID_NOT_FOUND"]
Abbildung 13: Die Brücke von NTSTATUS gibt es in zwei Arten. Bei Beginn mit 0xD das N-Bit entfernen und als NTSTATUS lesen.
6. COM und .NET — wie Fehlercodes auf Ausnahmen abgebildet werden
6.1. Die COM-Art — HRESULT + IErrorInfo
COM-Methoden geben grundsätzlich ein HRESULT zurück. Was sich in einem 32-Bit-Code mitteilen lässt, ist jedoch begrenzt.
Die Ergänzung ist IErrorInfo. Beschreibende Zeichenfolge und Ursprung des Fehlers lassen sich gesondert übermitteln, und in C++ fasst die Compilerunterstützung _com_error HRESULT und IErrorInfo zusammen. Apps, deren Dialog „Code + Beschreibung“ zeigt, transportieren den Beschreibungstext oft über diesen Mechanismus.
flowchart TB
accTitle: IErrorInfo ergänzt HRESULT
accDescr: Was in ein 32-Bit-HRESULT passt, ist begrenzt, deshalb transportiert IErrorInfo Beschreibungszeichenfolge und Ursprung gesondert, und in C++ fasst die Klasse _com_error beides zusammen
hr["HRESULT (nur 32 Bit)"] --> lim["Die packbare Information ist begrenzt"]
lim --> ei["IErrorInfo transportiert den Beschreibungstext"]
ei --> ce["_com_error fasst beides zusammen"]
ce -.-> dlg["Code + Beschreibung im Dialog"]
Abbildung 14: Eine Beschreibungszeichenfolge, die nicht ins 32-Bit-HRESULT passt, transportiert IErrorInfo gesondert.
6.2. Die .NET-Art — vom HRESULT zum Ausnahmetyp
Die .NET-Laufzeit wandelt einen HRESULT-Fehlschlag, den sie in der COM-Interop empfängt, in eine Ausnahme. Ein bekanntes HRESULT wird auf den zugehörigen Ausnahmetyp abgebildet, ein unbekanntes wird COMException.10
flowchart TB
accTitle: Abbildung von HRESULT auf .NET-Ausnahmen
accDescr: Ein fehlgeschlagenes HRESULT aus der COM-Interop wird bei bekannter Abbildung in den zugehörigen Ausnahmetyp, sonst in COMException gewandelt; in beiden Fällen bleibt der ursprüngliche Wert in Exception.HResult
hr["Fehlgeschlagenes HRESULT"] --> known{"Gibt es eine bekannte Abbildung?"}
known -->|ja| typed["In den zugehörigen Ausnahmetyp wandeln"]
known -->|nein| comex["In COMException wandeln"]
typed --> keep["Der ursprüngliche Wert bleibt in Exception.HResult"]
comex --> keep
Abbildung 15: .NET bildet HRESULT auf einen Ausnahmetyp ab, und in jeder Ausnahme bleibt der ursprüngliche Wert in Exception.HResult.
| HRESULT | .NET-Ausnahmetyp |
|---|---|
| E_ACCESSDENIED (0x80070005) | UnauthorizedAccessException |
| E_OUTOFMEMORY (0x8007000E) | OutOfMemoryException |
| E_INVALIDARG (0x80070057) | ArgumentException |
| E_NOTIMPL (0x80004001) | NotImplementedException |
| Wert ohne Abbildung | COMException (ursprünglicher Wert in der Eigenschaft ErrorCode) |
Die Ausnahmebehandlung am ursprünglichen HRESULT verzweigen
In jeder Ausnahme bleibt das ursprüngliche HRESULT in Exception.HResult. Wollen Sie bei Datei-E/A „nur bei Freigabeverletzung erneut versuchen“, können Sie diesen Wert als Bedingung nutzen. Das folgende Beispiel fängt nur 0x80070020, das eine Freigabeverletzung darstellt.
try
{
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException ex) when (ex.HResult == unchecked((int)0x80070020))
{
// 0x80070020 = HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION)
// Ein anderer Prozess hält die Datei — kurz warten und erneut versuchen, usw.
}
6.3. P/Invoke und GetLastError
Rufen Sie eine Win32-API direkt per P/Invoke, gehören Deklaration und Holen zusammen.
- In
DllImport(oderLibraryImport)SetLastError = trueangeben. - Unmittelbar nach festgestelltem Fehlschlag mit
Marshal.GetLastWin32Errorholen. Ab .NET 6 steht das gleichwertigeGetLastPInvokeErrorzur Verfügung.16
Vermeiden Sie, GetLastError selbst per P/Invoke zu deklarieren und aufzurufen. API-Aufrufe im Inneren der Laufzeit können den Wert überschreiben, sodass Sie den richtigen Fehlschlaggrund nicht erhalten.16
flowchart TB
accTitle: Letzten Fehler bei P/Invoke holen
accDescr: SetLastError auf true setzen und mit Marshal.GetLastWin32Error holen ist richtig; GetLastError direkt per P/Invoke zu rufen wird durch Überschreiben der Laufzeit ungenau
pi["Win32-API per P/Invoke rufen"] --> ok["SetLastError = true angeben"]
ok --> get["Mit GetLastWin32Error holen"]
pi --> ng["GetLastError direkt aufrufen"]
ng --> bad["Die Laufzeit überschreibt, ungenau"]
Abbildung 16: Bei P/Invoke gehören SetLastError = true und Marshal.GetLastWin32Error zusammen. Ein direkter Aufruf von GetLastError ist ungenau.
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern SafeFileHandle CreateFileW(string fileName, uint access, uint share,
IntPtr security, uint disposition, uint flags, IntPtr template);
// Den Rückgabewert als SafeFileHandle entgegennehmen, nicht als IntPtr, und mit using zuverlässig schließen
// (ein liegen gelassenes IntPtr lässt den Kernel-Handle lecken)
using var handle = CreateFileW(@"C:\ProgramData\MyApp\config.dat",
0x80000000 /*GENERIC_READ*/, 0, IntPtr.Zero, 3 /*OPEN_EXISTING*/, 0, IntPtr.Zero);
if (handle.IsInvalid)
{
int code = Marshal.GetLastWin32Error(); // Beispiel: 5
var message = new Win32Exception(code).Message; // Beispiel: Zugriff verweigert
logger.LogError("CreateFileW failed: {Code} (0x{Code:X8}) {Message}",
code, code, message);
}
Win32Exception holt die Meldungszeichenfolge des Betriebssystems zum Win32-Fehlercode, deshalb können Sie sie unverändert nutzen, um Code und Meldung ins Protokoll zu schreiben. Die Entwurfsfrage, auf welcher Schicht Sie Ausnahmen fangen und wie Sie sie protokollieren, behandelt „Wo sollten catch und Logging in der Ausnahmebehandlung stehen?“.
7. Praxis der Umwandlungs- und Untersuchungswerkzeuge — eine kopierbare Übersicht
Zuerst wählen Sie das Werkzeug nach Umgebung und Ziel. In den folgenden Abschnitten stehen Beispiele, die Sie so verwenden können.
| Lage | Werkzeug | Was sich nachschlagen lässt |
|---|---|---|
| Ohne Extra-Installation prüfen | certutil -error, net helpmsg | Name und Meldung zum Code (Abschnitt 7.2) |
| Definitionen mehrerer Systeme quer durchsuchen | err.exe | Definitionskandidaten in den Headern (Abschnitt 7.1) |
| Zahlen umwandeln und zerlegen | PowerShell | Dezimal/Hexadezimal, untere 16 Bit, Abbildung auf .NET-Ausnahmen (Abschnitt 7.3) |
| Während der Abbildanalyse die Bedeutung prüfen | WinDbg !error |
Deutung als Win32 oder NTSTATUS (Abschnitt 7.4) |
7.1. err.exe (Microsoft Error Lookup Tool)
Ein von Microsoft verteiltes eigenständiges Fehler-Nachschlagewerkzeug. Es durchsucht viele Headerdateien wie winerror.h und ntstatus.h quer und listet Definitionen und Meldungen, die zum angegebenen Code passen.7
err 0x80070005
err 5
err 0xC0000005
Beim Lesen der Ergebnisse achten Sie auf zwei Punkte.
- Aus mehreren Kandidaten den zum Kontext passenden wählen. „5“ trifft etwa auch andere Definitionen als Win32 ERROR_ACCESS_DENIED. Machen Sie den getroffenen Namen nicht unverändert zur Ursache.
- Den Stand der aufgenommenen Definitionen prüfen. Der Download-Dateiname trägt eine Version (zum Zeitpunkt des Schreibens Err_6.4.5.exe), und die Definitionen der Codes beruhen auf den Headern zum Zeitpunkt der Beigabe.7
flowchart TB
accTitle: Suchergebnisse von err.exe nach Kontext wählen
accDescr: err.exe durchsucht viele Headerdateien quer und listet passende Definitionen, deshalb wählen Sie bei mehreren Treffern zum selben Zahlenwert den angemessenen Kandidaten nach Kontext
in["err 5 eingeben"] --> scan["Viele Header quer durchsuchen"]
scan --> hits["Mehrere Definitionen treffen"]
hits --> pick["Den angemessenen Kandidaten nach Kontext wählen"]
Abbildung 17: err.exe durchsucht Header quer, deshalb können mehrere Kandidaten erscheinen; den angemessenen wählen Sie nach Kontext.
7.2. In Windows eingebaute Befehle
Ohne Extra-Installation nutzbar sind certutil und net helpmsg. Die Option -error von certutil zeigt den Meldungstext zum Fehlercode und nimmt ein hexadezimales HRESULT ebenso wie Dezimal entgegen.8
certutil -error 0x80070005
certutil -error 5
net helpmsg 5
net helpmsg ist nur für die Dezimalzahl eines Win32-Fehlercodes. In einer deutschen Umgebung kommt die Meldung auf Deutsch zurück, deshalb eignet sie sich auch zur Erklärung gegenüber Anwendern. Ein hexadezimales HRESULT schlagen Sie wie oben mit certutil -error nach.
flowchart TB
accTitle: Eingebaute Befehle unterscheiden
accDescr: Einen dezimalen Win32-Fehlercode schlagen Sie mit net helpmsg nach, einen Code einschließlich hexadezimalem HRESULT mit der Option -error von certutil
q{"Welchen Code haben Sie?"} -->|Dezimaler Win32| net["net helpmsg"]
q -->|Einschließlich Hexadezimal| cert["certutil -error"]
net -.-> jp["Die Meldung kommt in der Sprache des Betriebssystems"]
cert -.-> any["Nimmt Hexadezimal und Dezimal entgegen"]
Abbildung 18: Eingebaute Befehle unterscheiden. Dezimaler Win32-Fehler mit net helpmsg, einschließlich Hexadezimal mit certutil -error.
7.3. PowerShell-Einzeiler
Eine Übersicht zum Umwandeln der Schreibweise, Holen der Win32-Meldung, Zerlegen eines HRESULT und Abbilden auf .NET-Ausnahmen. Nach der Bedeutung des Codes bleibt die Untersuchung des fehlgeschlagenen Vorgangs und Ziels gesondert nötig.
# Win32-Fehlercode → Meldungszeichenfolge des Betriebssystems
[System.ComponentModel.Win32Exception]::new(5).Message
# → Zugriff verweigert
# Negative Dezimalzahl → Hexadezimalschreibweise (HRESULT erkennen)
'0x{0:X8}' -f -2147467259 # 0x80004005
# 0x8007xxxx → Win32-Fehlercode der unteren 16 Bit
0x80070005 -band 0xFFFF # 5
# HRESULT → von .NET abgebildete Ausnahme prüfen
[System.Runtime.InteropServices.Marshal]::GetExceptionForHR(-2147024891)
# → UnauthorizedAccessException (0x80070005)
# Win32-Fehlercode → HRESULT (Umpacken nachbilden)
'0x{0:X8}' -f (0x80070000 -bor 32) # 0x80070020
7.4. WinDbg !error
Während der Abbildanalyse schlagen Sie einen Code schnell mit der WinDbg-Erweiterung !error nach. Standardmäßig als Win32-Fehlercode, mit 1 als zweitem Argument als NTSTATUS.9
0:000> !error 5
Error code: (Win32) 0x5 (5) - Zugriff verweigert.
0:000> !error 0xc0000005 1
Error code: (NTSTATUS) 0xc0000005 - <Zugriffsverletzung>
In einem Absturzabbild zeigt !analyze -v den Ausnahmecode (NTSTATUS) automatisch, und von dort prüfen Sie die Bedeutung mit !error <code> 1.
flowchart TB
accTitle: Ablauf der Prüfung eines Ausnahmecodes in WinDbg
accDescr: In einem Absturzabbild zeigt der analyze-Befehl den Ausnahmecode automatisch an, und Sie übergeben diesen Code an die error-Erweiterung mit zweitem Argument 1, um ihn als NTSTATUS zu deuten
dump["Absturzabbild öffnen"] --> an["!analyze -v ausführen"]
an --> exc["Der Ausnahmecode wird angezeigt"]
exc --> chk["Bedeutung mit !error Code 1 prüfen"]
Abbildung 19: In der Abbildanalyse untersuchen Sie den von !analyze -v angezeigten Ausnahmecode mit !error und Flag 1.
8. Untersuchungsablauf — von der Schichtbestimmung zum Abgleich mit dem Kontext
In der tatsächlichen Untersuchung gehen Sie die folgenden fünf Stufen der Reihe nach. Nach dem Nachschlagen des Namens nicht aufhören, sondern am Ende fehlgeschlagenen Vorgang und Ziel prüfen ist der Punkt.
- Die Schreibweise angleichen. Eine negative Dezimalzahl wandeln Sie in acht Hexadezimalstellen. Hexadezimal unter acht Stellen lesen Sie mit führenden Nullen.
- Bestimmen, welcher Schicht der Code angehört. In der folgenden Tabelle grenzen Sie am Anfang der Ziffern den ersten Kandidaten ein und gleichen mit der zurückgebenden API und dem Anzeigeort ab.
- Zerlegen und den wesentlichen Code herausnehmen. Ein HRESULT 0x8007xxxx an den unteren 16 Bit, ein HRESULT 0xDxxxxxxx nach Entfernen des N-Bits.
- Name und Definition mit einem Werkzeug nachschlagen. Symbolname und Meldung mit err.exe, certutil,
!errorund Ähnlichem prüfen. - Mit dem Kontext abgleichen. Welche App, welcher Vorgang, welche API woran gescheitert ist, bestimmen Sie mit App-Protokoll, Ereignisprotokoll und Procmon. Der Code ist die „Art des Fehlschlags“, der Kontext der „Ort der Ursache“.
flowchart TB
accTitle: Ablauf der Fehlercode-Untersuchung
accDescr: Die Schreibweise auf Hex angleichen, an den ersten Ziffern die Schicht bestimmen, zerlegen und den wesentlichen Code herausnehmen, Name und Definition mit einem Werkzeug nachschlagen und dann mit dem Kontext abgleichen
fix["Schreibweise angleichen (Negativzahl in acht Hex-Stellen)"] --> judge{"Erste Ziffern?"}
judge -->|Dezimalschreibweise| d1["Als Win32-Fehler lesen"]
judge -->|0x8007| d2["Untere 16 Bit ins Dezimal"]
judge -->|0xC| d3["Als NTSTATUS lesen"]
judge -->|0xD| d4["N-Bit entfernen und lesen"]
d1 --> tool["Name und Definition mit einem Werkzeug nachschlagen"]
d2 --> tool
d3 --> tool
d4 --> tool
tool --> ctx["Mit dem Kontext abgleichen (Procmon u. a.)"]
Abbildung 20: Das Muster der Untersuchung. Schreibweise angleichen, Schicht bestimmen, zerlegen, den Namen nachschlagen und dann mit dem Kontext abgleichen.
| Aussehen | Erster Kandidat | Verfahren der Zerlegung und Umwandlung |
|---|---|---|
| 1- bis 5-stellige Dezimalzahl (5, 1223 und Ähnliches) | Win32-Fehlercode | Unverändert an net helpmsg oder err.exe |
| Negative Dezimalzahl (-2147024891 und Ähnliches) | HRESULT | In acht Hexadezimalstellen wandeln, dann die Zeile darunter |
| 0x8007xxxx | HRESULT (FACILITY_WIN32) | Untere 16 Bit ins Dezimal und als Win32 lesen |
| 0x8004xxxx | HRESULT (FACILITY_ITF) | In der Dokumentation der zurückgebenden Komponente nachschlagen |
| 0x8000xxxx | HRESULT (FACILITY_NULL) | Generische Codes wie E_FAIL. Schwerpunkt auf die Kontextuntersuchung verlagern |
| 0xCxxxxxxx | NTSTATUS (Fehler) | !error <code> 1, bei Bedarf nach Umwandlung in Win32 lesen |
| 0xDxxxxxxx | HRESULT-Abbildung eines NTSTATUS | N-Bit (0x10000000) entfernen und als NTSTATUS lesen |
| Eigene Facility wie 0x8024xxxx | HRESULT eines Funktionsbereichs | Am Facility-Wert den Bereich bestimmen und zur eigenen Unterlage (0x8024… ist Windows Update)2 |
Konkretes Beispiel zu Schritt 5: von 0x80070002 zum nicht gefundenen Pfad
Auch wenn die App nur „0x80070002“ zeigt, sehen Sie in der Result-Spalte von Procmon, „welcher Prozess gegen welchen Pfad NAME NOT FOUND erhalten hat“. Das ist die Beobachtung, die von der Zerlegung des Codes zur Bestimmung des tatsächlich fehlgeschlagenen Ziels führt.
Die Untersuchung auf der Seite des Ereignisprotokolls behandelt auch „Einführung in Windows-Ereignisprotokoll und ETW“.
9. Häufige Fehldeutungen — Muster, die die Untersuchung umwege machen
Zum Schluss Muster von Fehldeutungen, die in tatsächlichen Beratungen vorkommen.
Fehldeutung 1: 0x80004005 für „einen Code, der eine bestimmte Ursache zeigt“ halten
E_FAIL ist „nicht näher bezeichnetes Fehlschlagen“, und derselbe Wert erscheint bei Windows Update, im Netzwerk und in der Datenbank. Die bei einer Suche nach diesem Code gefundenen Maßnahmen der Reihe nach zu versuchen, ist fast sicher ein Umweg. Grenzen Sie nicht am Code, sondern an „welche App, welcher Vorgang, andere Protokolle zur selben Zeit“ ein.6
Fehldeutung 2: Nicht merken, dass eine negative Dezimalzahl ein HRESULT ist
Ein Protokoll „Fehler -2147467259 ist aufgetreten“ so zu suchen oder sich über „einen negativen Fehler?“ zu wundern. Sehen Sie eine negative Zahl, wandeln Sie sie ins Hexadezimal. Allein das zeigt 0x80004005 (E_FAIL) und schließt an das Wissen von Fehldeutung 1 an.
Fehldeutung 3: 0x8007xxxx als ganze acht Stellen nachschlagen und den unteren Win32-Fehler nicht sehen
Die Substanz von 0x80070005 ist „5 = Zugriff verweigert“. Schneller zum Kern kommen Sie, wenn Sie nicht die ganzen acht Stellen suchen, sondern die unteren 16 Bit herausnehmen und überlegen, „was Win32-Fehler 5 im Kontext dieses Vorgangs bedeutet“.
Fehldeutung 4: „Derselbe Code = dieselbe Ursache“ annehmen
Wer einmal erlebt hat, „Fehler 5 kam von der Antivirensoftware“, springt beim nächsten Fehler 5 oft zur selben Maßnahme. Auch bei gleichem Code ist die Ursache eine andere, wenn fehlgeschlagene API und Zielressource anders sind. Prüfung der Codebedeutung und Bestimmung des Ziels mit Procmon oder ähnlichem gehören jedes Mal zusammen.
Fehldeutung 5: Win32-Fehler 5 und 0xC0000005, STOP-Code und NTSTATUS verwechseln
Wenn Sie ERROR_ACCESS_DENIED und STATUS_ACCESS_VIOLATION wegen der „5“ gleichsetzen, driftet die Untersuchung in völlig verschiedene Richtungen: Rechteproblem und Programmfehler. Außerdem ist der STOP-Code eines Bluescreens ein anderes System als NTSTATUS, deshalb ergibt 0x9F in der NTSTATUS-Tabelle keine sinnvolle Antwort.15
flowchart TB
accTitle: Fehler 5 und 0xC0000005 haben verschiedene Untersuchungsrichtungen
accDescr: Win32-Fehler 5 untersuchen Sie als Rechteproblem, NTSTATUS 0xC0000005 als Programmfehler; sie gleichzusetzen lässt die Untersuchung in die falsche Richtung driften
a["Win32-Fehler 5"] --> ad["Als Rechteproblem untersuchen"]
b["NTSTATUS 0xC0000005"] --> bd["Als Programmfehler untersuchen"]
a -.-> memo["Unzusammenhängende Codes verschiedener Systeme"]
b -.-> memo
Abbildung 21: Wegen der „5“ nicht gleichsetzen. Fehler 5 geht zum Rechteproblem, 0xC0000005 zum Programmfehler.
10. Zusammenfassung
Zuerst das System erkennen. Die wichtigsten Windows-Fehlercodes sind die drei Systeme Win32-Fehlercode, HRESULT und NTSTATUS. Schwankungen der Schreibweise Dezimal, Hexadezimal und negativ gleichen Sie an und prüfen, welche Schicht wen zurückgegeben hat. NTSTATUS begegnet Ihnen als Ausnahmecode eines Absturzes und in der Result-Spalte von Procmon, aber Win32-Fehler 5 und 0xC0000005 sind verschieden, und STOP-Codes sind noch ein weiteres System.
Dann die Struktur lesen und die nötige Information herausnehmen. HRESULT besteht aus S/R/C/N/X-Bits, 11 Bit Facility und 16 Bit Code. Das wichtigste Muster ist 0x8007xxxx; aus den unteren 16 Bit lesen Sie den Win32-Fehler. In der COM-Interop wird HRESULT auf einen .NET-Ausnahmetyp abgebildet, und der ursprüngliche Wert bleibt in Exception.HResult. Bei P/Invoke gehören SetLastError = true und Marshal.GetLastWin32Error zusammen.
Zuletzt mit dem Kontext abgleichen. E_FAIL (0x80004005) ist kein Code, der die Ursache zeigt. Haben Sie erkannt, dass die Zerlegung keine Information hinzufügt, hören Sie auf, in den Code zu graben, und gehen Sie zu Vorgang, Ziel und Protokollen zur selben Zeit. Die Werkzeuge unterscheiden Sie: certutil und net helpmsg, err.exe, PowerShell, WinDbg !error.
Das Muster der Untersuchung ist „Schreibweise angleichen → Schicht bestimmen → zerlegen → Namen nachschlagen → mit dem Kontext abgleichen“. Der Code lehrt nur die Art des Fehlschlags. Beim nächsten ungewohnten Zahlenwert prüfen Sie vor dem Einfügen in das Suchfeld die ersten Ziffern und die Herkunft. Diese erste Zerlegung entscheidet, wo Sie danach suchen.
Verwandte Artikel
- Absturz-Dumps mit WinDbg + SOS lesen — Ein praxistauglicher Leitfaden zur Analyse nach der Sammlung
- Einführung in das Sammeln von Windows-Absturzabbildern - WER/ProcDump/WinDbg
- Wo sollten catch und Logging in der Ausnahmebehandlung stehen?
- Process Monitor (ProcMon) Praxisleitfaden — „Konfiguration wird nicht gelesen“ und ACCESS DENIED in 10 Minuten identifizieren
- Einführung in Windows-Ereignisprotokoll und ETW ── Protokolle von Geschäftsanwendungen in die Standardmechanismen des Betriebssystems einordnen
Verwandte Beratungsfelder
Die KomuraSoft LLC übernimmt Störungsuntersuchungen ausgehend von Fehlercodes wie „die Bedeutung dieses Fehlercodes ist unklar“ oder „0x80070005 erscheint nur in einer bestimmten Umgebung“, den Entwurf der Fehlerbehandlung in Apps, in denen Win32-API, COM und .NET gemischt sind, und die Ursachenbestimmung mit Absturzabbild und Process Monitor. Eine Beratung ausgehend von einem einzigen Screenshot des Fehlerdialogs ist in Ordnung.
- Windows-App-Entwicklung
- Fehleruntersuchung und Ursachenanalyse
- Technische Beratung und Design-Review
- Kontakt
Quellen
-
Microsoft Learn, Debug system error codes. Zum Index der Liste der Win32-Systemfehlercodes (0–15999), dazu, die Meldung zu einem von GetLastError zurückgegebenen Code mit FormatMessage und dem Flag FORMAT_MESSAGE_FROM_SYSTEM zu holen, dazu, dass WinINet-/WinHTTP-Fehler (12000er-Bereich) in diesem Raum definiert sind, und zur Untersuchung mit Microsoft Error Lookup Tool und dem Befehl !err. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Open Specifications, [MS-ERREF]: HRESULT. Zum Bit-Layout von HRESULT (S-, R-, C-, N-, X-Bit, 11 Bit Facility, 16 Bit Code), dazu, dass das N-Bit anzeigt, dass ein NTSTATUS-Wert in den HRESULT-Raum abgebildet wurde, und zur Liste der Facility-Codes einschließlich FACILITY_WINDOWS_UPDATE (36). ↩ ↩2 ↩3 ↩4
-
Microsoft Open Specifications, [MS-ERREF]: NTSTATUS. Zum Bit-Layout von NTSTATUS (2 Bit Sev, C-Bit, N-Bit, 12 Bit Facility, 16 Bit Code) und dazu, dass der Schweregrad in vier Arten Erfolg (00), Information (01), Warnung (10) und Fehler (11) fällt. ↩ ↩2 ↩3
-
Microsoft Learn, HRESULT_FROM_WIN32 macro. Zur Definition des Makros in winerror.h, das einen Win32-Systemfehlercode auf einen HRESULT-Wert abbildet. ↩ ↩2 ↩3
-
Microsoft Learn, Structure of COM Error Codes. Zur Rolle von Schweregradbit und Facility-Feld eines HRESULT, zu den Werten FACILITY_NULL, FACILITY_RPC, FACILITY_ITF, FACILITY_WIN32 und FACILITY_WINDOWS und dazu, dass Codes von FACILITY_ITF je Schnittstelle definiert sind und derselbe Wert unterschiedliche Bedeutung haben kann. ↩ ↩2 ↩3
-
Microsoft Learn, Common HRESULT values. Dazu, dass E_FAIL (0x80004005) „Unspecified failure“ (nicht näher bezeichnetes Fehlschlagen) ist, und zu den Definitionen häufiger HRESULT-Werte wie E_ACCESSDENIED (0x80070005), E_INVALIDARG (0x80070057) und E_OUTOFMEMORY (0x8007000E). ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, The Microsoft Error Lookup Tool. Dazu, dass das eigenständige Werkzeug den einem hexadezimalen Statuscode zugeordneten Meldungstext quer durch Headerdateien wie Winerror.h anzeigt, der Download-Dateiname Err_6.4.5.exe ist und die aufgenommenen Definitionen vom Stand der Kompilierung stammen. ↩ ↩2 ↩3
-
Microsoft Learn, certutil. Dazu, dass die Option -error von certutil den einem Fehlercode zugeordneten Meldungstext anzeigt und eine Schreibweise mit Symbolnamen wie 0x80070002 (WIN32: 2 ERROR_FILE_NOT_FOUND) verwendet wird. ↩ ↩2
-
Microsoft Learn, !error. Dazu, dass die WinDbg-Erweiterung !error Fehlerwerte von Win32, Winsock, NTSTATUS und NetAPI dekodiert und anzeigt und bei Flag 1 als NTSTATUS deutet. ↩ ↩2
-
Microsoft Learn, How to: Map HRESULTs and exceptions. Zum gegenseitigen Abbilden von COM-HRESULT und .NET-Ausnahmen, zur Zuordnungstabelle wie E_NOTIMPL → NotImplementedException, dazu, dass ein HRESULT ohne ausdrückliche Abbildung zu COMException wird, und dazu, dass Message, Source und Ähnliches der Ausnahme aus IErrorInfo initialisiert werden. ↩ ↩2
-
Microsoft Learn, RtlNtStatusToDosError function (winternl.h). Dazu, dass die Funktion einen NTSTATUS-Code in den zugehörigen Win32-Systemfehlercode umwandelt, bei fehlender Zuordnung ERROR_MR_MID_NOT_FOUND zurückgibt und es keine Umkehrfunktion gibt. ↩ ↩2
-
Microsoft Learn, Last-Error Code. Dazu, dass der letzte Fehlercode je Thread gehalten wird, dass er unmittelbar nach dem Fehlschlag mit GetLastError geholt werden soll, dass APIs, die den Code bei Erfolg mit 0 überschreiben, und solche, die das nicht tun, gemischt vorkommen, und dazu, dass Bit 29 für anwendungsdefinierte Codes reserviert ist. ↩ ↩2
-
Microsoft Learn, RegOpenKeyExW function. Dazu, dass bei Erfolg ERROR_SUCCESS und bei Fehlschlag ein in Winerror.h definierter von null verschiedener Fehlercode als Rückgabewert zurückgegeben wird. ↩
-
Microsoft Open Specifications, [MS-ERREF]: NTSTATUS values. Zur Liste der NTSTATUS-Werte einschließlich STATUS_ACCESS_VIOLATION (0xC0000005), STATUS_DLL_NOT_FOUND (0xC0000135), STATUS_STACK_OVERFLOW (0xC00000FD), STATUS_HEAP_CORRUPTION (0xC0000374) und STATUS_BREAKPOINT (0x80000003). ↩ ↩2
-
Microsoft Learn, Bug check code reference. Zur Liste der auf einem Bluescreen angezeigten Bug-Check-Codes (STOP-Codes) und dazu, Informationen zum Code mit der WinDbg-Erweiterung !analyze anzuzeigen. An der Liste ist erkennbar, dass es ein von NTSTATUS getrenntes eigenes Nummernsystem ist. ↩ ↩2
-
Microsoft Learn, Marshal.GetLastWin32Error Method. Dazu, den letzten Fehlercode eines P/Invoke-Aufrufs mit gesetztem SetLastError-Flag zu holen, dass GetLastError direkt per P/Invoke wegen Überschreibens durch API-Aufrufe im Inneren der Laufzeit unzuverlässig ist und ab .NET 6 GetLastPInvokeError empfohlen wird. ↩ ↩2
Verwandte Artikel
Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.
Time Travel Debugging — Langlaufende Fehler, die sich nicht reproduzieren, aufzeichnen und zurückspulen
Ein Fehler, der nur einmal im Monat auftritt, hinterlässt im Absturz-Dump nur das Ergebnis. Mit Time Travel Debugging (TTD) in WinDbg zei...
Warum Argumente zerbrechen — Die Regeln der Windows-Kommandozeilenargumente
Windows übergibt CreateProcess eine einzige Zeichenfolge, die der Empfänger zerlegt. Behandelt die Regeln von CommandLineToArgvW, CRT und...
Apps, die nach dem Fortsetzen aus dem Schlaf kaputtgehen — Energieereignisse und Geschäftsanwendungen, die das Fortsetzen überstehen
Sie klappen den Laptop auf, und die Verbindungen der Geschäftsanwendung sind tot — die Ursache ist ein Entwurf, der Schlaf nicht vorsieht...
DllMain und die Ladersperre — Der wahre Grund, warum man sagt, in der DLL-Initialisierung nichts zu tun
Warum Sie aus DllMain weder LoadLibrary aufrufen noch mit Threads synchronisieren dürfen. Anhand von Primärquellen erklärt dieser Artikel...
Was „Keine Rückmeldung“ wirklich ist — Wie Windows entscheidet, dass eine App hängt, und Entwürfe, die nicht hängen
„Keine Rückmeldung“ unter Windows ist ein Mechanismus, bei dem das Betriebssystem urteilt, dass ein Fenster 5 Sekunden lang keine Nachric...
Verwandte Themen
Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.
Technische Windows-Themen
Portal zu Windows-Entwicklung, Fehleranalyse und der Nutzung bestehender Assets.
Fehleranalyse und Langzeitprobleme
Sporadische Fehler, Kommunikationsdiagnose, Langzeitabstürze und Tests von Fehlerpfaden.
Leistungen zu diesem Thema
Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.
Windows-App-Entwicklung
Geschäftsanwendungen, Geräteintegration und Kommunikationstools von den Anforderungen bis zur Umsetzung.
Fehleruntersuchung und Ursachenanalyse
Wir untersuchen schwer reproduzierbare Fehler, Langzeitprobleme, Lecks und Kommunikationsabbrüche.
Häufige Fragen
Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.
- Was bedeutet der Fehler 0x80004005?
- 0x80004005 ist der HRESULT E_FAIL und bedeutet "Unspecified failure" (nicht näher bezeichnetes Fehlschlagen). Er zeigt nur, dass ein Fehlschlag aufgetreten ist, dessen genauer Grund nicht berichtet werden kann; er ist kein Code, der die Ursache selbst darstellt. Derselbe 0x80004005 erscheint deshalb an unzusammenhängenden Stellen — Netzwerk, Windows Update, VBA, ein Datenbanktreiber. Wenn Sie diesen Code sehen, graben Sie nicht in der Bedeutung des Codes; engen Sie die Ursache anhand des Kontexts ein, welche App und welcher Vorgang ihn erzeugt hat, und anhand anderer Fehlerinformationen im Ereignisprotokoll oder in einem detaillierten Protokoll.
- Was ist ein negativer Fehlercode wie -2147467259?
- Es ist ein 32-Bit-HRESULT, angezeigt als vorzeichenbehaftete Dezimalzahl. Ein HRESULT setzt bei Fehlschlag das höchstwertige Bit, daher ist er als vorzeichenbehaftete Ganzzahl immer negativ. In PowerShell wandelt '0x{0:X8}' -f -2147467259 ihn zurück ins Hexadezimal (in diesem Beispiel 0x80004005 = E_FAIL). Wenn Sie in einem Protokoll oder einer Skriptfehlermeldung eine negative Zahl sehen, die mit -214… beginnt, ist der Standardschritt, sie zuerst ins Hexadezimal umzuwandeln und dann nachzuschlagen.
- Was ist der einfachste Weg, die Bedeutung eines Fehlercodes nachzuschlagen?
- Ohne Extra-Installation können Sie an der Eingabeaufforderung net helpmsg 5 (für einen Win32-Fehler in Dezimal) und certutil -error 0x80070005 verwenden. certutil akzeptiert auch ein hexadezimales HRESULT und zeigt den Symbolnamen und den Nachrichtentext. In PowerShell holt [System.ComponentModel.Win32Exception]::new(5).Message die Meldung in der Sprache des Betriebssystems. Auf einer Entwicklungsmaschine behalten Sie Microsofts offizielles Nachschlagewerkzeug err.exe (Microsoft Error Lookup Tool); es durchsucht Win32, HRESULT und NTSTATUS und listet passende Definitionen auf einmal.
- Was für ein Fehler ist 0xC0000005?
- Es ist der NTSTATUS STATUS_ACCESS_VIOLATION, also eine Zugriffsverletzung (ein unzulässiger Speicherzugriff). Es ist der Code, den Sie beim Absturz einer Anwendung am häufigsten als "Exception code" im Ereignisprotokoll oder in einem Absturzabbild sehen, und er zeigt einen Programmfehler an, etwa die Dereferenzierung eines ungültigen Zeigers oder den Zugriff auf bereits freigegebenen Speicher. Er ähnelt namentlich dem Win32-Fehler 5 (ERROR_ACCESS_DENIED = Zugriff verweigert), ist aber ein unzusammenhängender Code eines anderen Systems; verwechseln Sie sie nicht. Der zuverlässige Weg, die Ursache zu identifizieren, ist, ein Absturzabbild zu erfassen und es in WinDbg zu analysieren.
- Warum ist die Ursache jedes Mal anders, selbst beim gleichen Fehlercode?
- Weil ein Fehlercode nur angibt, welche Art von Fehlschlag vorliegt, und was fehlgeschlagen ist und warum vom Aufrufkontext entschieden wird. Fehler 5 (Zugriff verweigert) ist zum Beispiel derselbe Code für völlig verschiedene Ursachen — unzureichende NTFS-Berechtigungen, fehlende Administratorrechte, eine Antivirus-Sperre und so weiter. In einer ähnlichen Lage, wenn ein anderer Prozess die Datei noch offen hat, erhalten Sie einen anderen Code (Fehler 32 = Freigabeverletzung), und den Code richtig zu lesen ändert, wo Sie suchen. Fehler 2 (Datei nicht gefunden) betrifft oft nicht die Hauptdatei, sondern eine abhängige DLL oder eine Einstellungsdatei. Sobald Sie die Bedeutung des Codes nachgeschlagen haben, mit Process Monitor oder ähnlichem zu bestätigen, welche API gegen welche Ressource fehlgeschlagen ist, ist der kurze Weg zur Ursache.
Autorenprofil
Profilseite des Artikelautors.
Go Komura
Geschäftsführer von KomuraSoft LLC
Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.