【问题标题】:Using SHFileOperation: What errors are occuring使用 SHFileOperation:发生了什么错误
【发布时间】:2010-12-31 04:08:36
【问题描述】:

我正在使用函数 SHFileOperation() 将文件发送到回收站,我收到 2 个错误,我不知道它们的含义,因为使用此函数的错误代码不是 GetLastError() 值。

当函数 SHFileOperation() 失败时,返回值为 0x57(十进制 87)和 0x2(十进制 2)。谁能帮我发现这些错误的定义(特别是当您考虑使用此函数时,这些错误不是GetLastError() 代码的一部分)。

一些重要信息:

  • 我使用的是 Windows 7(我知道 MSDN 说要使用 IFileOperation 而不是 SHFileOperation,但我想让我的应用程序向后兼容,这就是我使用 SHFileOperation 的原因)。如果由于我在 Windows 7 上使用 SHFileOperation 而发生错误,我可以使用什么解决方案来使其在 2000 及更高版本的所有 Windows 版本上都能正常工作?

  • 据我所知,我的 SHFILEOPSTRUCT 是正确的(使用了正确的标志,.pFrom 是一个双空结尾的字符串),我已经进行了广泛的调试。我确定的一件事是我的文件路径是正确的(导致一个真实的文件并且它的格式正确)。

  • 大约 2/5 次 SHFileOperation() 工作,这意味着它将文件发送到回收站并且不返回错误

.

 BOOL result;
 SHFILEOPSTRUCT fileStruct;
 fileStruct.hwnd = hwnd; 
 fileStruct.wFunc = FO_DELETE;
 fileStruct.pFrom = dest.c_str();
 fileStruct.fFlags = FOF_FILESONLY; // FOF_ALLOWUNDO
 fileStruct.fAnyOperationsAborted = result;

 // Call operation(delete file)
 int success = SHFileOperation( &fileStruct );

 // if delete was successful
 if ( success != 0 ) 
 {
    printf( "%s \t %X %d \n", dest.c_str(), success, success );
    cout << result << endl;

    MessageBox( hwnd, "Failed to delete file", "Error", MB_OK|MB_ICONERROR );
    return;
 }

【问题讨论】:

  • 您的评论具有误导性。您应该将其传递到与 if 相同的行或 if 块内,并将其更改为 // if delete failed

标签: c++ winapi


【解决方案1】:

正如 shf301 所说,错误代码 87 是 ERROR_INVALID_PARAMETER。这可能是因为您没有初始化未使用的 SHFILEOPSTRUCT 字段的内容,因此它们将包含随机值。 documentation 表示 pTo “如果不使用,必须设置为 NULL”;操作系统可能正在检查该字段的值,如果它不为 NULL,则返回错误。

首先通过以下任一方式将所有内容设置为零:

SHFILEOPSTRUCT fileStruct = { 0 };

SHFILEOPSTRUCT fileStruct;
ZeroMemory(&fileStruct, sizeof(SHFILEOPSTRUCT));

错误代码2是ERROR_FILE_NOT_FOUND;如果文件可能不存在,或者用户在您的程序尝试删除它之前已将其删除,则忽略此错误代码可能是安全的。 (请注意,即使您在尝试删除文件之前检查该文件是否存在,也可能在此期间另一个进程已将其删除,因此您始终需要处理此错误。)

【讨论】:

    【解决方案2】:

    这个片段有一些严重的问题,我建议阅读SHFILEOPSTRUCT structure

    1. pFrom 必须双空终止。我不知道 dest 是什么类型,但几乎可以肯定它不会返回一个双空终止的字符串。

    2. 如果不使用 pTo 参数,则必须将其设置为 NULL。不允许使用通配符。使用它们会导致不可预知的结果。

    3. 安全的做法是在填充之前调用结构上的零内存

      SHFILEOPSTRUCT shStruct;
      ZeroMemory (&shStruct, sizeof(SHFILEOPSTRUCT));

    4. fileStruct.fAnyOperationsAborted = 结果;不会将函数返回的值放入结果中。 SHFILEOPSTRUCT 存在于堆栈中,可以在调用后简单地读取

    这些问题本身就解释了您得到的错误代码。

    【讨论】:

      【解决方案3】:

      根据 SHFileOperation 文档,这些错误映射到 WinError.h 中的标准 Windows 错误代码,您可以在 this page on MSDN 查找这些错误代码。

      您的错误似乎是:

      ERROR_FILE_NOT_FOUND 2 (0x2) 系统找不到指定的文件。

      ERROR_INVALID_PARAMETER 87 (0x57) 参数不正确。

      【讨论】:

        【解决方案4】:

        当使用SHFileOperation 处理宽字符串时,您不仅需要double-null 终止字符串,而且因为pFrom 是字符串的列表,所以您必须双双- null 终止您的路径字符串:

        所以,在fileStruct.pFrom = dest.c_str(); 声明中,不能保证会给你一个双重null

        你必须在分配之前这样做:

        WCHAR wszFrom[MAX_PATH] = { 0 };
        StrCpyW(wszFrom, dest.c_str());
        CopyMemory(wszFrom + lstrlenW(wszFrom), "\0\0", 2);
        

        然后分配双双空字符串:

        fileStruct.pFrom = wszFrom;
        

        你可以防止这个error

        ERROR_FILE_NOT_FOUND 2 (0x2) The system cannot find the file specified.
        

        【讨论】:

          猜你喜欢
          • 2013-03-07
          • 1970-01-01
          • 1970-01-01
          • 2017-07-22
          • 2021-08-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多