在C#代码中,您可以捕获从某些非托管库中深入抛出的本机异常吗?如果是这样,你需要做任何不同的事情来抓住它或做一个标准的尝试...抓住它吗?
您可以使用Win32Exception并使用其NativeErrorCode属性来适当地处理它.
// http://support.microsoft.com/kb/186550 const int ERROR_FILE_NOT_FOUND = 2; const int ERROR_ACCESS_DENIED = 5; const int ERROR_NO_APP_ASSOCIATED = 1155; void OpenFile(string filePath) { Process process = new Process(); try { // Calls native application registered for the file type // This may throw native exception process.StartInfo.FileName = filePath; process.StartInfo.Verb = "Open"; process.StartInfo.CreateNoWindow = true; process.Start(); } catch (Win32Exception e) { if (e.NativeErrorCode == ERROR_FILE_NOT_FOUND || e.NativeErrorCode == ERROR_ACCESS_DENIED || e.NativeErrorCode == ERROR_NO_APP_ASSOCIATED) { MessageBox.Show(this, e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } } }
Catch without()将捕获非CLS兼容的异常,包括本机异常.
try { } catch { }
有关详细信息,请参阅以下FxCop规则 http://msdn.microsoft.com/en-gb/bb264489.aspx
C#和本机代码之间的互操作层将异常转换为托管形式,允许它被C#代码捕获.从.NET 2.0开始,catch (Exception)
应该捕获除了不可恢复的错误之外的任何内容.
在某处使用.NET Reflector我看过以下代码:
try { ... } catch(Exception e) { ... } catch { ... }
嗯,C#不允许抛出不从System.Exception类派生的异常.据我所知,interop marshaller的任何异常包都由继承System.Exception的异常类包装.
所以我的问题是是否可以捕获不是System.Exception的异常.
这取决于您所谈论的本机异常类型.如果你指的是SEH例外,那么CLR会做两件事之一.
在已知的SEH错误代码的情况下,它将它映射到适当的.Net异常(即OutOfMemoryException)
对于不可映射(E_FAIL)或未知代码,它只会抛出一个SEHException实例.
这两个都将被一个简单的"catch(Exception)"块捕获.
可以跨越本机/托管边界的另一种本机异常是C++异常.我不确定它们是如何映射/处理的.我的猜测是,由于Windows在SEH之上实现了C++异常,因此它们只是以相同的方式映射.