views:

203

answers:

2

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?

A: 

I'm not a C++ programmer, but you could try to rename that file. If you can do that, you probably can delete it.

Rubens Farias
Thanks, but this procedure cannot be used because of 2 reasons:- It is a destructive action.- It does not work. For example a running exe can be renamed, but can't be deleted. (Unlike that an opened PDF cannot be renamed.)
Jan Slodicka
+1  A: 

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).

Jerry Coffin
Thanks.1) I think it is an acceptable risk. (Well, we don't have transactional file system.) The point is I want to issue a warning prior to start any destructive action. I know, special cases exist...2) I tried that, but CreateFile(FILE_SHARE_DELETE,FILE_FLAG_DELETE_ON_CLOSE) fails for all flags combinations I tried. (I mean for 2 standard tests - opened pdf, running exe.)As a side remark, I use more complex delete procedure:a) DeleteFile,b) Remore readonly attribute and retry deletec) MoveFileEx( path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT )
Jan Slodicka