Nol*_*rin 19 c# winapi exception win32exception
我最近编写了很多涉及与Win32 API互操作的代码,并且开始想知道什么是处理由Windows API函数调用引起的本机(非托管)错误的最佳方法.
目前,对本机函数的调用如下所示:
// NativeFunction returns true when successful and false when an error
// occurred. When an error occurs, the MSDN docs usually tell you that the
// error code can be discovered by calling GetLastError (as long as the
// SetLastError flag has been set in the DllImport attribute).
// Marshal.GetLastWin32Error is the equivalent managed function, it seems.
if (!WinApi.NativeFunction(param1, param2, param3))
throw new Win32Exception();
Run Code Online (Sandbox Code Playgroud)
引发异常的行可以等效地重写,我相信:
throw new Win32Exception(Marshal.GetLastWin32Error());
Run Code Online (Sandbox Code Playgroud)
现在,这很好,它会抛出一个异常,包含设置的Win32错误代码以及作为MessageException对象属性的(通常)人类可读的错误描述.但是,我一直认为修改/包装至少一些(如果不是全部)这些异常是明智的,这样它们会给出一个稍微更多的面向上下的错误消息,即在本机代码的任何情况下都更有意义.正在使用.我考虑了几个替代方案:
在构造函数中指定自定义错误消息Win32Exception.
throw new Win32Exception(Marshal.GetLastWin32Error(), "My custom error message.");
Run Code Online (Sandbox Code Playgroud)包装Win32Exception在另一个Exception对象中,以便保留原始错误代码和消息(Win32Exception现在InnerException是父异常).
throw new Exception("My custom error message.", Win32Exception(Marshal.GetLastWin32Error()));
Run Code Online (Sandbox Code Playgroud)与2相同,除了使用另一个Win32Exception作为包装器异常.
与2相同,除了使用从Exception包装器异常派生的自定义类.
与2相同,除了在适当时使用BCL(基类库)异常作为父类.不确定它是否InnerException适合Win32Exception在这种情况下设置为(也许对于低级包装器而不是更高级/抽象的接口,这并不能说明Win32互操作在幕后发生?)
基本上我想知道的是:在.NET中处理Win32错误的推荐做法是什么?我看到它以各种不同的方式在开源代码中完成,但我很好奇是否有任何设计指南.如果没有,我会对您的个人偏好感兴趣.(也许你甚至没有使用上述方法?)
这并不是真正特定于 Win32 异常;问题是,什么时候应该由两个不同的 Exception 派生类型来标识两个不同的错误情况,以及它们什么时候应该抛出内部存储有不同值的相同类型?
不幸的是,如果不事先知道代码将被调用的所有情况,这是不可能回答的。:) 这是只能按类型过滤异常的问题。一般来说,如果您强烈认为以不同的方式处理两个错误情况会很有用,请抛出不同的类型。
否则,经常出现的情况是 Exception.Message 返回的字符串只需要记录或显示给用户。
如果有其他信息,请用您自己的更高级别的内容包装 Win32Exception。例如,您正在尝试对文件执行某些操作,而您运行的用户没有执行此操作的权限。捕获 Win32Exception,将其包装在您自己的异常类中,其消息给出文件名和正在尝试的操作,后跟内部异常的消息。