我正在编写一些需要调用CopyFileEx函数的C++代码.像大多数其他WIN32函数一样,CopyFileEx的文档说:
如果函数失败,则返回值为零.要获取扩展错误信息,请调用GetLastError.
这一切都很好 - 但有谁知道我在哪里可以找到特定API函数可能通过GetLastError返回的错误代码列表?在这种情况下,我想以不同的方式处理不同的错误条件,但没有这个函数的错误代码列表,我将减少到生成我想要处理的错误条件,只是为了看看产生了什么错误代码或去了通过数字0到15999的系统错误代码试图猜测哪些可能适用!
编辑:这里有一个更多的上下文来帮助解释这个问题以及为什么我想知道是否有一个确定的错误代码列表,可以由函数返回任何地方.
代码将用作Windows服务的一部分,因此虽然有用户,但他们并不总是在那里响应错误.我需要能够区分每次都不需要报告的错误,如果文件被锁定我只是稍后再重新尝试一次.如果我没有读取特定文件的权限,我可以记录问题并继续,如果目标目录不可读或已满,那么我希望服务停止并触发报告过程,这将吸引注意力用户.
如果没有CopyFileEx失败方式的全面列表,我发现很难做到这一点.
Microsoft没有提供API可能返回的所有错误代码的列表,原因很简单,因为列表可能会随着时间的推移而发生变化,Windows的各种实现,安装的驱动程序或简单的疏忽(API通常会返回由其中一个API调用的错误引起的错误你打过电话了).
有时,文档会调出特定于该API用户特别感兴趣的错误,但通常它们不会有明确的完整错误列表.它们也不应该是不幸的,但这是生活中的事实.
我同情你的困境 - 有很多次我会喜欢这种信息,所以我可以更好地了解如何处理应该预料到的问题 - 特别是那些有合理恢复路径的问题.通常我会尝试通过测试找到API的失败行为来处理这个问题,我想避免这种情况,因为它很痛苦,并且确保我已经涵盖了所有场景或未来差异.
但是,覆盖所有场景(包含错误代码的完整列表)或防止未来的更改实际上是一个不可能实现的目标.考虑一下Microsoft如何管理在Win32中记录所有可能的错误代码:
假设Win32 API只有两个功能:foo()
和bar()
. foo()
可能会生成自己的错误,ERROR_FOO
并bar()
可能会生成自己的错误ERROR_BAR
.然而,foo()
电话bar()
,所以foo()
也可能会返回ERROR_BAR
如果调用bar()
返回的错误.
文档反映了以下内容:
foo()
可以重新调整ERROR_FOO
或ERROR_BAR
bar()
可能会回来 ERROR_BAR
现在,当API v2发布时,bar()
已经扩展到也返回ERROR_BAZ
.对于这个API大小的东西,它很容易管理bar()的文档需要更新以添加新的错误代码(但是,请注意,对于像真正的Win32这样大的API和像MS一样大的组织,同样可能不是真的,但我们假设它是).
但是,添加新错误的人bar()
无法直接了解事实,其foo()
行为也会因可能返回的错误而发生变化.在这个小的API中,它可能不是什么大问题 - 在像Win32这样的东西中它会是一团糟.现在抛出Win32可以依赖第三方代码(驱动程序,插件,COM对象等)的事实,现在几乎不可能执行任务.
实际上,这不一定是一个很好的例子,因为如果错误代码是API合同的一部分ERROR_BAZ
应该永远不会出现.
所以这是另一个场景:API有一个OpenObject()
可以返回ERROR_NO_MEMORY
或的函数ERROR_NOT_FOUND
.当这个系统最初开发时,它没有安全概念(比如MS-DOS),但是新版本增加了访问控制.现在我们希望OpenObject()
能够返回ERROR_ACCESS_DENIED
,但它不能,因为这将改变合同,因此OpenObjectEx()
添加了一个新的API 来处理这种情况.这里至少有两个问题:
OpenObject()
API并因访问限制而失败的遗留应用程序会发生什么?合同错误返回都没有说明问题是什么.这个问题是许多人认为异常规范(在C++或Java中)不是一个坏主意的原因之一.