要求  
   監控指定目錄的所有文件的改變!  
   包括改變文件名,文件內容.    
   要知道是哪個文件改變了.請高手指點!

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject);
    var
      Dir:PChar;
      re:DWORD;
      ProHandle:THandle;
    begin
      re:=1;
      Dir:='D:\';  //FindFirstChangeNotification函数创建一个进程,监视目录的变化
      ProHandle:=FindFirstChangeNotification(Dir,false,
        FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_SIZE);
      //创建不成功
      if ProHandle=INVALID_HANDLE_VALUE then
      begin
        beep;
        ShowMessage(SysErrorMessage(GetLastError));
        exit;
      end;  //如目录确实发生变化,退出
      while re<>0 do
      begin
        //监视前面进程执行情况,re=0表示前面的进程退出,即目录有变化
        re:=WaitForSingleObject(ProHandle,100);
        Application.ProcessMessages();
      end;
      ShowMessage('当前目录发生改变');  //循环监视目录的变化情况
      while true do
      begin
        re:=1;
        //重新执行前面定义的进程
        FindNextChangeNotification(ProHandle);
        while re<>0 do
        begin
          re:=WaitForSingleObject(ProHandle,100);
          Application.ProcessMessages();
        end;
        ShowMessage('当前目录发生改变');
      end;
    end;
      

  2.   

    到msdn上去查一下 FINDFIRSTNOTIFICATION 及 findnextnotification这两个api
    然后
      

  3.   

    lihao_ningxia(耗子)
      用钩子,当消息是这一类消息就处理呗>>多謝你的關注,不過你所說的等于白說!而且我想用hook可能還不行!
     如,監控Movefile之類的東西可能不能解決問題!DWGZ() 
    我需要的是監控文件,而不是目錄,你所說功能用Delphi的
    TShellChangeNotifier控件就能實現了!
      

  4.   

    实时侦测目录中文件变化?    
      在WIN32下用DELPHI侦测目录变化,可用WIN32提供的文件改变通知API来完成。FindFirstChangeNotification, FindNextChangeNotification,FindCloseChangeNotification。 
    在应用程序中调用这些函数时,产生一个监控这个变化的句柄,可用WAIT函数集来等待这个变化。这样,当监控程序运行时,可以达到监控文件变化的动作。更进一步,可把此程序做成一个状态区图标(TRAY)来完成监控。Windows在删除、复制、移动、访问文件时并不发送消息,当然截获不到。要截取这些操作过程的唯一办法就是截获API,这又需要你编写Vxd程序了,杀毒软件都是这样作的。你注意一下杀毒软件一般都带有一个vxd程序。光有vxd还不行,还需截获文件API。还有另外一个办法,就是CIH病毒采用的办法,直接跳到系统零层去操作。具体办法如下:一、SIDT指令( 将中断描述符表寄存器IDTR--64位宽,16~47Bit存有中断描述符表IDT基地址--的内容存入指定地址单元)不是特权指令,就是说我们可以在Ring3下执行该指令,获得IDT的基地址,从而修改IDT,增加一个中断门安置我们的中断服务,一旦Ring3程序中产生此中断,VMM就会调用此中断服务程序,而此中断服务程序就运行在Ring0下了。这一点与在DOS下非常相似。二、要实现对系统中所有文件I/O操作的实时监视,还要用到另一种关键技-FileHooking,通过挂接一个处理函数,截获所有与文件I/O操作有关的系 统调用。Windows9x使用32位保护模式可安装文件系统(IFS),由可安装文件系统管理器(IFSManager)协调对文件系统和设备的访问,它接收以Win32API函数调用形式向系统发出的文件I/O请求,再将请求转给文件系统驱动程序FSD,由它调用低级别的IOS系统实现最终访问。每个文件I/OAPI调用都有一个特定的FSD函数与之对应,IFSManager负责完成由API到FSD的参数装配工作,在完成文件I/OAPI函数参数的装配之后转相应FSD执行之前,它会调用一个称为FileSystemApiHookFunction的Hooker函数。通过安装自己的Hooker函数,就可以截获系统内所有对文件I/O的API调用,从而实现实时监控。=========================================procedure TForm1.Button2Click(Sender: TObject);begin{establish a notification for file name changes on the selected directory}NotificationHandle := FindFirstChangeNotification(PChar(DirectoryListBox1.Directory), FALSE,FILE_NOTIFY_CHANGE_FILE_NAME);{if the notification was set up correctly, modify some UI elements...}if (NotificationHandle <> INVALID_HANDLE_VALUE) thenbeginButton1.Enabled := TRUE;Button2.Enabled := FALSE;endelsebegin{...otherwise indicate that there was an error}ShowMessage('There was an error setting the notification');Exit;end;end;procedure TForm1.Button1Click(Sender: TObject);vardwResult: DWORD; // holds the result of waiting on the notificationWaiting: Boolean; // loop control variablebegin{setup the loop control for a continuous loop}Waiting := TRUE;{indicate that the application is waiting for the change notification to fire}Button1.Enabled := FALSE;StatusBar1.SimpleText := 'Now waiting for a filename change';Application.ProcessMessages;{enter the loop}while Waiting dobegin{at this point, the application is suspended until the notificationobject is signaled that a filename change has occured in theselected directory (this includes file deletions)}dwResult := WaitForSingleObject(NotificationHandle,INFINITE);if (dwResult = WAIT_OBJECT_0) thenbegin{indicate that the notification object was signaled}ShowMessage('The selected directory signaled a filename change');{query the user to see if they wish to continue monitoring thisdirectory}if Application.MessageBox('Do you wish to continue monitoring this directory?', 'Continue?', MB_ICONQUESTION orMB_YESNO) = IDYES then{if the user wishes to continue monitoring the directory, resetthe notification object and continue the loop...}FindNextChangeNotification(NotificationHandle)else{...otherwise break out of the loop}Waiting := FALSE;end;end;{close the notification object}FindCloseChangeNotification(NotificationHandle);{reset UI elements}Button1.Enabled := FALSE;Button2.Enabled := TRUE;StatusBar1.SimpleText := '';FileListBox1.Update;end;===========================================下面是一个监视的控件:unit dirnotify;interfaceusesWindows, Messages, SysUtils, Classes,Graphics, Controls, Forms, Dialogs;typeEDirNotificationError = class(Exception);TDirNotify = class;TNotifyFilter = (nfFileName, nfDirName, nfAttributes, nfSize, nfLastWrite,nfSecurity);TNotifyFilters = set of TNotifyFilter;TNotificationThread = class(TThread)Owner: TDirNotify;procedure Execute; override;procedure DoChange;end;TDirNotify = class(TComponent)privateFEnabled: Boolean;FOnChange: TNotifyEvent;FNotificationThread: TNotificationThread;FPath: String;FWatchSubTree: Boolean;FFilter: TNotifyFilters;procedure SetEnabled( Value: Boolean );procedure SetOnChange( Value: TNotifyEvent );procedure SetPath( Value: String );procedure SetWatchSubTree( Value: Boolean );procedure SetFilter( Value: TNotifyFilters );procedure RecreateThread;protectedprocedure Change;procedure Loaded; override;publicconstructor Create(AOwner: TComponent); override;destructor Destroy; override;publishedproperty Enabled: Boolean read FEnabled write SetEnabled default True;property OnChange: TNotifyEvent read FOnChange write SetOnChange;property Path: String read FPath write SetPath;property WatchSubTree: Boolean read FWatchSubTree write SetWatchSubTree;property Filter: TNotifyFilters read FFilter write SetFilter default [nfFileName, nfDirName, nfAttributes, nfLastWrite, nfSecurity];end; procedure Register;implementationconstLASTERRORTEXTLENGTH = 500;
      

  5.   

    我曾用過
    FindFirstChangeNotification
    FindNextChangeNotification
    FindCloseChangeNotification
    這一組API,但它們只能感知到有所改變,但改變了什么,哪個文件改變了,用這組API不能解決問題!還有沒有高手知道怎么做呀! 
    在線等待......
      

  6.   

    varLastErrorText: array [0..LASTERRORTEXTLENGTH] of char; function GetLastErrorText: PChar;beginFormatMessage( FORMAT_MESSAGE_FROM_SYSTEM,nil, GetLastError, 0, LastErrorText, LASTERRORTEXTLENGTH, nil );Result := LastErrorText;end; procedure TNotificationThread.Execute;varh: THandle;nf: Longint;wst: LongBool;beginnf := 0;if (nfFileName in Owner.Filter) then nf := FILE_NOTIFY_CHANGE_FILE_NAME;if (nfDirName in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_DIR_NAME;if (nfAttributes in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_ATTRIBUTES;if (nfSize in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_SIZE;if (nfLastWrite in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_LAST_WRITE;if (nfSecurity in Owner.Filter) then nf := nf or FILE_NOTIFY_CHANGE_SECURITY;// yeahh, this one is stupid but Win98 malfunctions in any other value than 0 or 1if Owner.FWatchSubTree then wst := Longbool(1)else wst := Longbool(0);h := FindFirstChangeNotification( Pointer(Owner.Path), wst, nf );if (h = INVALID_HANDLE_VALUE) thenraise EDirNotificationError.Create( GetLastErrorText );repeatif (WaitForSingleObject( h, 1000 ) = WAIT_OBJECT_0) thenbeginSynchronize(DoChange);if not FindNextChangeNotification( h ) thenraise EDirNotificationError.Create( GetLastErrorText );end;until Terminated;end; procedure TNotificationThread.DoChange;beginOwner.Change;end; constructor TDirNotify.Create(AOwner: TComponent);begininherited Create(AOwner);FEnabled := True;FFilter := [nfFileName];end; destructor TDirNotify.Destroy;beginFNotificationThread.Free;inherited Destroy;end;procedure TDirNotify.Loaded;begininherited;RecreateThread;end; procedure TDirNotify.SetEnabled(Value: Boolean);beginif Value <> FEnabled thenbeginFEnabled := Value;RecreateThread;end;end; procedure TDirNotify.SetPath( Value: String );beginif Value <> FPath thenbeginFPath := Value;RecreateThread;end;end; procedure TDirNotify.SetWatchSubTree( Value: Boolean );beginif Value <> FWatchSubTree thenbeginFWatchSubTree := Value;RecreateThread;end;end; procedure TDirNotify.SetFilter( Value: TNotifyFilters );beginif Value <> FFilter thenbeginFFilter := Value;RecreateThread;end;end; procedure TDirNotify.SetOnChange(Value: TNotifyEvent);beginFOnChange := Value;end; procedure TDirNotify.Change;beginif Assigned(FOnChange) thenFOnChange(Self);end; procedure TDirNotify.RecreateThread;begin// destroy threadFNotificationThread.Free;FNotificationThread := nil;if FEnabled and not(csDesigning in ComponentState)and not(csLoading in ComponentState) and (FPath <> '') thenbegin// create threadFNotificationThread := TNotificationThread.Create(True);FNotificationThread.Owner := self;FNotificationThread.Resume;end;end; procedure Register;beginRegisterComponents('System', [TDirNotify]);end;end. 
     
      

  7.   

    Means_pan(酷鱼-Delphi的方向在哪里)>>你所Copy的代碼就是Delphi的TShellChangeNotifier控件再次強調,我所希望到的是哪個文件改變了!