Solved

Detect File Changes in Dir

Posted on 2000-05-02
6
183 Views
Last Modified: 2012-05-04
How can i detect if a File have changed in a special directory (I mean a new File, a File was deleted . . . .)
And how can i detect if a SubFolder was changed ?
0
Comment
Question by:snoopy_Spy
6 Comments
 
LVL 7

Expert Comment

by:daniel_c
ID: 2771592
You can use TTimer to detect it.
I give you an example:
1. Make New Application from Delphi IDE.
2. Add component TFileListBox
3. Add Component TTimer

On Form Event Create, put this code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  FileListBox1.Directory:= 'C:\';
end;

On TTimer Event Timer, put this code:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  FileListBox1.Update;
end;


Below is the whole code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, FileCtrl, ExtCtrls;

type
  TForm1 = class(TForm)
    FileListBox1: TFileListBox;
    Timer1: TTimer;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose:= false;
  ShowMessage('Sorry, cannot close!');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FileListBox1.Directory:= 'C:\';
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  FileListBox1.Update;
end;

end.

It will always update information on folder C:\.

Hope it will help!

Regards,

Daniel
0
 
LVL 20

Expert Comment

by:Madshi
ID: 2772374
Under win9x you can use FindFirstFileNotification, but this API only tells you that *something* has happened, it doesn't tell you the filename etc.
Under winNT you can use ReadDirectoryChangesW, which tells you all you want to know.

Regards, Madshi.
0
 
LVL 1

Expert Comment

by:Asw
ID: 2773113
Listening.
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

Author Comment

by:snoopy_Spy
ID: 2773152
Sorry but this is not the way i would like to make it !

Madshi
Have you some further infos about the two functions ?
0
 
LVL 20

Accepted Solution

by:
Madshi earned 50 total points
ID: 2773182
Hmmm... There's a component in the free RxLibrary for FindFirstFileNotification. Look here:

http://www.rxlib.com/

I've nothing for ReadDirectoryChangesW, sorry.

Regards, Madshi.
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 2773211
here's a component I wrote some years ago, so I can't remember a lot about it, but it provides a changed event if the montitored directory changes. I can also monitor subdirectories, and allows you to specify what you'd like to monitor.

Anyway, have a look at it and see if it's what you want.

unit changed;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

type
  EChangeError = class(exception);

  TChangeSet = (ntFileName, ntDirName, ntAttributes, ntSize, ntLastWrite, ntSecurity);
  TChangeType = set of TChangeSet;

  TChanged = class;

  TWaitThread = class(TThread)
  private
    EventArray:array[0..1] of THandle;
    fNotifyType : DWORD;
    fChanged : TChanged;
  protected
    Procedure Execute;override;
  public
    Constructor Create(NotifyType:DWORD;Changed:TChanged);
  end;

  TChanged = class(TComponent)
  private
    fEnabled : boolean;
    fSubDirs : boolean;
    fPath : string;
    fChangeType : TChangeType;
    fLocalChangeType : DWORD;
    fWaitThread : TWaitThread;
    szPath : array[0..255] of char;
    fOnChanged : TNotifyEvent;
    procedure UpdateThread;
  protected
    procedure SetEnabled(value:boolean);
    procedure SetSubDirs(value:boolean);
    procedure SetPath(value:string);
    procedure SetChangeType(value:TChangeType);
    procedure DoChanged;
  public
    Constructor Create(AOwner:TComponent);override;
    Destructor Destroy;override;
  published
    Property Enabled:boolean read fEnabled write SetEnabled;
    Property SubDirs:boolean read fSubDirs write SetSubDirs;
    Property OnChanged:TNotifyEvent read fOnChanged write fOnChanged;
    Property ChangeType:TChangeType read fChangeType write SetChangeType;
    Property Path:string read fPath write SetPath;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Planetech', [TChanged]);
end;

Constructor TWaitThread.Create(NotifyType:DWORD;Changed:TChanged);
begin
  inherited Create(False);
  fNotifyType := NotifyType;
  fChanged := Changed;
end;

procedure TWaitThread.Execute;
begin
  while not Terminated do with (fChanged as TChanged) do
    begin
      EventArray[0] := CreateEvent(Nil,    // no security attributes
                                   TRUE,    // manual reset event
                                   FALSE,   // not-signalled
                                   Nil);   // no name
      EventArray[1] := FindFirstChangeNotification(szPath,
                                                   fSubDirs,
                                                   fNotifyType);
      WaitForMultipleObjects(2, @EventArray, FALSE, INFINITE);
      synchronize(doChanged);

      FindCloseChangeNotification(EventArray[1]);
      CloseHandle(EventArray[0]);
    end;
end;
//----------------------------------------------------------------------------

Constructor TChanged.Create(AOwner:TComponent);
var
  t:integer;
begin
  inherited Create(AOwner);
end;

Destructor TChanged.Destroy;
begin
  inherited Destroy;
end;

procedure TChanged.SetEnabled(value:boolean);
begin
  if value = fEnabled then exit;
  fEnabled := value;
  UpdateThread;
end;

procedure TChanged.SetSubDirs(value:boolean);
begin
  if value = fSubDirs then exit;
  fSubDirs := value;
  UpdateThread;
end;

procedure TChanged.SetPath(value:string);
begin
  if value = fPath then exit;
  fPath := value;
  StrPCopy(szPath, fPath);
  UpdateThread;
end;

procedure TChanged.SetChangeType(value:TChangeType);
begin
  if fChangeType = value then exit;
  fLocalChangeType := 0;
  if ntFileName in value then fLocalChangeType := fLocalChangeType or FILE_NOTIFY_CHANGE_FILE_NAME;
  if ntDirName in value then fLocalChangeType := fLocalChangeType or FILE_NOTIFY_CHANGE_DIR_NAME;
  if ntAttributes in value then fLocalChangeType := fLocalChangeType or FILE_NOTIFY_CHANGE_ATTRIBUTES;
  if ntSize in value then fLocalChangeType := fLocalChangeType or FILE_NOTIFY_CHANGE_SIZE;
  if ntLastWrite in value then fLocalChangeType := fLocalChangeType or FILE_NOTIFY_CHANGE_LAST_WRITE;
  if ntSecurity in value then fLocalChangeType := fLocalChangeType or FILE_NOTIFY_CHANGE_SECURITY;
  fChangeType := value;
end;

procedure TChanged.UpdateThread;
begin
  if (not (csDesigning in ComponentState) and (fPath = '')) then
      Raise EChangeError.create('Path cannot be Null');
  if (not (csDesigning in ComponentState) and (fLocalChangeType = 0)) then
      Raise EChangeError.create('Must Specify ChangeType');
  if fWaitThread <> nil then
     begin
       fWaitThread.Terminate;
       PulseEvent(fWaitThread.EventArray[0]);
       WaitForSingleObject(fWaitThread.handle, INFINITE);
       CloseHandle(fWaitThread.handle);
       fWaitThread := nil;
     end;
  if fEnabled then
    fWaitThread := TWaitThread.create(fLocalChangeType,self);
end;

procedure TChanged.DoChanged;
begin
  if assigned (fOnChanged) then fOnChanged(Self);
end;

end.
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Email security requires an ever evolving service that stays up to date with counter-evolving threats. The Email Laundry perform Research and Development to ensure their email security service evolves faster than cyber criminals. We apply our Threat…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question