Форум: "Основная";
Текущий архив: 2005.01.23;
Скачать: [xml.tar.bz2];
ВнизРабота с 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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.046 c