2015-06-18 7 views
1

Я использую Windows 7 Professional, и я использую SHFileOperation() для рекурсивного копирования содержимого одной папки в другую. Но есть заблокированный файл (открытый исключительно приложением); Мне нужно пропустить его, но SHFileOperation() возвращает 0x20 при попытке скопировать этот файл.Игнорирование исключительно заблокированных файлов в SHFileOperation

Как пропустить этот файл во время операции копирования файлов?

UPDATE: это код:

// 
// 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

Только RTFM, вы пробовали FOF_NOERRORUI? –

+0

@ ХансПасант да. Я использую 'FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI'. – deselect

+1

Тогда, конечно, он отлично работает и скопировал файлы, которые он мог, и пропустил те, которые он не смог? Возвращаемое значение просто указывает, что не все файлы были скопированы, что обычно имеет значение. –

ответ

3

Документация SHFileOperation() говорит:

Возвращаемое значение

Тип: INT

Возвращает ноль в случае успеха; иначе нет. Приложения обычно должны просто проверять нуль или ненулевое значение.

Рекомендуется проверять значение члена fAnyOperationsAborted SHFILEOPSTRUCT. SHFileOperation может вернуть 0 для успеха, если пользователь отменяет операцию. Если вы не проверите fAnyOperationsAborted и возвращаемое значение, вы не можете знать, что функция выполнила всю заданную вами задачу, и вы можете перейти к неправильным предположениям.

Не используйте GetLastError с возвращаемыми значениями этой функции.

Для проверки ненулевых значений для целей устранения неполадок они в основном сопоставляются с данными, определенными в Winerror.h. Однако некоторые из его возможных возвращаемых значений основаны на кодах ошибок pre-Win32, которые в некоторых случаях перекрывают более поздние значения Winerror.h без соответствия их значения. Эти конкретные значения подробно описаны здесь, и для этих конкретных значений только эти значения должны приниматься по кодам Winerror.h.

В вашем случае 0x20 не один из кодов ошибок до Win32, поэтому он отображает до стандартного кода ошибки Win32, в частности ERROR_SHARING_VIOLATION, который подходит для вашей ситуации, как один из файлов не может быть доступ.

Чтобы пропустить файл-нарушитель, включите флаг FOF_NOERRORUI в поле SHFILEOPSTRUCT::fFlags. Документация SHFILEOPSTRUCT говорит только следующее о том, что флаг:

FOF_NOERRORUI

Не отображать диалоговое окно для пользователя, если происходит ошибка.

Однако документация имеет также сказать:

fAnyOperationsAborted
Тип: BOOL

Когда функция возвращается, этот элемент содержит значение TRUE, если какие-либо операции с файлами прервана, прежде чем они были завершены ; в противном случае FALSE.Операция может быть вручную отменена пользователем через UI или , она может быть автоматически отключена системой, если установлены флаги FOF_NOERRORUI или FOF_NOCONFIRMATION.

Документация IFileOperation (которая заменяет SHFileOperation() на Vista, и позже) имеет больше сказать о FOF_NOERRORUI флага:

FOF_NOERRORUI (0x0400)

Не отображать сообщение пользователю если произошла ошибка. Если этот флаг установлен без FOFX_EARLYFAILURE, любая ошибка обрабатывается так, как если бы пользователь выбрал Ignore или Continue в диалоговом окне. Он останавливает текущее действие, устанавливает флаг, указывающий на то, что действие было прервано, и продолжит оставшуюся часть операции.

...

FOFX_EARLYFAILURE (0x00100000)

Если FOFX_EARLYFAILURE устанавливается вместе с FOF_NOERRORUI, весь набор операций останавливается при встрече с какой-либо ошибки в любой операции. Этот флаг действителен только тогда, когда установлен FOF_NOERRORUI.

Так, с FOF_NOERRORUI включены, возвращаемым значением ERROR_SHARING_VIOLATION, а также SHFILEOPSTRUCT::fAnyOperationsAborted поля быть установлено в TRUE, будет вам сказать, что файл не удался получить доступ во время копирования, но не какого файл в частности. Это не означает, что вся задача SHFileOperation() потерпела неудачу.

+0

Но у меня уже есть FOF_NOERRORUI в fFlags. Это мой код: http://pastebin.com/x4ZNVkAX – deselect

 Смежные вопросы

  • Нет связанных вопросов^_^