I have this piece of code that has not been modified but all of a sudden it has stopped working... I could swear that it used to work but can't guarantee it. It throws an exception:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
static void Main(string[] args)
{
ErrorMsg(123);
}
[DllImport("kernel32.dll", EntryPoint = "FormatMessageW", CharSet = CharSet.Auto)]
static extern int FormatMessage(int dwFlags, IntPtr lpSource, long dwMessageId, int dwLanguageId, out IntPtr MsgBuffer, int nSize, IntPtr Arguments);
[DllImport("kernel32.dll", Ch开发者_开发问答arSet = CharSet.Auto)]
public static extern int GetThreadLocale();
/// <summary>
/// Gets a Locale specific windows error
/// code specified.
/// </summary>
/// <param name="errorcode">The errorcode.</param>
public static string ErrorMsg(long errorcode)
{
try
{
if (errorcode == 0)
return "No Error";
IntPtr pMessageBuffer;
int dwBufferLength;
string sMsg;
int dwFormatFlags;
//FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS
dwFormatFlags = 0x00000100 | 0x00000200 | 0x00001000;
dwBufferLength = FormatMessage(dwFormatFlags, IntPtr.Zero, errorcode, GetThreadLocale(), out pMessageBuffer, 0, IntPtr.Zero);
if (dwBufferLength == 0)
return "An Unknown Error Has occured.";
sMsg = Marshal.PtrToStringUni(pMessageBuffer);
Marshal.FreeHGlobal(pMessageBuffer);
return sMsg;
}
catch (Exception ex)
{
return "An Unknown Error Has occured.";
}
}
What am I doing wrong here, I can't seem to find anything? Thanks!
Your code worked fine when I tested it on my machine. By the way is there any reason you wouldn't prefer the following method which is a little shorter and achieves equivalent goal:
static void Main()
{
var ex = new Win32Exception(123);
Console.WriteLine(ex.Message);
}
Of course under the covers Win32Exception
PInvokes into FormatMessage
but at least it's the .NET framework that should worry about it, not us.
UPDATE:
Here's how the Win32Exception.GetErrorMessage
method is implemented in .NET:
private static string GetErrorMessage(int error)
{
string result = "";
StringBuilder stringBuilder = new StringBuilder(256);
int num = SafeNativeMethods.FormatMessage(12800, NativeMethods.NullHandleRef, error, 0, stringBuilder, stringBuilder.Capacity + 1, IntPtr.Zero);
if (num != 0)
{
int i;
for (i = stringBuilder.Length; i > 0; i--)
{
char c = stringBuilder[i - 1];
if (c > ' ' && c != '.')
{
break;
}
}
result = stringBuilder.ToString(0, i);
}
else
{
result = "Unknown error (0x" + Convert.ToString(error, 16) + ")";
}
return result;
}
where FormatMessage
is declared like this:
[DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Auto, SetLastError = true)]
public static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr arguments);
Try sMsg = Marshal.PtrToStringUni(pMessageBuffer, dwBufferLength);
精彩评论