Мониторинг изменений на диске

Как определяешь наличие новых файлов? По таймеру или через ReadDirectoryChangesW? Если по таймеру, то оставь его и попробуй вот такой код (тебя интересует флаг FILE_NOTIFY_CHANGE_CREATION):
unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
type
 PFileNotifyInformation = ^TFileNotifyInformation;
 TFileNotifyInformation = record
 NextEntryOffset: DWORD;
 Action: DWORD;
 FileNameLength: DWORD;
 FileName: array [0..MAX_PATH - 1] of WideChar;
 end;
 TForm1 = class(TForm)
 Memo1: TMemo;
 procedure FormCreate(Sender: TObject);
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
const
 Filter = FILE_NOTIFY_CHANGE_FILE_NAME or
 FILE_NOTIFY_CHANGE_DIR_NAME or
 FILE_NOTIFY_CHANGE_ATTRIBUTES or
 FILE_NOTIFY_CHANGE_SIZE or
 FILE_NOTIFY_CHANGE_LAST_WRITE or
 FILE_NOTIFY_CHANGE_LAST_ACCESS or
 FILE_NOTIFY_CHANGE_CREATION or
 FILE_NOTIFY_CHANGE_SECURITY;
var
 Dir: THandle;
 Notify: TFileNotifyInformation;
 BytesReturned: DWORD;
begin
 Dir := CreateFile('d:\', GENERIC_READ,
 FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
 nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
 if Dir <> INVALID_HANDLE_VALUE then
 try
 if not ReadDirectoryChangesW(Dir, @Notify, SizeOf(TFileNotifyInformation),
 False, Filter, @BytesReturned, nil, nil) then
 raise Exception.Create(SysErrorMessage(GetLastError))
 else
 case Notify.Action of
 FILE_ACTION_ADDED: ShowMessage('New file' + Notify.FileName);
 FILE_ACTION_REMOVED: ShowMessage('Delete file' + Notify.FileName);
 FILE_ACTION_MODIFIED: ShowMessage('Modify file' + Notify.FileName);
 FILE_ACTION_RENAMED_OLD_NAME: ShowMessage('Old Name file' + Notify.FileName);
 FILE_ACTION_RENAMED_NEW_NAME: ShowMessage('New Name file' + Notify.FileName);
 end;
 finally
 CloseHandle(Dir);
 end;
end;
end.
Author: Rouse_
Source: Взято из http://forum.sources.ru
ID: 03194
----
unit wfsU;
interface
type
 // Структура с информацией об изменении в файловой системе (передается в callback процедуру)
 PInfoCallback = ^TInfoCallback;
 TInfoCallback = record
 FAction : Integer; // тип изменения (константы FILE_ACTION_XXX)
 FDrive : string; // диск, на котором было изменение
 FOldFileName : string; // имя файла до переименования
 FNewFileName : string; // имя файла после переименования
 end;
 // callback процедура, вызываемая при изменении в файловой системе
 TWatchFileSystemCallback = procedure (pInfo: TInfoCallback);
{ Запуск мониторинга файловой системы
 Параметры:
 pName - имя папки для мониторинга
 pFilter - комбинация констант FILE_NOTIFY_XXX
 pSubTree - мониторить ли все подпапки заданной папки
 pInfoCallback - адрес callback процедуры, вызываемой при изменении в файловой системе}
procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
// Остановка мониторинга
procedure StopWatch;
implementation
uses
 Classes, Windows, SysUtils;
const
 FILE_LIST_DIRECTORY = $0001;
type
 PFileNotifyInformation = ^TFileNotifyInformation;
 TFileNotifyInformation = record
 NextEntryOffset : DWORD;
 Action : DWORD;
 FileNameLength : DWORD;
 FileName : array[0..0] of WideChar;
 end;
 WFSError = class(Exception);
 TWFS = class(TThread)
 private
 FName : string;
 FFilter : Cardinal;
 FSubTree : boolean;
 FInfoCallback : TWatchFileSystemCallback;
 FWatchHandle : THandle;
 FWatchBuf : array[0..4096] of Byte;
 FOverLapp : TOverlapped;
 FPOverLapp : POverlapped;
 FBytesWritte : DWORD;
 FCompletionPort : THandle;
 FNumBytes : Cardinal;
 FOldFileName : string;
 function CreateDirHandle(aDir: string): THandle;
 procedure WatchEvent;
 procedure HandleEvent;
 protected
 procedure Execute; override;
 public
 constructor Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
 destructor Destroy; override;
 end;
var
 WFS : TWFS;
procedure StartWatch(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
begin
 WFS := TWFS.Create(pName, pFilter, pSubTree, pInfoCallback);
end;
procedure StopWatch;
var
 Temp : TWFS;
begin
 if Assigned(WFS) then
 begin
 PostQueuedCompletionStatus(WFS.FCompletionPort, 0, 0, nil);
 Temp := WFS;
 WFS := nil;
 Temp.Terminate;
 end;
end;
constructor TWFS.Create(pName: string; pFilter: cardinal; pSubTree: boolean; pInfoCallback: TWatchFileSystemCallback);
begin
 inherited Create(True);
 FreeOnTerminate := True;
 FName := IncludeTrailingBackslash(pName);
 FFilter := pFilter;
 FSubTree := pSubTree;
 FOldFileName := EmptyStr;
 ZeroMemory(@FOverLapp, SizeOf(TOverLapped));
 FPOverLapp := @FOverLapp;
 ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
 FInfoCallback := pInfoCallback;
 Resume
end;
destructor TWFS.Destroy;
begin
 PostQueuedCompletionStatus(FCompletionPort, 0, 0, nil);
 CloseHandle(FWatchHandle);
 FWatchHandle := 0;
 CloseHandle(FCompletionPort);
 FCompletionPort := 0;
 inherited Destroy;
end;
function TWFS.CreateDirHandle(aDir: string): THandle;
begin
 Result := CreateFile(PChar(aDir), FILE_LIST_DIRECTORY, 
 FILE_SHARE_READ + FILE_SHARE_DELETE + FILE_SHARE_WRITE,
 nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_OVERLAPPED, 0);
end;
procedure TWFS.Execute;
begin
 FWatchHandle := CreateDirHandle(FName);
 WatchEvent;
end;
procedure TWFS.HandleEvent;
var
 FileNotifyInfo : PFileNotifyInformation;
 InfoCallback : TInfoCallback;
 Offset : Longint;
begin
 Pointer(FileNotifyInfo) := @FWatchBuf[0];
 repeat
 Offset := FileNotifyInfo^.NextEntryOffset;
 InfoCallback.FAction := FileNotifyInfo^.Action;
 InfoCallback.FDrive := FName;
 SetString(InfoCallback.FNewFileName, FileNotifyInfo^.FileName, FileNotifyInfo^.FileNameLength);
 InfoCallback.FNewFileName := Trim(InfoCallback.FNewFileName);
 case FileNotifyInfo^.Action of
 FILE_ACTION_RENAMED_OLD_NAME: FOldFileName := Trim(WideCharToString(@(FileNotifyInfo^.FileName[0])));
 FILE_ACTION_RENAMED_NEW_NAME: InfoCallback.FOldFileName := FOldFileName;
 end;
 FInfoCallback(InfoCallback);
 PChar(FileNotifyInfo) := PChar(FileNotifyInfo) + Offset;
 until (Offset = 0) or Terminated;
end;
procedure TWFS.WatchEvent;
var
 CompletionKey: Cardinal;
begin
 FCompletionPort := CreateIoCompletionPort(FWatchHandle, 0, Longint(Pointer(self)), 0);
 ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
 if not ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree,
 FFilter, @FBytesWritte, @FOverLapp, nil) then
 begin
 raise WFSError.Create(SysErrorMessage(GetLastError));
 Terminate;
 end
 else
 begin
 while not Terminated do
 begin
 GetQueuedCompletionStatus(FCompletionPort, FNumBytes, CompletionKey, FPOverLapp, INFINITE);
 if CompletionKey <> 0 then
 begin
 Synchronize(HandleEvent);
 ZeroMemory(@FWatchBuf, SizeOf(FWatchBuf));
 FBytesWritte := 0;
 ReadDirectoryChanges(FWatchHandle, @FWatchBuf, SizeOf(FWatchBuf), FSubTree, FFilter,
 @FBytesWritte, @FOverLapp, nil);
 end
 else
 Terminate;
 end
 end
end;
end.
Пример использования:
unit Unit1;
interface
uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
type
 TForm1 = class(TForm)
 Memo1: TMemo;
 procedure FormCreate(Sender: TObject);
 procedure FormDestroy(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
var
 Form1: TForm1;
implementation
{$R *.dfm}
uses wfsU;
procedure MyInfoCallback(pInfo: TInfoCallback);
const
 Action: array[1..3] of String = ('Создание: %s', 'Удаление: %s', 'Изменение: %s');
begin
 case pInfo.FAction of
 FILE_ACTION_RENAMED_NEW_NAME: Form1.Memo1.Lines.Add(Format('Переименование: %s в %s',
 [pInfo.FDrive+pInfo.FOldFileName, pInfo.FDrive + pInfo.FNewFileName]));
 else
 if pInfo.FAction < FILE_ACTION_RENAMED_OLD_NAME then
 Form1.Memo1.Lines.Add(Format(Action[pInfo.Faction], [pInfo.FDrive+pInfo.FNewFileName]));
 end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
 // мониторим, например, изменения всех папок на диске C: (создание, удаление, переименование)
 StartWatch('C:\', FILE_NOTIFY_CHANGE_DIR_NAME, True, @MyInfoCallback);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
 StopWatch
end;
end.
PS: только для NT/2000/XP/2003
Author: Krid
Source: Взято из http://forum.sources.ru
ID: 03195
Category:Файловая система