Windows文件變更監控

有的時候需要在新建、修改和刪除文件時執行一些操作,這就需要監控文件的變更。http://zhanyonhu.blog.163.com/blog/static/16186044200882484143208/提出了3種方法來實現:

1. 函數FindFirstChangeNotification和FindNextChangeNotification

2. 系統核心工具軟件,比如FileMon(文件監視),開放源代碼

3. Hook API,鉤住CreateFile函數,分析其參數,藉此來判斷是創建文件還是讀寫文件;鉤住DeleteFile函數,監視文件刪除操作;鉤住CreateDirectory和RemoveDirectory,藉此判斷是否是刪除文件;鉤住回收站相關函數,藉此判斷是否是移動到回收站。

後面兩種方法一個使用驅動相關的技術,一個使用Hook,都比較複雜。通過Windows提供的API已經可以滿足一些基本的文件監控需求。下面主要看下2個函數:

FindFirstChangeNotification Function

Creates a change notification handle and sets up initial change notification filter conditions. A wait on a notification handle succeeds when a change matching the filter conditions occurs in the specified directory or subtree. The function does not report changes to the specified directory itself.

This function does not indicate the change that satisfied the wait condition. To retrieve information about the specific change as part of the notification, use the ReadDirectoryChangesW function.

HANDLE WINAPI FindFirstChangeNotification(
  __in          LPCTSTR lpPathName,
  __in          BOOL bWatchSubtree,
  __in          DWORD dwNotifyFilter
);

Parameters
lpPathName 
The path of the directory to be watched. 

In the ANSI version of this function, the name is limited to MAX_PATH characters. To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. For more information, see Naming a File.

bWatchSubtree 
If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory; if it is FALSE, it monitors only the specified directory.

dwNotifyFilter 
The filter conditions that satisfy a change notification wait. This parameter can be one or more of the following values.

 

http://www.codeproject.com/KB/files/DirCheck.aspx提供了一個用FindFirstChangeNotification實現的封裝類。

ReadDirectoryChangesW Function

Retrieves information that describes the changes within the specified directory. The function does not report changes to the specified directory itself.


To track changes on a volume, see change journals.


Syntax

BOOL WINAPI ReadDirectoryChangesW(
  __in         HANDLE hDirectory,
  __out        LPVOID lpBuffer,
  __in         DWORD nBufferLength,
  __in         BOOL bWatchSubtree,
  __in         DWORD dwNotifyFilter,
  __out_opt    LPDWORD lpBytesReturned,
  __inout_opt  LPOVERLAPPED lpOverlapped,
  __in_opt     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
Parameters

hDirectory [in]
A handle to the directory to be monitored. This directory must be opened with the FILE_LIST_DIRECTORY access right.

lpBuffer [out]
A pointer to the DWORD-aligned formatted buffer in which the read results are to be returned. The structure of this buffer is defined by the FILE_NOTIFY_INFORMATION structure. This buffer is filled either synchronously or asynchronously, depending on how the directory is opened and what value is given to the lpOverlapped parameter. For more information, see the Remarks section.

nBufferLength [in]
The size of the buffer that is pointed to by the lpBuffer parameter, in bytes.

bWatchSubtree [in]
If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory. If this parameter is FALSE, the function monitors only the directory specified by the hDirectory parameter.

dwNotifyFilter [in]
The filter criteria that the function checks to determine if the wait operation has completed. This parameter can be one or more of the following values.

lpBytesReturned [out, optional]
For synchronous calls, this parameter receives the number of bytes transferred into the lpBuffer parameter. For asynchronous calls, this parameter is undefined. You must use an asynchronous notification technique to retrieve the number of bytes transferred.

lpOverlapped [in, out, optional]
A pointer to an OVERLAPPED structure that supplies data to be used during asynchronous operation. Otherwise, this value is NULL. The Offset and OffsetHigh members of this structure are not used.

lpCompletionRoutine [in, optional]
A pointer to a completion routine to be called when the operation has been completed or canceled and the calling thread is in an alertable wait state. For more information about this completion routine, see FileIOCompletionRoutine.

http://www.codeproject.com/KB/files/directorychangewatcher.aspx提供了一個用ReadDirectoryChangesW實現的封裝類。

http://www.codeproject.com/KB/files/FileSpyArticle.aspx給出了FindFirstChangeNotification和ReadDirectoryChangesW的一些詳細介紹和示例。可以參考一下。

 

其他相關的解決方案:

FileSystemWatcher偵聽文件系統更改通知,並在目錄或目錄中的文件發生更改時引發事件。可監視指定目錄中的文件或子目錄的更改。可以創建一個組件來監視本地計算機、網絡驅動器或遠程計算機上的文件。

下面的示例創建一個 FileSystemWatcher,以便在運行時監視指定的目錄。組件設置爲監視 LastWrite 和 LastAccess 時間方面的更改,以及目錄中文本文件的創建、刪除或重命名。如果更改、創建或刪除文件,文件路徑將被輸出到控制檯。在文件重命名後,舊路徑和新路徑都輸出到控制檯。在此示例中使用 System.Diagnostics 和 System.IO 命名空間。

public ref class Watcher
{
private:
   // Define the event handlers.
   static void OnChanged( Object^ /*source*/, FileSystemEventArgs^ e )
   {
      // Specify what is done when a file is changed, created, or deleted.
      Console::WriteLine( "File: {0} {1}", e->FullPath, e->ChangeType );
   }

   static void OnRenamed( Object^ /*source*/, RenamedEventArgs^ e )
   {
      // Specify what is done when a file is renamed.
      Console::WriteLine( "File: {0} renamed to {1}", e->OldFullPath, e->FullPath );
   }

public:
   [PermissionSet(SecurityAction::Demand, Name="FullTrust")]
   int static run()
   {
      array<String^>^args = System::Environment::GetCommandLineArgs();

      // If a directory is not specified, exit program.
      if ( args->Length != 2 )
      {
         // Display the proper way to call the program.
         Console::WriteLine( "Usage: Watcher.exe (directory)" );
         return 0;
      }

      // Create a new FileSystemWatcher and set its properties.
      FileSystemWatcher^ watcher = gcnew FileSystemWatcher;
      watcher->Path = args[ 1 ];

      /* Watch for changes in LastAccess and LastWrite times, and 
          the renaming of files or directories. */
      watcher->NotifyFilter = static_cast<NotifyFilters>(NotifyFilters::LastAccess |
            NotifyFilters::LastWrite | NotifyFilters::FileName | NotifyFilters::DirectoryName);

      // Only watch text files.
      watcher->Filter = "*.txt";

      // Add event handlers.
      watcher->Changed += gcnew FileSystemEventHandler( Watcher::OnChanged );
      watcher->Created += gcnew FileSystemEventHandler( Watcher::OnChanged );
      watcher->Deleted += gcnew FileSystemEventHandler( Watcher::OnChanged );
      watcher->Renamed += gcnew RenamedEventHandler( Watcher::OnRenamed );

      // Begin watching.
      watcher->EnableRaisingEvents = true;

      // Wait for the user to quit the program.
      Console::WriteLine( "Press \'q\' to quit the sample." );
      while ( Console::Read() != 'q' )
         ;
   }
};

int main() {
   Watcher::run();
}


FileSyncProvider是同步的同步提供程序,它可用於同步 NTFS、FAT 或 SMB 文件系統中的文件、文件夾和子文件夾。詳細參見MSDNhttp://msdn.microsoft.com/zh-cn/library/microsoft.synchronization.files.filesyncprovider(v=SQL.100).aspx



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章