2009-10-30 13 views
25

Sto scherzando con alcune funzioni di Windows usando p/invoke. Occasionalmente, ricevo un codice di errore che non è ERROR_SUCCESS (un nome strano).Ottenere il codice di errore del sistema Windows titolo/descrizione dal suo numero esadecimale

C'è un modo per cercare questi all'interno del programma? Peresempio, se ottengo l'errore 1017. Posso dire all'utente

Il sistema ha tentato di caricare o ripristinare un file nel Registro di sistema, ma il file specificato non è in un formato di file Registro di sistema. (ERROR_NOT_REGISTRY_FILE: 0x3F9)

Invece di

Codice errore: 1017

risposta

76

non sono sicuro se c'è un wrapper niifty .NET, ma si può chiamare l'API FormatMessage usando P/Invoke.

Vedere this answer per come verrebbe normalmente chiamato dal codice nativo. Anche se la domanda si riferisce ai codici di errore di acquisizione da HRESULT, la risposta vale anche per i codici di reinvio dei normali codici di errore del sistema operativo provenienti da GetLastError/GetLastWin32Error).

EDIT: Grazie per la segnalazione Malfist me PInvoke.net, che include alternativa, gestito API:

using System.ComponentModel; 

string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message; 
Console.WriteLine(errorMessage); 
+2

http: //www.pinvoke. net/default.aspx/kernel32/FormatMessage.html dice di non usare mai FormatMessage – Malfist

+0

@Malfist, grazie per averlo indicato. C'è una risposta che dice che va bene finché usi Marshal.GetLastWin32Error per recuperare il codice di errore. Nondimeno, sembra che Win32Exception sia una soluzione migliore. –

+2

Si noti, tuttavia, che entrambe queste soluzioni ricevono solo il messaggio di errore descrittivo; nessuno di questi ti porterà il nome dell'errore in maiuscolo con caratteri di sottolineatura che vedi nella documentazione (come ** ERROR_NOT_REGISTRY_FILE **). Per chiunque approdi qui e se ne stia chiedendo, di recente ho chiesto [una domanda specifica su come determinare a livello di programmazione quei nomi di errore] (http://stackoverflow.com/q/30203717/1248365), e la risposta è risultata essere che non puoi Si riferiscono ai nomi costanti di winerror.h, un file di inclusione del C++ fornito in Windows SDK. –

-2

Sì c'è una funzione che fa questo, ma non mi ricordo di cosa si tratta. Nel frattempo, è possibile utilizzare lo strumento di ricerca degli errori (Strumenti-> Ricerca errori) per vedere cosa significa un determinato codice all'interno di Visual Studio.

+2

O semplicemente fai quello che Nick ha detto :-) –

+1

Non vedo questo. E questo non mi aiuta a mostrare nulla all'utente. – Malfist

+1

Come risponde la domanda dell'OP? – SepehrM

0

Sono atterrato su questa pagina mentre cercavo un'alternativa gestita alla chiamata di FormatMessage tramite P/Invoke.

Come altri hanno già detto, non c'è modo di ottenere quei nomi maiuscoli, sottolineati, a meno di cercarli in winerror.h, che ho visto riprodotti online in vari luoghi dove sono atterrato nel corso della ricerca di informazioni sulla risoluzione di codici di stato specifici. Una rapida ricerca su Google, per winerror.h, a sua volta, scoperta di una pagina, a Rensselaer Polytechnic Instutute, in cui qualcuno ha tratto utilmente le dichiarazioni #define da esso.

Guardarlo mi ha dato un'idea; Penso che ci possa essere un modo per arrivarci, lavorando dal codice sorgente di winerror.h, che ho, come parte di Windows Platform SDK fornito con ogni versione recente di Microsoft Visual Studio.

In questo momento, sono nel bel mezzo di risolvere un problema urgente nell'assembly .NET che mi ha portato a questa pagina. Poi, vedrò cosa posso accartocciare insieme; questo tipo di sfida è proprio il mio vicolo, e qualcuno ha lanciato un guanto di sfida.

1

Si potrebbe prendere il definisce da winerror.h a Rensselaer Polytechnic Institute, e metterli in un Enum:

public enum Win32ErrorCode : long 
{ 
    ERROR_SUCCESS = 0L, 
    NO_ERROR = 0L, 
    ERROR_INVALID_FUNCTION = 1L, 
    ERROR_FILE_NOT_FOUND = 2L, 
    ERROR_PATH_NOT_FOUND = 3L, 
    ERROR_TOO_MANY_OPEN_FILES = 4L, 
    ERROR_ACCESS_DENIED = 5L, 
    etc. 
} 

Quindi se il vostro codice di errore è in una variabile error_code si usa:

Enum.GetName(typeof(Win32ErrorCode), error_code); 
+2

Esiste una classe copy-paste che li tiene su http://www.pinvoke.net/default.aspx/Constants/WINERROR.html –

Problemi correlati