J
jonfroehlich
I have seen many posts about p/invoking FormatMessage to convert an
error code to a string--unfortunately I can't seem to get it to work.
I read in the SmartPhone SDK that not all Windows CE-based devices
will contain the system message-table resources (when
FORMAT_MESSAGE_FROM_SYSTEM is specified), I'm wondering if that's my
problem? (I'm on a Cingular 2125 WM 5 device running .NET 2.0 SP1).
Also, is there a canonical error code that I can pass to these
functions to test them out?
I've implemented it in two ways (the first way is preferable--less
code).
[DllImport("coredll.dll", SetLastError = true)]
public static extern int FormatMessage(int dwFlags, IntPtr lpSource,
int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize,
IntPtr Arguments);
public static string GetErrorMessage(int errorCode)
{
StringBuilder sb = new StringBuilder(1024);
int error = FormatMessage(FormatMessageFlags.FromSystem,
IntPtr.Zero, errorCode, 0, sb, sb.Capacity, IntPtr.Zero);
Debug.WriteLine("GetErrorMessage : FormatMessage returned:" +
error);
return sb.ToString();
}
FormatMessage always returns 0. I've also tried it this way (from
pinvoke.net):
[DllImport("coredll.dll", SetLastError = true)]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
uint nSize, IntPtr pArguments);
[DllImport("coredll.dll", SetLastError = true)]
static extern IntPtr LocalFree(IntPtr hMem);
public static string GetErrorMessage2(int errorCode)
{
// from header files
const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
IntPtr lpMsgBuf = IntPtr.Zero;
uint dwChars = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
IntPtr.Zero,
(uint)errorCode,
0, // Default language
ref lpMsgBuf,
0,
IntPtr.Zero);
if (dwChars == 0)
{
// Handle the error.
int le = Marshal.GetLastWin32Error();
return null;
}
string sRet = Marshal.PtrToStringUni(lpMsgBuf);
// Free the buffer.
lpMsgBuf = LocalFree(lpMsgBuf);
return sRet;
}
In this case, dwChars is always 0 and calling GetLastWin32Error=317.
error code to a string--unfortunately I can't seem to get it to work.
I read in the SmartPhone SDK that not all Windows CE-based devices
will contain the system message-table resources (when
FORMAT_MESSAGE_FROM_SYSTEM is specified), I'm wondering if that's my
problem? (I'm on a Cingular 2125 WM 5 device running .NET 2.0 SP1).
Also, is there a canonical error code that I can pass to these
functions to test them out?
I've implemented it in two ways (the first way is preferable--less
code).
[DllImport("coredll.dll", SetLastError = true)]
public static extern int FormatMessage(int dwFlags, IntPtr lpSource,
int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize,
IntPtr Arguments);
public static string GetErrorMessage(int errorCode)
{
StringBuilder sb = new StringBuilder(1024);
int error = FormatMessage(FormatMessageFlags.FromSystem,
IntPtr.Zero, errorCode, 0, sb, sb.Capacity, IntPtr.Zero);
Debug.WriteLine("GetErrorMessage : FormatMessage returned:" +
error);
return sb.ToString();
}
FormatMessage always returns 0. I've also tried it this way (from
pinvoke.net):
[DllImport("coredll.dll", SetLastError = true)]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
uint nSize, IntPtr pArguments);
[DllImport("coredll.dll", SetLastError = true)]
static extern IntPtr LocalFree(IntPtr hMem);
public static string GetErrorMessage2(int errorCode)
{
// from header files
const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
IntPtr lpMsgBuf = IntPtr.Zero;
uint dwChars = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
IntPtr.Zero,
(uint)errorCode,
0, // Default language
ref lpMsgBuf,
0,
IntPtr.Zero);
if (dwChars == 0)
{
// Handle the error.
int le = Marshal.GetLastWin32Error();
return null;
}
string sRet = Marshal.PtrToStringUni(lpMsgBuf);
// Free the buffer.
lpMsgBuf = LocalFree(lpMsgBuf);
return sRet;
}
In this case, dwChars is always 0 and calling GetLastWin32Error=317.