Getting the Windows System Error Code title/description from its hex number

35,152

Solution 1

I'm not sure if there's a niifty .NET wrapper, but you could call the FormatMessage API using P/Invoke.

See this answer for how it would normally be called from native code. Though the question refers to grabbing error codes from HRESULTs, the answer also applies for retreiving codes from the regular OS error codes coming from GetLastError/GetLastWin32Error).

EDIT: Thanks Malfist for pointing me to pinvoke.net, which includes alternative, managed API:

using System.ComponentModel;

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

Solution 2

You could take the defines from winerror.h at Rensselaer Polytechnic Institute, and put them into an 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.
}

Then if your error code is in a variable error_code you would use :

Enum.GetName(typeof(Win32ErrorCode), error_code);
Share:
35,152
Programatt
Author by

Programatt

I am a programmer by day, and a tinkerer by night.

Updated on June 30, 2020

Comments

  • Programatt
    Programatt almost 4 years

    I'm messing around with some windows functions using p/invoke. Occasionally, I get an error code that is not ERROR_SUCCESS (such an odd name).

    Is there a way to look these up within the program? Forexample, if I get error 1017. Can I tell the user

    The system has attempted to load or restore a file into the registry, but the specified file is not in a registry file format. (ERROR_NOT_REGISTRY_FILE: 0x3F9)

    Instead of

    Error Code: 1017

  • Andy Raddatz
    Andy Raddatz over 14 years
    Or just do what Nick said :-)
  • Programatt
    Programatt over 14 years
  • Nick Meyer
    Nick Meyer over 14 years
    @Malfist, thanks for pointing that out. There is a reply there that says it's okay as long as you're using Marshal.GetLastWin32Error to retrieve the error code. Nonetheless, it looks like Win32Exception is a better solution.
  • Programatt
    Programatt over 14 years
    I don't see this. And this doesn't help me display anything to the user.
  • SepehrM
    SepehrM almost 10 years
    How does this answer the OP's question?
  • Adi Inbar
    Adi Inbar almost 9 years
    Note, though, that both of these solutions only get the descriptive error message; neither of these will get you the capitalized error name with underscores that you see in documentation (such as ERROR_NOT_REGISTRY_FILE). For anyone who lands here and is wondering about that, I recently asked a question specifically about how to programmatically determine those error names, and the answer turned out to be that you can't. They refer to constant names from winerror.h, a C++ include file provided in the Windows SDK.
  • Frederik Struck-Schøning
    Frederik Struck-Schøning almost 8 years
    There is a copy-paste class holding these at pinvoke.net/default.aspx/Constants/WINERROR.html
  • matthias_buehlmann
    matthias_buehlmann about 3 years
    This does not work for me, since Marshal.GetLastWin32Error() gives me 0 while [DllImport("kernel32.dll")] private static extern uint GetLastError(); gives me the correct error value. (interestingly, if I set return type to int instead of uint I also get 0, and Marshal.GetLastWin32Error() has int as return type rather than uint). so, I dllimport GetLastError() with uint return type and then get the message by using new Win32Exception((int) GetLastError()).Message
  • Ramon de Klein
    Ramon de Klein almost 3 years
    @matthias_buehlmann Did you set DllImportAttribute.SetLastError set to true? See also: docs.microsoft.com/en-us/dotnet/api/…