Link to home
Start Free TrialLog in
Avatar of benjvr
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
Avatar of d32coder
d32coder

Try these components on Torry's.

http://www.torry.net/notification.htm

Don
Have a look in the Win API help file - read about the function 'FindFirstChangeNotification' - 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 FindFirstChangeNotificationA(lpPathName: PAnsiChar;
  bWatchSubtree: BOOL; dwNotifyFilter: DWORD): THandle; stdcall;

implementation

{$R *.DFM}

function FindFirstChangeNotificationA; external kernel32 name
'FindFirstChangeNotificationA';

function WinErrorAsString(AErrCode: DWORD): string;
var
  lng: integer;
begin
  SetLength(Result, MAX_PATH + 1);
  lng := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                       nil,
                       AErrCode,
                       LANG_SYSTEM_DEFAULT,
                       PChar(Result),
                       MAX_PATH,
                       nil);

  if lng > 0 then
    SetLength(Result, lng)
  else
    Result := 'Unknown error';
end;

procedure TFrmFindNextChange.Button1Click(Sender: TObject);
const
  count: integer = 0;
var
  done:           boolean;
  dwWaitStatus:   DWORD;
  dwChangeHandle: THandle;
begin
  Button1.Enabled := false;
  try
    dwChangeHandle := FindFirstChangeNotificationA(
//                      'I:\Dev\Delphi\32\QandD\',
                      'C:\Windows',
                      BOOL(1),
                      FILE_NOTIFY_CHANGE_FILE_NAME
                      or FILE_NOTIFY_CHANGE_ATTRIBUTES
                      or FILE_NOTIFY_CHANGE_SIZE
                      or FILE_NOTIFY_CHANGE_LAST_WRITE
                      );

    if dwChangeHandle = INVALID_HANDLE_VALUE then begin
      Label1.Caption := 'Error: ' + WinErrorAsString(GetLastError);
      Exit;
    end;

    done := false;
    repeat
      dwWaitStatus := WaitForSingleObject(dwChangeHandle, 30000);

      case dwWaitStatus of
        WAIT_OBJECT_0: begin
          Inc(count);
          Label2.Caption := IntToStr(count);
          Label2.Update;
          Application.ProcessMessages;

          if FindNextChangeNotification(dwChangeHandle) = false then
            Exit;
        end;

        WAIT_ABANDONED,
        WAIT_TIMEOUT,
        WAIT_FAILED:  done := true;
      end;
    until done;
  finally
    Button1.Enabled := true;
  end;
end;

end.
ASKER CERTIFIED SOLUTION
Avatar of gi7mhl
gi7mhl

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial