Мне нужно знать метод, чтобы определить, открыт ли файл в монопольном режиме или иным образом (чтение-запись и т. Д.)? - PullRequest
0 голосов
/ 04 октября 2018

У меня есть приложение для резервного копирования, и я до сих пор использовал компонент Zipmaster, в котором файлы Excel / Word, даже если открыть, получит сжатый, но файлы PST будут пропущены.Другими словами, файлы, которые заблокированы исключительно другими процессами, пропускаются.Мой новый инструмент сжатия останавливается с ошибкой при обнаружении исключительно заблокированного файла.Поэтому я хочу перехватывать и пропускать исключительно открытые файлы.Все файлы Deligni Assignfile и т. Д. Выдают одно и то же сообщение для файлов, открытых в Excel / Word или PST.

Мне нужно знать способ определения, открывается ли файл другими процессами в монопольном режиме или иным образом (чтение-запись и т. Д.).)?

Примечание: я не могу использовать Volume Shadow Copy на некоторых дисках, например: Fat32

С уважением

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Это то, что я использую ..

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;
0 голосов
/ 04 октября 2018

Вы можете использовать функцию CreateFile для проверки доступа к файлу из вашего потока.

Что сказано в Документах:

Создает или открывает файл или устройство ввода-вывода.<..> Функция возвращает дескриптор, который можно использовать для доступа к файлу или устройству для различных типов ввода / вывода в зависимости от файла или устройства и указанных флагов и атрибутов.

Давайте напишем некоторый код:

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
  2. Функция FormatMessage
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...