[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

Detect File Changes in Dir

Posted on 2000-05-02
6
Medium Priority
?
188 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

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 200 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

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

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…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

656 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