2013-02-08 20 views
6

私は拾い読みしていますが、私が捜していることに関する情報を見つけることができません。FileSystemWatcherがフォルダ/ファイルを開くのを監視するのに使用されました

特定のフォルダーを監視し、そのフォルダーが他のユーザーによって開かれたとき、またはそのフォルダーの下にあるファイルが開かれたときのためのヘルプを探しています。この時点で、ユーザーがファイルを開いて変更したときを見ることができますが、ファイルを開いて表示するだけでLastAccessを追加してもイベントはスローされません。どんな情報や助けにも感謝します。 C#4.0で\ジャンク

コード:

フォルダ名はCです

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 
    public static void Run() 
    { 


     FileSystemWatcher watcher = new FileSystemWatcher(); 
     watcher.Path = @"C:\"; 
     watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite 
      | NotifyFilters.FileName | NotifyFilters.DirectoryName; 
     watcher.Filter = "junk"; 

     // Add event handlers. 
     watcher.Changed += new FileSystemEventHandler(OnChanged); 
     watcher.Created += new FileSystemEventHandler(OnChanged); 
     watcher.Deleted += new FileSystemEventHandler(OnChanged); 
     watcher.Renamed += new RenamedEventHandler(OnRenamed); 
     watcher.IncludeSubdirectories = true; 
     watcher.EnableRaisingEvents = true; 

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

    // Define the event handlers. 
    private static void OnChanged(object source, FileSystemEventArgs e) 
    { 
     // Specify what is done when a file is changed, created, or deleted. 
     Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); 
    } 

    private 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); 
    } 
+0

フォルダ名がC:\ JUNKの場合は、Pathプロパティに入れてください。 – Steve

+0

@Steve - あなたの提案によれば、私は自分のコードを変更しましたが、それでもフォルダを開いてもトリガしません。 – Saren

+1

この種の変更を追跡するには、ファイルシステムフィルタドライバを試してください。他の亜種はうまくいきません。 –

答えて

0

あなたは

watcher.Path = @"C:\junk"; 

設定し、イベントはすべてのファイルに対して発射する必要がある場合watcher.Filter行を削除する必要があります

Filterプロパティを使用すると、matchiにワイルドカードを設定できますたとえば、*.txt

+0

私はコードを変更しましたが、まだ開いている場合はトリガーがありません。 – Saren

2

LastAccessedを追加してもイベントはスローされません。

NotifyFilters.LastAccessedは、購読するイベントではなく、そのプロパティを取得することを指定しているためです。使用可能なイベントはChanged,Created、またはDeletedです。いずれも必要なものはありません。

ReadDirectoryChangesW Win32関数(hereを参照)をご覧ください。それはあなたが望むものを提供しているようだFILE_NOTIFY_CHANGE_LAST_ACCESSフラグを渡すことができます。

監視しているディレクトリまたはサブツリー内のファイルの最終アクセス時間への変更は、変更通知の待機操作を返すようになります。

編集:FileSystemWatcherReadDirectoryChangesWに、FILE_NOTIFY_CHANGE_LAST_ACCESSと同じである、32 intとしてNotifyFilters.LastWriteを内部的に通過しない、これは無視してください。その関数はまだファイルへのアクセスを通知しない、私は試した。

おそらく、これはthisによって引き起こされる:

最終アクセス日時は時間が1時間以内の精度であることを保証緩い精度を持っています。 Windows Vistaでは、Last Access Timeの更新を無効にしてNTFSのパフォーマンスを向上させました。あなたは、この値に依存しているアプリケーションを使用している場合は、次のコマンドを使用して、それを有効にすることができます。

fsutil behavior set disablelastaccess 0 

をこの変更を有効にするために、コンピュータを再起動する必要があります。

コマンドプロンプトで実行すると、おそらくLastAccessが書き込まれ、イベントが発生します。私は自分のSSDで試してみるつもりはないし、VMを準備していないが、Windows 7ではdisablelastaccessがすぐに使用可能になっているようだ。

この動作を無効にしてもまだ動作しない場合は、Raymond Chenの提案ボックスが来るのを待ってください。通常、ドキュメントが正しく動作していないように見える理由出会い。 ;-)

また、ループ内のディレクトリをスキャンして、ファイルのLastAccessedプロパティを調べることもできます。あなたが何をしようとしていますユーザーが特定のファイルを開くとき?

+0

ありがとうございました! – Saren

+0

最初にそれを実装しよう...;) – CodeCaster

+0

これはPITAと思われますが、それは別の時間です。今のところ、私は取るべきルートがあります。 – Saren

0

実際に必要なのはNtQuerySystemInformation列挙型とタイマーです。ディレクトリをスキャンしてファイルが開いているかどうかを確認できます。ファイルシステムウォッチャーはあなたにこの情報を与えません。

0
public void OnChanged(object sender, FileSystemEventArgs e) 
{ 
    string FileName = System.IO.Path.GetFileName(e.FullPath); 

    if(IsAvailable(System.IO.Path.Combine(RecievedPath,FileName))) 
    { 
     ProcessMessage(FileName); 
    } 
} 


private void ProcessMessage(string fileName) 
{ 
    try 
    { 
     File.Copy(System.IO.Path.Combine(RecievedPath,fileName), System.IO.Path.Combine(SentPath,fileName)); 
     MessageBox.Show("File Copied"); 
    } 
    catch (Exception) 
    { } 
} 

private static bool IsAvailable(String filePath) 
{ 
    try 
    { 
     using (FileStream inputStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None)) 
     { 
      if (inputStream.Length > 0) 
      { 
       return true; 
      } 
      else 
      { 
       return false; 
      } 

     } 
    } 
    catch (Exception) 
    { 
     return false; 
    } 
} 
0

オンアクセスファイルパスを取得するには、ミニフィルタードライバーの1つの解決策があります。要件を実装するには、ミニフィルタドライバを実装する必要があります。

関連する問題