Getting the Windows System Error Code title/description from its hex number
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);
Comments
-
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 over 14 yearsOr just do what Nick said :-)
-
Programatt over 14 yearspinvoke.net/default.aspx/kernel32/FormatMessage.html Says never to use FormatMessage
-
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 over 14 yearsI don't see this. And this doesn't help me display anything to the user.
-
SepehrM almost 10 yearsHow does this answer the OP's question?
-
Adi Inbar almost 9 yearsNote, 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 almost 8 yearsThere is a copy-paste class holding these at pinvoke.net/default.aspx/Constants/WINERROR.html
-
matthias_buehlmann about 3 yearsThis 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 toint
instead ofuint
I also get 0, and Marshal.GetLastWin32Error() hasint
as return type rather thanuint
). so, I dllimport GetLastError() with uint return type and then get the message by usingnew Win32Exception((int) GetLastError()).Message
-
Ramon de Klein almost 3 years@matthias_buehlmann Did you set
DllImportAttribute.SetLastError
set totrue
? See also: docs.microsoft.com/en-us/dotnet/api/…