如何检查文件是否可以被删除

问题描述:

我想用它卸载过程中,提前向用户发出警告。 该过程应该适用于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文件 b)去除打开PDF

使用GENERIC_WRITE | DELETE似乎同样的行为。 单独使用DELETE适用于情况b),但不适用于a)。

我没有确凿证据证明与LockFile()捕获任何有意义的冲突,但假设它。

是否有人有更好的主意吗?

我不是一个C++程序员,但你可以尝试重命名文件。如果你能做到这一点,你可能会删除它。

+0

谢谢,但这个过程不能因为两个原因中: - 这是一个破坏性操作。 - 它不起作用。例如,一个正在运行的exe可以重命名,但不能被删除。 (与打开的PDF不能重命名不同。) – 2009-11-16 12:34:39

第一点:除非你采取措施,以防止它,几乎任何你可以报告你测试的时间之间的变化,并在尝试的时候,你已经尝试过检查后,您基于该测试(如采取行动可以删除它,用户可能会将其更改为“只读”)。

为了得到有意义的结果,而不是使用的DeleteFile删除的文件,我会使用CreateFileFILE_SHARE_DELETEFILE_FLAG_DELETE_ON_CLOSE标志。如果您无法以这种方式打开文件,它会提供很好的线索,您将无法删除它。如果你可以打开它这样,那么简单地关闭句柄将删除的文件 - 没有别的可以在此期间将其打开,除非它也规定FILE_SHARE_DELETE(即使是这样,当最后一个句柄文件已关闭,文件将被删除,所以如果不立即删除,它将很快)。

+0

谢谢。 1)我认为这是一个可以接受的风险。 (好吧,我们没有事务性文件系统。)重点是我想在开始任何破坏性行为之前发出警告。我知道,有特殊情况...... 2)我试过了,但是的CreateFile(FILE_SHARE_DELETE,FILE_FLAG_DELETE_ON_CLOSE)失败的所有标志组合我试过了。 (我的意思是2个标准试验 - 打开PDF格式,运行EXE。) 作为一个侧面的话,我使用更复杂的删除过程: 一个)的DeleteFile, b)中遥远而明亮只读属性,然后重试删除 C)MoveFileEx(路径, NULL,MOVEFILE_DELAY_UNTIL_REBOOT) – 2009-11-16 13:04:10