2

我正在使用 Windows 7 Professional,并且我正在使用SHFileOperation()将一个文件夹内容递归复制到另一个文件夹。但是有一个锁定的文件(由应用程序独占打开);我需要跳过它,但SHFileOperation()在尝试复制此文件时返回 0x20。

如何在文件复制操作期间跳过此文件?

更新:这是代码:

//
// CopyDirectory()
//  рекурсивное копирование содержимого одной директории в другую средствами Windows
// lpszSource      - исходная папка
// lpszDestination - папка назначения
//
BOOL CopyDirectory( LPSTR lpszSource, LPSTR lpszDestination )
{
    LPSTR lpszNewSource = NULL;

    // структура операции с файлами
    SHFILEOPSTRUCT fileOP = { 0 };

    // выделим память под новый путь
    lpszNewSource = (LPSTR)calloc(strlen(lpszSource) + 50, 1);

    // запишем новый путь с маской
    wsprintf(lpszNewSource, "%s\\*", lpszSource);

    // запишем параметры операции копирования
    fileOP.wFunc    = FO_COPY;
    fileOP.pTo  = lpszDestination;
    fileOP.pFrom    = lpszSource;
    fileOP.fFlags   = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI;

    // выполняем операцию
    INT retVal = SHFileOperation( &fileOP );

    // освободим память
    FREE_NULL(lpszNewSource);

    DebugPrint(DEBUG_INFO, "retVal = %d\n", retVal);

    // возвращаем результат копирования
    return retVal == 0;
}
4

1 回答 1

4

SHFileOperation()文档说:

返回值

类型:整数

如果成功则返回零;否则非零。应用程序通常应该简单地检查零或非零。

最好检查 SHFILEOPSTRUCT 的 fAnyOperationsAborted 成员的值。如果用户取消操作,SHFileOperation 可以返回 0 表示成功。如果您不检查 fAnyOperationsAborted 以及返回值,则您无法知道该函数完成了您要求它完成的全部任务,并且您可能会在不正确的假设下继续进行。

不要将此函数的返回值与 GetLastError 一起使用。

为了检查非零值以进行故障排除,它们主要映射到 Winerror.h 中定义的值。但是,它的几个可能的返回值是基于 Win32 之前的错误代码,在某些情况下,这些代码会与后面的 Winerror.h 值重叠,但不匹配它们的含义。此处详细介绍了这些特定值,对于这些特定值,Winerror.h 代码仅应接受这些含义。

在您的情况下,0x20不是 Win32 之前的错误代码之一,因此它映射到标准的 Win32 错误代码,具体来说ERROR_SHARING_VIOLATION,这适合您的情况,因为其中一个文件无法访问。

要跳过有问题的文件,请在字段中启用FOF_NOERRORUI标志。SHFILEOPSTRUCT::fFlagsSHFILEOPSTRUCT文档仅说明了有关该标志的以下内容:

FOF_NOERRORUI

如果发生错误,不要向用户显示对话框。

但是,文档也确实这样说:

fAnyOperationsAborted
类型:BOOL

当函数返回时,如果任何文件操作在完成之前被中止,则此成员包含 TRUE;否则,错误。用户可以通过 UI 手动中止操作,或者如果设置了 FOF_NOERRORUI 或 FOF_NOCONFIRMATION 标志,则可以由系统静默中止

(在 Vista 和更高版本上IFileOperation替换)的文档对标志有更多的说明:SHFileOperation()FOF_NOERRORUI

FOF_NOERRORUI (0x0400)

如果发生错误,不要向用户显示消息。如果在没有 FOFX_EARLYFAILURE 的情况下设置此标志,则任何错误都将被视为用户在对话框中选择了忽略或继续。它暂停当前操作,设置一个标志以指示操作已中止,然后继续操作的其余部分。

...

FOFX_EARLYFAILURE (0x00100000)

如果 FOFX_EARLYFAILURE 与 FOF_NOERRORUI 一起设置,则在任何操作中遇到任何错误时都会停止整个操作集。此标志仅在设置 FOF_NOERRORUI 时有效。

因此,FOF_NOERRORUI启用后, 的返回值ERROR_SHARING_VIOLATION以及SHFILEOPSTRUCT::fAnyOperationsAborted设置为 TRUE 的字段将告诉您在复制期间无法访问文件,而不是具体是哪个文件。这并不意味着整个SHFileOperation()任务完全失败。

于 2015-06-19T02:22:21.370 回答