7

I need to writing a Delphi program which will monitor a folder for changes (add, update, rename and removal of files).

I have seen suggestions to use theTShellChangeNotifier. Is this the correct solution for this problem? How should I use it?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Snackmoore
  • 905
  • 3
  • 18
  • 32
  • https://web.archive.org/web/20160518172109/http://www.cromis.net/blog/downloads/directory-watch/ is very good and free. – Gabriel Jun 16 '17 at 19:19

3 Answers3

5

I think this article will help you: Monitoring System Shell Changes using Delphi

Basically it analyzes the TShellChangeNotifier, discards it and then goes for a TSHChangeNotify which is basically a wrapper for the SHChangeNotify windows api function.

Jorge Córdoba
  • 51,063
  • 11
  • 80
  • 130
  • 1
    It seem to be monitor the entire file system, I can only limit it to monitor local hard drives. Is there a way where I could specify the folder it will only monitor? I am worry it might eat up a lot of unnecessary resources. Thanks a lot. – Snackmoore Nov 17 '09 at 08:22
  • I don't think you can, at least with the SHChangeNotify. Nonetheless is shouldn't eat up a lot of resources, you'll just ignore whatever doesn't affects the path you're interested in, windows will monitor all the changes wheter you're listening or not :) – Jorge Córdoba Nov 17 '09 at 08:44
5

This question might help. mghie's answer shows how to properly use ReadDirectoryChangesW.

Community
  • 1
  • 1
jpfollenius
  • 16,456
  • 10
  • 90
  • 156
0

i suggest using madShell

RegisterShellEvent(ShellEvent, pathToMonitor, false, [seItemCreated, seItemRenamed]);

//

procedure Tform.ShellEvent(event: TShellEventType; const obj1, obj2: IShellObj; drive: char; value: cardinal);
var
  filename: string;
  isReady: boolean;
begin
  if (event = seItemCreated) then
    filename := obj1.Path
  else if (event = seItemRenamed) then
    filename := obj2.Path
  else
    exit;

  // try to open to ensure it's read for reading
  repeat
    try
      TfileStream.Create(filename, fmOpenRead + fmShareExclusive).Free;
      isReady := true;
    except
      isReady := false;
      sleep(250);
    end;
  until (isReady) or (not FileExists(filename));

  OutputDebugString(pChar('ShellEvent: ' + filename));

end;
glob
  • 2,960
  • 17
  • 21
  • 1
    I don't know madShell but that `repeat` loop looks very ugly. It continually throws and catches exceptions and has a hard-coded delay...not what I expect from a clean and efficient solution... – jpfollenius Nov 17 '09 at 12:34