[DllImport("kernel32.dll")]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId, [Out] StringBuilder lpBuffer,
uint nSize, IntPtr Arguments);
// the version, the sample is built upon:
[DllImport("Kernel32.dll", SetLastError=true)]
static extern uint FormatMessage( uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
uint nSize, IntPtr pArguments);
// the parameters can also be passed as a string array:
[DllImport("Kernel32.dll", SetLastError=true)]
static extern uint FormatMessage( uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
uint nSize, string[] Arguments);
<DllImport("Kernel32.dll", EntryPoint:="FormatMessageW", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function FormatMessage(ByVal dwFlags As Integer, ByRef lpSource As IntPtr, ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, ByRef lpBuffer As [String], ByVal nSize As Integer, ByRef Arguments As IntPtr) As Integer
End Function
enum FormatMessageFlags : uint
{
FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100,
FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000,
FORMAT_MESSAGE_FROM_HMODULE = 0x00000800,
FORMAT_MESSAGE_FROM_STRING = 0x00000400,
FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000,
FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200,
FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF,
FORMAT_MESSAGE_FROM_HMODULE = 0x00000800,
FORMAT_MESSAGE_FROM_STRING = 0x00000400
}
To have FormatMessage substitute %1, %2, etc. with arguments you pass it, declare FormatMessage with a string[] for the last parameter and just pass a normal C# string array. You need to include FORMAT_MESSAGE_ARGUMENT_ARRAY in the dwFlags parameter for this to work.
If you are trying use FormatMessage to "decode" an error from Marshal.GetLastWin32Error, go take a look at Marshal.ThrowExceptionForHR (http://msdn.microsoft.com/en-us/library/ckxcyk36(v=VS.80).aspx).
// from header files
const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
int nLastError= Marshal.GetLastWin32Error();
IntPtr lpMsgBuf= IntPtr.Zero;
uint dwChars= FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
IntPtr.Zero,
(uint)nLastError,
0, // Default language
ref lpMsgBuf,
0,
IntPtr.Zero);
if (dwChars==0)
{
// Handle the error.
int le= Marshal.GetLastWin32Error();
return null;
}
string sRet= Marshal.PtrToStringAnsi(lpMsgBuf);
// Free the buffer.
lpMsgBuf= LocalFree( lpMsgBuf );
return sRet;
This functionality is also given by System.ComponentModel.Win32Exception:
string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
Console.WriteLine(errorMessage);
Yet the sample might still be useful for messages not provided by the system.