代码之家  ›  专栏  ›  技术社区  ›  Jackson

CopyFileEx会出现哪些错误代码?

  •  7
  • Jackson  · 技术社区  · 17 年前

    我正在编写一些C++代码,需要调用CopyFielEx函数。与大多数其他WIN32函数一样,CopyFileEx的文档说明:

    如果函数失败,则返回值为零。要获取扩展错误信息,请调用GetLastError。

    这很好,但有人知道我在哪里可以找到特定API函数可能通过GetLastError返回的错误代码列表吗?在这种情况下,我希望以不同的方式处理不同的错误条件,但不需要错误代码列表 对于此功能 我将被简化为生成我想要处理的错误条件,只是为了看看产生了什么错误代码,或者通过从数字0到15999的系统错误代码来猜测哪些可能适用!

    编辑:这里有更多的上下文来帮助解释这个问题,以及为什么我想知道是否有一个明确的错误代码列表,可以由函数在任何地方返回。

    该代码将作为Windows服务的一部分使用,因此当有用户时,他们不会总是在那里响应错误。我需要能够区分不需要每次报告的错误,如果文件被锁定,我只是想稍后再试一次。如果我没有读取特定文件的权限,我可以记录问题并继续,如果目标目录无法读取或已满,则我希望服务停止并触发一个会吸引用户注意力的报告过程。

    3 回复  |  直到 17 年前
        1
  •  6
  •   Michael Burr    17 年前

    Microsoft没有给出API可能返回的所有错误代码的列表,原因很简单,该列表可能会随着时间的推移和Windows的各种实现、安装的驱动程序或简单的疏忽而改变(API通常返回由您调用的API中调用的其他API引起的错误)。

    有时,文档会调用特定的错误,这些错误对于该API的用户来说特别重要,但一般来说,它们不会有一个完整的错误列表。他们也不应该这样做,这是不幸的,但却是生活中的事实。

    然而,覆盖所有场景(包含一个全面的错误代码列表)或防止将来的更改实际上是一个不可能的目标。考虑微软可能需要如何管理Win32中所有拥有的错误代码的记录:

    foo() bar() . foo() ERROR_FOO bar() 可能会产生自己的错误, ERROR_BAR . 然而 foo() 电话 bar() foo() 可能还会回来 错误提示条 如果它呼吁 bar()

    这些文件反映了以下内容:

    • foo() 我也可以回去吗 错误(u FOO) 错误提示条
    • 可能会回来 错误提示条

    现在,当API v2发布时, 已扩展到也返回 ERROR_BAZ

    然而,这个家伙将新的错误添加到 bar() 无法直接看到 foo() 在可能返回的错误方面,用户的行为也发生了变化。在这样一个小的API中,这可能不是什么大问题——在Win32之类的东西中,这将是一团混乱。现在再加上Win32可以依赖于第三方代码(驱动程序、插件、COM对象等),这项任务现在几乎不可能完成。

    实际上,这不一定是一个很好的例子,因为如果错误代码是API契约的一部分 错误_BAZ 不应该出现在画面中。

    所以这里有另一个场景:API有一个 OpenObject() 可以返回的函数 ERROR_NO_MEMORY ERROR_NOT_FOUND . 当这个系统最初开发时,它没有安全概念(比如MS-DOS),但新版本增加了访问控制。现在我们想要 能够返回 ERROR_ACCESS_DENIED ,但它不能,因为这会改变合同,所以需要一个新的API OpenObjectEx() 是为了应对这种情况而增加的。这里至少有两个问题:

    • 随着时间的推移,您将获得大量的API,这些API与旧API相比几乎没有价值
    • 调用旧应用程序的遗留应用程序会发生什么情况 API,由于访问限制而失败?两个约定的错误返回都不能说明问题的真相。

        2
  •  3
  •   Community Mohan Dere    6 年前

    这里有一张 Windows error codes here 但它没有指定每个API调用的错误代码。尽管如此,MSDN站点确实提供了许多关于大多数API方法的有用信息,包括它们可能返回的错误代码。

    FormatMessage 函数可用于将错误转换为正确的错误消息,同时考虑当前的Windows语言。通常,显示这样的错误消息就足够了。您只想为可能出现的错误添加逻辑,即使这样,您也只想显示一条错误消息。

    当读到 CopyFileEx ,除了关于获取GetLastError()调用的部分之外,您还将阅读以下内容:

    如果目标文件已存在且已隐藏文件属性或设置了文件属性只读属性,则此函数将失败,并出现错误“拒绝访问”。

    使用CopyFileEx复制加密文件时,该函数将尝试使用源文件加密中使用的密钥加密目标文件。如果无法完成此操作,此函数将尝试使用默认密钥加密目标文件。如果这两种方法都无法完成,CopyFileEx将失败,并显示错误\加密\失败错误代码。如果希望CopyFileEx在目标文件无法加密的情况下完成复制操作,请在对CopyFileEx的调用中将copy_file_ALLOW_DECRYPTED_destination_作为dwCopyFlags参数的值。

    基本上,这些都是您通常可以预期的错误。所有其他操作只会向用户发送一条错误消息。

    (我讨厌这个网站翻译

        3
  •  1
  •   Ilya    14 年前

    CopyFileEx最终由一系列设备驱动程序来处理,有些是由Microsoft编写的,有些可能不是,设备驱动程序返回一个任意的NTSTATUS代码,该代码被转换为Win32错误代码。由于它可以是返回此NTSTATUS的自定义驱动程序,Microsoft无法向您保证任何有关它的信息。

    CopyFileEx给您一个“简短”列表的唯一方法是,如果CopyFileEx已将详细的错误代码更改为一些简单的错误代码,即它将返回错误\u访问\u拒绝、错误\u共享\u违规或所有其他错误的错误\u GEN \u失败(即它将 隐藏

    更新: 就合同而言,用户代码应该处理CopyFileEx失败(即返回FALSE时)。用户代码可以通过在失败时查询GetLastError来处理零个或多个特定错误代码。

    用户代码很少实际处理错误代码。试图处理所有这些问题肯定不是最佳做法。如果用户代码对特定的错误代码有特定的操作,它应该这样做。否则,处理错误代码的唯一方法是向用户指示错误代码或记录错误代码(请参见FormatMessage),同时将其视为不透明值。