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

4

45

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

Linkous answered 30/10, 2009 at 16:19 Comment(0)
S
122

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);
Sanderling answered 30/10, 2009 at 16:23 Comment(5)
pinvoke.net/default.aspx/kernel32/FormatMessage.html Says never to use FormatMessageLinkous
@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.Sanderling
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.Norwich
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()).MessageEuchre
@Euchre Did you set DllImportAttribute.SetLastError set to true? See also: learn.microsoft.com/en-us/dotnet/api/…Chiffon
R
4

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);
Rickettsia answered 10/12, 2015 at 12:2 Comment(1)
There is a copy-paste class holding these at pinvoke.net/default.aspx/Constants/WINERROR.htmlWurster
S
-1

I landed on this page while in search of a managed alternative to calling FormatMessage through P/Invoke.

As others have said, there is no way to get those capitalized, underscored names, short of looking them up in winerror.h, which I have seen reproduced online in various places where I landed in the course of searching for information about resolving specific status codes. A quick Google search, for winerror.h, itself, uncovered a page, at Rensselaer Polytechnic Instutute, where someone has helpfully extracted the #define statements from it.

Looking at it gave me an idea; I think there may be a way to get there, working from the source code of winerror.h, which I have, as part of the Windows Platform SDK that ships with every recent version of Microsoft Visual Studio.

Right now, I am in the middle of sorting out a pressing issue in the .NET assembly that brought me to this page. Then, I'll see what I can cobble together; this kind of challenge is right up my alley, and somebody threw down a gauntlet.

Sussex answered 9/10, 2015 at 21:53 Comment(0)
M
-7

Yes there's a function that does that but I don't remember what it is. In the mean time, you can use the error lookup tool (Tools->Error Lookup) to see what a particular code means from within Visual Studio.

Misadventure answered 30/10, 2009 at 16:23 Comment(3)
Or just do what Nick said :-)Misadventure
I don't see this. And this doesn't help me display anything to the user.Linkous
How does this answer the OP's question?Retrad

© 2022 - 2024 — McMap. All rights reserved.