Как проверить, можно ли удалить файл - PullRequest
1 голос
/ 13 ноября 2009

Я хочу использовать его во время процедуры удаления, чтобы предупредить пользователя. Процедура должна работать для W2000 +, поэтому Vista API не допускаются.

Кажется, это вызывает некоторые конфликты:

if( GetFileAttributes( lpPath ) == INVALID_FILE_ATTRIBUTES )
{
    // File does not exist
}
else
{
    BOOL bCanDelete = FALSE ;
    HANDLE hFile = CreateFile( path, 
        GENERIC_WRITE /*|DELETE*/, 
        0 /*FILE_SHARE_DELETE*/, 
        NULL, 
        OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL, 
        NULL 
    );
    if( hFile != INVALID_HANDLE_VALUE )
    {
        DWORD size = 10000 ;  // a number > file size allowed
        if( size != INVALID_FILE_SIZE )
        {
            if( LockFile( hFile, 0,0, size,0) )
            {
                UnlockFile( hFile, 0,0, size,0) ;
                bCanDelete = TRUE ;
            }
        }
        CloseHandle( hFile ) ;
    }
}

А именно он обнаруживает следующие ситуации: а) Удаление запущенного exe-файла б) Удаление открытого pdf

Использование GENERIC_WRITE | DELETE ведет себя аналогично. Использование только DELETE работает для случая б), но не для а).

У меня нет никаких положительных доказательств того, что LockFile () отлавливает какой-либо значимый конфликт, но предположим, что это так.

У кого-нибудь есть идея получше?

Ответы [ 2 ]

1 голос
/ 13 ноября 2009

Первое замечание: если вы не предпримете шаги, чтобы предотвратить это, почти все, о чем вы сообщаете, может измениться между временем тестирования и временем, когда вы пытаетесь выполнить действие на основе этого теста (например, после того, как вы попытались проверить, что можете удалите его, пользователь может изменить его на «только для чтения»).

Чтобы получить значимый результат, вместо удаления файла с помощью DeleteFile, я бы использовал CreateFile с FILE_SHARE_DELETE и флагом FILE_FLAG_DELETE_ON_CLOSE. Если вы не можете открыть файл таким способом, это дает довольно хорошую подсказку, что вы не сможете его удалить. Если вы можете открыть его таким образом, то простое закрытие дескриптора приведет к удалению файла - и ничто другое не сможет открыть его в промежутке времени, если в нем также не указано FILE_SHARE_DELETE (и даже если это произойдет, когда последний дескриптор файл закрыт, файл будет удален, поэтому, если он не будет удален сразу, он будет вскоре).

0 голосов
/ 13 ноября 2009

Я не программист на C ++, но вы можете попробовать переименовать этот файл. Если вы можете сделать это, вы, вероятно, можете удалить его.

...