Board index » delphi » monitoring directory contents

monitoring directory contents

I would like to monitor the contents of a folder and run a procedure when
there are changes inside. Right now what I do is list the directory every 30
seconds and then compare the list with the old one. I think this is highly
efficient and if anyone has any idea how I could do it please do let me
know. Much thanks.
 

Re:monitoring directory contents


Do you use a FindFirstChangeNotification function?

--
With best regards, Mike Shkolnik
E-Mail: mshkol...@scalabium.com
        mshkol...@yahoo.com
WEB: http://www.scalabium.com

Gerald <jh...@SingaporeMail.Com> D???
???Y??:191C91BDFE8ED411B84400805FBE794C21B75...@pfs21.ex.nus.edu.sg...

Quote
> I would like to monitor the contents of a folder and run a procedure when
> there are changes inside. Right now what I do is list the directory every
30
> seconds and then compare the list with the old one. I think this is highly
> efficient and if anyone has any idea how I could do it please do let me
> know. Much thanks.

Re:monitoring directory contents


FindFirstChangeNotification
WaitForSingleObject

Although personally I would stick with polling.

procedure TForm1.Button1Click(Sender: TObject);
Var
  Flag : Bool;
  Hnd : DWORD;
  Path : String;
begin
  Flag := False ;  //Watch Dir not Dir Tree
  Path := 'c:\t' ; //Path to watch
  Hnd := FindFirstChangeNotification(PChar(Path), Flag,
FILE_NOTIFY_CHANGE_FILE_NAME);
  If Hnd = INVALID_HANDLE_VALUE Then
     Begin
       ShowMessage( 'Invalid Handle Returned' ) ;
       Exit;
     End;
  If WaitForSingleObject(Hnd, INFINITE) = WAIT_FAILED Then
     Begin
       ShowMessage( 'Wait Failed' ) ;
       Exit;
     End;
  // The Thread Returns When A File is Added/Deleted/Renamed
  ShowMessage('Something Happened') ;
end;

On Mon, 11 Mar 2002 17:54:54 +0800, "Gerald" <jh...@SingaporeMail.Com>
wrote:

Quote
>I would like to monitor the contents of a folder and run a procedure when
>there are changes inside. Right now what I do is list the directory every 30
>seconds and then compare the list with the old one. I think this is highly
>efficient and if anyone has any idea how I could do it please do let me
>know. Much thanks.

Re:monitoring directory contents


Quote
"J French" <je...@iss.u-net.com> wrote in message

news:3c8cbb43.18431450@news.u-net.com...

Quote

> FindFirstChangeNotification
> WaitForSingleObject

IIRC there may be a problem using FindFirstChangeNotification on W95/98
platforms. The details are not clear in my mind so I'd suggest a google
search of the delphi newsgroups.

Quote

> Although personally I would stick with polling.

If its working don't fix it ;).

Re:monitoring directory contents


If i use waitforsingleobject and there are no changes wouldnt my program
wait forever and even if there is another user input to the prorgam it
wouldnt respond cos it would be in the waitforsingleobject state

Quote
>        Exit;
>      End;
>   If WaitForSingleObject(Hnd, INFINITE) = WAIT_FAILED Then
>      Begin
>        ShowMessage( 'Wait Failed' ) ;
>        Exit;
>      End;
>   // The Thread Returns When A File is Added/Deleted/Renamed
>   ShowMessage('Something Happened') ;
> end;

> On Mon, 11 Mar 2002 17:54:54 +0800, "Gerald" <jh...@SingaporeMail.Com>
> wrote:

> >I would like to monitor the contents of a folder and run a procedure when
> >there are changes inside. Right now what I do is list the directory every
30
> >seconds and then compare the list with the old one. I think this is
highly
> >efficient and if anyone has any idea how I could do it please do let me
> >know. Much thanks.

Re:monitoring directory contents


Quote
"Gerald" <jh...@SingaporeMail.Com> wrote in message

news:191C91BDFE8ED411B84400805FBE794C21C2C862@pfs21.ex.nus.edu.sg...

Quote
> If i use waitforsingleobject and there are no changes wouldnt my program
> wait forever and even if there is another user input to the prorgam it
> wouldnt respond cos it would be in the waitforsingleobject state

yes
  you could loop around wait with a timeout
  processmessages if timeout rather than object signal

or use something not altogether unlike

var ha:array[0..1] of thandle;
var h:thandle;

 h:=findfirstchangenotification(target,false,
FILE_NOTIFY_CHANGE_LAST_WRITE);
 ha[0]:=h;
 terminatefilewait:=false;
 repeat
   waitresult:=  MsgWaitForMultipleObjects(1,ha,false,INFINITE,QS_ALLINPUT);
   if waitresult= WAIT_TIMEOUT
   then // do timeout processing if used
   else
   begin
      if waitresult = WAIT_OBJECT_0 then
      begin
        //filechange processing
        findnextchangenotification(h);
      end
      else
      if waitresult = WAIT_OBJECT_0 +1
      then  //etcetcetc
      else
      begin // no objects .. must be app message queue
        application.processmessages;
        if application.terminated then
         terminatefilewait:=true;
      end;
    end;
 until terminatefilewait;
 FindCloseChangeNotification(h);

Re:monitoring directory contents


Quote
"Gerald" <jh...@SingaporeMail.Com> wrote in message

news:191C91BDFE8ED411B84400805FBE794C21C2C862@pfs21.ex.nus.edu.sg...

Quote
> If i use waitforsingleobject and there are no changes wouldnt my program
> wait forever and even if there is another user input to the prorgam it
> wouldnt respond cos it would be in the waitforsingleobject state

Yes. One solution is to put the change notification and wait code in its own
thread.

Re:monitoring directory contents


In article <191C91BDFE8ED411B84400805FBE794C21C2C...@pfs21.ex.nus.edu.sg>,

Quote
"Gerald" <jh...@SingaporeMail.Com> writes:
>If i use waitforsingleobject and there are no changes wouldnt my program
>wait forever and even if there is another user input to the prorgam it
>wouldnt respond cos it would be in the waitforsingleobject state

Yes, you need to wait for a defined period (the value in mSecs), then consider
two cases ...

Returned as a change notification (return code WAIT_OBJECT_0), return from your
thread and call the main program event handler.

Returned as time-out (returned code WAIT_TIMEOUT) - re-call WaitForSingleObject
after checking forTThread.Terminated and close thread if set.

The time-period for the WFSO should be short enough not to appear long when you
want to close the main program (and so it would call TThread.Terminate).

OTOH I have used a 30 sec poll to check for additions and deletions. As I
wanted to display all the files when one was added, I used a stringlist t hold
the file-names, and did a checksum on the stringlist to check for changes and
trigger a re-dislay.

I also found that FindFirstChangeNotification did not work for mapped remote
directories on a server. I had no reponse to a recent request for help or
solutions to that problem, and so reverted to polling.

Alan Lloyd
alangll...@aol.com

Other Threads