How to check if a file can be deleted
I want to use it during uninstall procedure to warn the user ahead. The procedure should work for W2000+, hence Vista API's are not allowed.
This seems to catch some conflicts:
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 ) ;
}
}
Namely it detects these situations: a) Deleting running exe file b) Deleting opened pdf
Using GENERIC_WRITE|DELETE seems to behave similarly. Using DELETE alone works for the case b), but not for a).
I have no positive evidence that LockFile() catches any meaningful conflict, but suppose it does.
Does anybody have a better idea?
First point: unless you take steps to prevent it, nearly anything you report may change between the time you test, and the time you try to take action based on that test (e.g. after you've tried to check that you can delete it, the user might change it to 'read-only').
To get a meaningful result, instead of using DeleteFile to delete the file, I'd use CreateFile
with FILE_SHARE_DELETE
and the FILE_FLAG_DELETE_ON_CLOSE
flag. If you can't open the file this way, it gives a pretty good clue that you won't be able to delete it. If you can open it this way, then simply closing the handle will delete the file -- and nothing else will be able to open it in the interim unless it also specifies FILE_SHARE_DELETE
(and even if it does, when the last handle to the file is closed, the file will be deleted, so if it's not deleted immediately, it will be soon).
I'm not a C++ programmer, but you could try to rename that file. If you can do that, you probably can delete it.
精彩评论