benjvr
asked on
New file notification
I need to process files on at a time as they are dropped into a folder by some other part of a system.
Using a timer and checking the contents of the folder is the obvious solution, but is there any way that I can be notified by the OS when a new file is created in the folder and respond to the event?
Regards,
Ben
Using a timer and checking the contents of the folder is the obvious solution, but is there any way that I can be notified by the OS when a new file is created in the folder and respond to the event?
Regards,
Ben
Have a look in the Win API help file - read about the function 'FindFirstChangeNotificati on' - this function tells the OS to keep you informed about changes to a directory.
an example from usenet:
unit FindNextChange;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TFrmFindNextChange = class(TForm)
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FrmFindNextChange: TFrmFindNextChange;
function FindFirstChangeNotificatio nA(lpPathN ame: PAnsiChar;
bWatchSubtree: BOOL; dwNotifyFilter: DWORD): THandle; stdcall;
implementation
{$R *.DFM}
function FindFirstChangeNotificatio nA; external kernel32 name
'FindFirstChangeNotificati onA';
function WinErrorAsString(AErrCode: DWORD): string;
var
lng: integer;
begin
SetLength(Result, MAX_PATH + 1);
lng := FormatMessage(FORMAT_MESSA GE_FROM_SY STEM,
nil,
AErrCode,
LANG_SYSTEM_DEFAULT,
PChar(Result),
MAX_PATH,
nil);
if lng > 0 then
SetLength(Result, lng)
else
Result := 'Unknown error';
end;
procedure TFrmFindNextChange.Button1 Click(Send er: TObject);
const
count: integer = 0;
var
done: boolean;
dwWaitStatus: DWORD;
dwChangeHandle: THandle;
begin
Button1.Enabled := false;
try
dwChangeHandle := FindFirstChangeNotificatio nA(
// 'I:\Dev\Delphi\32\QandD\',
'C:\Windows',
BOOL(1),
FILE_NOTIFY_CHANGE_FILE_NA ME
or FILE_NOTIFY_CHANGE_ATTRIBU TES
or FILE_NOTIFY_CHANGE_SIZE
or FILE_NOTIFY_CHANGE_LAST_WR ITE
);
if dwChangeHandle = INVALID_HANDLE_VALUE then begin
Label1.Caption := 'Error: ' + WinErrorAsString(GetLastEr ror);
Exit;
end;
done := false;
repeat
dwWaitStatus := WaitForSingleObject(dwChan geHandle, 30000);
case dwWaitStatus of
WAIT_OBJECT_0: begin
Inc(count);
Label2.Caption := IntToStr(count);
Label2.Update;
Application.ProcessMessage s;
if FindNextChangeNotification (dwChangeH andle) = false then
Exit;
end;
WAIT_ABANDONED,
WAIT_TIMEOUT,
WAIT_FAILED: done := true;
end;
until done;
finally
Button1.Enabled := true;
end;
end;
end.
unit FindNextChange;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TFrmFindNextChange = class(TForm)
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FrmFindNextChange: TFrmFindNextChange;
function FindFirstChangeNotificatio
bWatchSubtree: BOOL; dwNotifyFilter: DWORD): THandle; stdcall;
implementation
{$R *.DFM}
function FindFirstChangeNotificatio
'FindFirstChangeNotificati
function WinErrorAsString(AErrCode:
var
lng: integer;
begin
SetLength(Result, MAX_PATH + 1);
lng := FormatMessage(FORMAT_MESSA
nil,
AErrCode,
LANG_SYSTEM_DEFAULT,
PChar(Result),
MAX_PATH,
nil);
if lng > 0 then
SetLength(Result, lng)
else
Result := 'Unknown error';
end;
procedure TFrmFindNextChange.Button1
const
count: integer = 0;
var
done: boolean;
dwWaitStatus: DWORD;
dwChangeHandle: THandle;
begin
Button1.Enabled := false;
try
dwChangeHandle := FindFirstChangeNotificatio
// 'I:\Dev\Delphi\32\QandD\',
'C:\Windows',
BOOL(1),
FILE_NOTIFY_CHANGE_FILE_NA
or FILE_NOTIFY_CHANGE_ATTRIBU
or FILE_NOTIFY_CHANGE_SIZE
or FILE_NOTIFY_CHANGE_LAST_WR
);
if dwChangeHandle = INVALID_HANDLE_VALUE then begin
Label1.Caption := 'Error: ' + WinErrorAsString(GetLastEr
Exit;
end;
done := false;
repeat
dwWaitStatus := WaitForSingleObject(dwChan
case dwWaitStatus of
WAIT_OBJECT_0: begin
Inc(count);
Label2.Caption := IntToStr(count);
Label2.Update;
Application.ProcessMessage
if FindNextChangeNotification
Exit;
end;
WAIT_ABANDONED,
WAIT_TIMEOUT,
WAIT_FAILED: done := true;
end;
until done;
finally
Button1.Enabled := true;
end;
end;
end.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
http://www.torry.net/notification.htm
Don