我需要知道一种确定文件是否以独占模式打开或其他方式(读写等)的方法吗?

时间:2018-10-04 18:15:02

标签: delphi file-io

我有一个备份应用程序,并且一直使用Zipmaster组件,到目前为止,即使打开,Excel / Word文件也将被压缩,但PST文件将被跳过。 换句话说,将跳过仅由其他进程锁定的文件。当遇到独占锁定的文件时,我的新压缩工具因错误而暂停。因此,我想捕获并跳过专门打开的文件。对于在Excel / Word或PST中打开的文件,Delphi的Assignfile等都给出相同的消息。

我需要知道一种确定文件是否由其他进程以独占模式或其他方式(读写等)打开的方法吗?

请注意:我不能在某些驱动器上使用“卷影复制”,例如:Fat32

致谢

2 个答案:

答案 0 :(得分:2)

这就是我用的..

function IsFileInUse(FileName: TFileName): Boolean;
var
  HFileRes: HFILE;
begin
  result := False;
  if not FileExists(FileName) then exit;
   HFileRes := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil, 
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
   result := (HFileRes = INVALID_HANDLE_VALUE);
   if not result then CloseHandle(HFileRes);
end;

答案 1 :(得分:1)

您可以使用CreateFile function测试文件是否可以从您的线程访问。

文档所说的:

  

创建或打开文件或I / O设备。 <..>函数返回一个句柄,根据文件或设备以及指定的标志和属性,该句柄可用于访问各种类型的I / O的文件或设备。

让我们写一些代码:

procedure Button1Click(Sender: TObject);
var
  FileName: String;
  FileHandle: THandle;
  Flags: Cardinal;
  LastError: Cardinal;
  TextErrorCode: PChar;

  procedure DisplayNotification;
  begin
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or 
                  FORMAT_MESSAGE_FROM_SYSTEM, 
                  nil, LastError, LANG_USER_DEFAULT, 
                  @TextErrorCode, 0, nil
                 );
    ShowMessage(TextErrorCode);
    LocalFree(HLOCAL(TextErrorCode));
  end;

begin
  FileName := 'YourPath + YourFileName';
  Flags := GetFileAttributes(PChar(FileName));
  if Flags <> INVALID_FILE_ATTRIBUTES then
    begin
      if (faDirectory and Flags) <> faDirectory then
        begin
          FileHandle := CreateFile(PChar(FileName),
                                   GENERIC_READ, FILE_SHARE_READ,
                                   nil, OPEN_EXISTING, 0, 0
                                  );
          LastError := GetLastError;
          try
            if FileHandle <> INVALID_HANDLE_VALUE then
              begin
                // Execute you backup code
              end;
          finally
            CloseHandle(FileHandle);
          end;

          // Notify user about problems with opening the file
          if FileHandle = INVALID_HANDLE_VALUE then
            DisplayNotification;
        end
      else
        // Notification about specified filename defines a directory not a single file
    end
  else
    begin
      // Notify user if there is a problem with getting file's attributes
      LastError := GetLastError;
      DisplayNotification;
    end;
end;

现在,您可以检查文件是否被另一个进程占用,如果不是,则执行代码以备份打开的文件。

有用的链接:

  1. GetFileAttributes function
  2. FormatMessage function