捕获由Win32函数本身返回异常的演示代码如下:
using System; using System.ComponentModel; // 使用平台调用技术进行互操作性之前,首先需要添加这个命名空间 using System.Runtime.InteropServices; namespace 处理Win32函数返回的错误 { class Program { // Win32 API // DWORD WINAPI GetFileAttributes( // _In_ LPCTSTR lpFileName //); // 在托管代码中对非托管函数进行声明 [DllImport("Kernel32.dll",SetLastError=true,CharSet=CharSet.Unicode)] public static extern uint GetFileAttributes(string filename); static void Main(string[] args) { // 试图获得一个不存在文件的属性 // 此时调用Win32函数会发生错误 GetFileAttributes("FileNotexist.txt"); // 在应用程序的Bin目录下存在一个test.txt文件,此时调用会成功 //GetFileAttributes("test.txt"); // 获得最后一次获得的错误 int lastErrorCode = Marshal.GetLastWin32Error(); // 将Win32的错误码转换为托管异常 //Win32Exception win32exception = new Win32Exception(); Win32Exception win32exception = new Win32Exception(lastErrorCode); if (lastErrorCode != 0) { Console.WriteLine("调用Win32函数发生错误,错误信息为 : {0}", win32exception.Message); } else { Console.WriteLine("调用Win32函数成功,返回的信息为: {0}", win32exception.Message); } Console.Read(); } } }
要想获得在调用Win32函数过程中出现的错误信息,首先必须将DllImport属性的SetLastError字段设置为true,只有这样,平台调用才会将最后一次调用Win32产生的错误码保存起来,然后会在托管代码调用Win32失败后,通过Marshal类的静态方法GetLastWin32Error获得由平台调用保存的错误码,从而对错误进行相应的分析和处理。这样就可以获得Win32中的错误信息了。
上面代码简单地演示了如何在托管代码中获得最后一次发生的Win32错误信息,然而还可以通过调用Win32 API 提供的FormatMessage函数的方式来获得错误信息,然而这种方式有一个很显然的弊端(所以这里就不演示了),当对FormatMessage函数调用失败时,这时候就有可能获得不正确的错误信息,所以,推荐采用.NET提供的Win32Exception异常类来获得具体的错误信息。
关于更多的FormatMessage函数可以参考MSDN: http://msdn.microsoft.com/en-us/library/ms679351(v=vs.85).aspx