2009-10-30 20 views
25

Estoy jugando con algunas funciones de Windows usando p/invoke. Ocasionalmente, obtengo un código de error que no es ERROR_SUCCESS (un nombre tan extraño).Obteniendo el título/descripción del código de error del sistema de Windows desde su número hexadecimal

¿Hay alguna manera de buscar esto dentro del programa? Porejemplo, si me da error 1017. ¿Puedo decirle al usuario

El sistema ha intentado cargar o restaurar un archivo en el registro, pero el archivo especificado no está en un formato de archivo registro. (ERROR_NOT_REGISTRY_FILE: 0x3F9)

En lugar de

Código de error: 1017

Respuesta

76

No estoy seguro de si hay un envoltorio niifty .NET, pero se puede llamar a la API FormatMessage usando P/Invoke.

Consulte this answer para saber cómo se llamaría normalmente desde el código nativo. Aunque la pregunta se refiere a los códigos de error de agarre de HRESULT, la respuesta también se aplica a los códigos de recuperación de los códigos de error de sistema operativo estándar que provienen de GetLastError/GetLastWin32Error).

EDIT: Gracias por señalar Malfist me pinvoke.net, que incluye alternativa, logró 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 que nunca debe usar FormatMessage – Malfist

+0

@Malfist, gracias por señalarlo. Hay una respuesta que dice que está bien, siempre y cuando esté usando Marshal.GetLastWin32Error para recuperar el código de error. No obstante, parece que Win32Exception es una mejor solución. –

+2

Sin embargo, tenga en cuenta que estas dos soluciones solo reciben el mensaje de error descriptivo; ninguno de estos le dará el nombre del error en mayúscula con subrayado que se ve en la documentación (como ** ERROR_NOT_REGISTRY_FILE **). Para cualquiera que aterrice aquí y se pregunte sobre eso, recientemente le pregunté [una pregunta específica sobre cómo determinar por programación esos nombres de error] (http://stackoverflow.com/q/30203717/1248365), y la respuesta resultó ser que no puedes Se refieren a nombres constantes de winerror.h, un archivo incluido C++ proporcionado en el SDK de Windows. –

-2

Sí hay una función que hace eso, pero no me acuerdo de qué se trata. Mientras tanto, puede usar la herramienta de búsqueda de errores (Herramientas-> Búsqueda de errores) para ver qué significa un código particular dentro de Visual Studio.

+2

O simplemente haz lo que Nick dijo :-) –

+1

No veo esto. Y esto no me ayuda a mostrar nada al usuario. – Malfist

+1

¿Cómo responde esto la pregunta del OP? – SepehrM

0

Aterricé en esta página mientras buscaba una alternativa administrada para llamar a FormatMessage a través de P/Invoke.

Como han dicho otros, no hay forma de obtener esos nombres en mayúsculas y minúsculas, sin buscarlos en winerror.h, que he visto reproducido en línea en varios lugares donde llegué en el curso de la búsqueda de información sobre la resolución de códigos de estado específicos. Una búsqueda rápida en Google, para winerror.h, en sí mismo, descubrió una página, en Rensselaer Polytechnic Instutute, donde alguien ha extraído provechosamente las declaraciones #define de ella.

Al verlo me dio una idea; Creo que puede haber una forma de llegar allí, trabajando desde el código fuente de winerror.h, que tengo, como parte del Windows Platform SDK que se incluye con cada versión reciente de Microsoft Visual Studio.

En este momento, estoy en el medio de resolver un problema apremiante en el ensamblado de .NET que me trajo a esta página. Entonces, veré lo que puedo improvisar; este tipo de desafío está en mi callejón, y alguien arrojó un guantelete.

1

Puede tomar las definiciones de winerror.h en Rensselaer Polytechnic Institute, y ponerlos en una enumeración:

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. 
} 

Entonces, si el código de error está en una variable código_error se debería utilizar:

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

Hay una clase de copiar y pegar que contiene estos en http://www.pinvoke.net/default.aspx/Constants/WINERROR.html –

Cuestiones relacionadas