忽略SHFileOperation中的独占锁定文件

时间:2015-06-18 22:28:00

标签: winapi shfileoperation

我使用的是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;
}

1 个答案:

答案 0 :(得分:4)

SHFileOperation()文档说:

  

返回值

     

输入:int

     

如果成功则返回零;否则非零。 应用程序通常只需检查零或非零。

     

最好检查SHFILEOPSTRUCT的fAnyOperationsAborted成员的值。如果用户取消操作,SHFileOperation可以返回0表示成功。 如果您没有检查fAnyOperationsAborted以及返回值,则无法知道该函数是否完成了您提出的完整任务,并且您可能会在错误的假设下继续。

     

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

     

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

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

要跳过违规文件,请在FOF_NOERRORUI字段中启用SHFILEOPSTRUCT::fFlags标记。 SHFILEOPSTRUCT文档仅针对该标志说明了以下内容:

  

FOF_NOERRORUI

     

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

但是,文档也说明了这一点:

  

fAnyOperationsAborted
  键入:BOOL

     

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

IFileOperation的文档(取代Vista及更高版本的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()任务完全失败。