Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.01.23;
Скачать: CL | DM;

Вниз

Работа с ReadDirectoryChangesW   Найти похожие ветки 

 
Федюлин Григорий ©   (2005-01-06 12:09) [0]

Уважаемые мастера, кто с функцией ReadDirectoryChangesW НА ТЫ?. Пожалуйста подскажите, как можно фиксировать все изменения в файловой системе и получать имена всех изменившихся файлов. Ссылку: http://www.delphi.xonix.ru/download/filemon1/readdirchanges.zip не предлагать. И статью того же места жительства... У меня имеется програмный код, который выполняет данную функцию, но в нём есть ошибка, которую я не знаю как исправить.


 
Fay ©   (2005-01-06 12:11) [1]

А мы все знаем как исправить ошибку в коде, котороге не видели никогда. Так?


 
Федюлин Григорий ©   (2005-01-06 13:22) [2]

Пожал..ста:

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, ExtCtrls, ClipBrd;
const
BUF_SIZE = 2048;

procedure WorkThread(LV : TListView);stdcall;
var
hDir : THandle;

lpBuf : Pointer;
Ptr   : Pointer;

cbReturn : Cardinal;
FileName : PWideChar;

Item : TListItem;
sTime : _SYSTEMTIME;
begin
// Сначала нам надо получить описатель каталога, за которым мы будем следить
// В данном примере это будет весь диск C:
hDir := CreateFile ("C:\",GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
  or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
// Если ошиблись...
if hDir = INVALID_HANDLE_VALUE
 then begin ShowMessage(SysErrorMessage(GetLastError)); exit; end;

// Выделяем память под буфер
// const BUF_SIZE = 2048 - думаю вполне достаточно
GetMem(lpBuf,BUF_SIZE);

repeat
 // очищаем память перед записью в нее (на всякий случай)
 ZeroMemory(lpBuf,BUF_SIZE);

 // Теперь мы будем ждать пока чего-нибудь в интересующем нас каталоге
 // изменится или произойдет ошибка (и мы выйдем из цикла)
 // FILE_NOTIFY_CHANGE - это список флагов - о них ниже.
 if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,
FILE_NOTIFY_CHANGE_FILE_NAME  +  FILE_NOTIFY_CHANGE_DIR_NAME + FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil)
  then Break;

 // Сюда мы попадаем, если функция выполнилась успешно
 // и lpBuf указывает на одну или несколько структур FILE_NOTIFY_INFORMATION
 Ptr:=lpBuf;
repeat
  // Добавляем новый элемент в TListView (ViewStyle = vsReport )
  Item := LV.Items.Add;

  // Выделяем память под имя файла. Вот именно слово PFileNotifyInformation нужно как-то объявить, ноя не знаю как, а может какуюто библиотеку нужно подключить:
  GetMem(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);//Ошибка
  // Очищаем память - чтобы последним символом после копирования
  // был бы #0 нуль
  ZeroMemory(FileName,PFileNotifyInformation(Ptr).FileNameLength+2);
  // WinAPI функция для копирования Unicode строки
  lstrcpynW(FileName,PFileNotifyInformation(Ptr).FileName,
            PFileNotifyInformation(Ptr).FileNameLength div 2+1);
  // Имя файла у нас дается относительно папки
  // т.е.если изменится файл C:\File\test.dat, то FileName
  // будет равно File\test.dat
  Item.Caption:="C:\"+FileName;
  // Имя файла нам больше не нужно - очищаем память
  FreeMem(FileName);

  // Определяем тип произошедшего действия
  case PFileNotifyInformation(Ptr).Action of
   FILE_ACTION_ADDED    : Item.SubItems.Add("Файл был создан");
   FILE_ACTION_REMOVED  : Item.SubItems.Add("Файл был удален");
   FILE_ACTION_MODIFIED : Item.SubItems.Add("Файл был изменен");
   FILE_ACTION_RENAMED_OLD_NAME :
  Item.SubItems.Add("Файл был переименован и в имени файла - предыдущее имя");
   FILE_ACTION_RENAMED_NEW_NAME :
 Item.SubItems.Add("новое имя после переименования");
   else Item.SubItems.Add("Произошло что-то странное");
  end;

  // Время, когда произошло событие
  GetLocalTime(sTime);
  with sTime do
   Item.SubItems.Add(Format("%.2d:%.2d:%.2d",[wHour,wMinute,wSecond])); // 13:54:20

  // Если эта запись не последняя (NextEntryOffset < >  0), то...
  if PFileNotifyInformation(Ptr).NextEntryOffset=0
   then Break
    else begin
  // ... добавляем строку в примечания (если интересно посмотреть смещение)
     Item.SubItems.Add("Offset : "+
      IntToStr(PFileNotifyInformation(Ptr).NextEntryOffset));
  //Передвигаем указатель на NextEntryOffset байт вперед
     Inc(Cardinal(Ptr),PFileNotifyInformation(Ptr).NextEntryOffset);
  // Теперь Ptr указывает на следующую запись
    end;

 // Передвигать надо именно Ptr, а не lpBuf
 until false;

until false;

// Очищаем память
FreeMem(lpBuf);
end;

Надеюсь вы разберётесь:)


 
Fay ©   (2005-01-06 13:39) [3]

Потом - я на экзамен убегаю.


 
Fay ©   (2005-01-06 13:56) [4]

А какая ошибка-то хоть?


 
Игорь Шевченко ©   (2005-01-06 17:57) [5]

interface
uses
 Windows;

type
 FILE_NOTIFY_INFORMATION = packed record
   NextEntryOffset: DWORD;
   Action: DWORD;
   FileNameLength: DWORD;
   FileName: array[0..0] of WideChar;
 end;
 PFILE_NOTIFY_INFORMATION = ^FILE_NOTIFY_INFORMATION;


?


 
GuAV ©   (2005-01-07 01:59) [6]

Федюлин Григорий ©   (06.01.05 13:22) [2]
procedure WorkThread(LV : TListView);stdcall;
 Item := LV.Items.Add;

Подозрительно... к VCL без синхронайза..



Страницы: 1 вся ветка

Текущий архив: 2005.01.23;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.023 c
1-1105114348
pika
2005-01-07 19:12
2005.01.23
Глюк !!!


3-1103539744
Tek
2004-12-20 13:49
2005.01.23
Подскажите плз, как перегнать таблицу с одной базы в другую..


1-1105352097
ODINUS
2005-01-10 13:14
2005.01.23
Rave


14-1104859911
Cardinal
2005-01-04 20:31
2005.01.23
Теорема Фалеса


4-1102015586
Neiron
2004-12-02 22:26
2005.01.23
Удаление секций из PE файла