7

私はブラウジングしましたが、私が探しているものに関する情報を見つけることができません.これをすでに超えている別の投稿がある場合は、お詫び申し上げます.

特定のフォルダーが別の人によって開かれたとき、またはそのフォルダーの下のファイルが開かれたときに、特定のフォルダーを監視するコードについて助けを求めています。この時点で、ユーザーがファイルを開いて変更したことを確認できますが、ファイルを開いて表示しただけでは、LastAccessed を追加してもイベントはスローされません。情報やヘルプをいただければ幸いです。

フォルダ名は C:\Junk

C# 4.0 のコード:

    [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);
    }
4

6 に答える 6

2

LastAccessed を追加してもイベントは発生しません。

NotifyFilters.LastAccessedサブスクライブするイベントではなく、そのプロパティを取得することを指定するためです。利用可能なイベントはChangedCreated、またはDeletedであり、いずれも希望どおりにはなりません。

ここReadDirectoryChangesWに文書化されている Win32 関数を確認する必要があります。必要なものを提供するように見えるフラグを渡すことができます。FILE_NOTIFY_CHANGE_LAST_ACCESS

監視対象のディレクトリまたはサブツリー内のファイルの最終アクセス時刻が変更されると、変更通知の待機操作が返されます。

編集: これを無視してください。FileSystemWatcherは内部的NotifyFilters.LastWriteに int 32 として渡されます。これは、 と同じFILE_NOTIFY_CHANGE_LAST_ACCESSですReadDirectoryChangesW。その機能はまだファイルアクセスを通知しません、私は試しました。

おそらくこれはこれが原因です

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

fsutil behavior set disablelastaccess 0

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

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

その動作を無効にしてもまだ機能しない場合は、Raymond Chen の提案ボックス (または彼自身) が来るのを待ちます。通常、発生した動作をドキュメントが正しく説明していないように見える理由について、非常に論理的な説明があります。;-)

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

于 2013-02-08T19:13:28.393 に答える
0

設定する必要があります

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

watcher.Filterすべてのファイルに対してイベントが発生する場合は、行を削除します

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

于 2013-02-08T19:13:15.347 に答える
0

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

于 2013-02-08T19:50:30.423 に答える
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;
    }
}
于 2016-10-14T09:01:50.913 に答える
0

Digvijay Rathore はすでに答えを出しています。私の意見では、少し短すぎるとはいえ、唯一の良い答えです。

いくつかの単語と、関心のあるユーザーが開始できるリンクを追加したいと思います。

FileSystemWatcher は、監視対象のフォルダー内で何が起こっているかを監視するだけで役立ちますが、ユーザー (または OS) が何をしているかを監視および傍受することはできません。

たとえば、FSW (FileSystemWatcher) を使用すると、ファイル/フォルダーが何らかの方法で作成、削除、名前変更、または変更されたときを監視できます。これらのイベントは、アクションが完了する前でも途中でもなく、アクションが完了した後に解き放たれます。

単純な FSW は、ユーザーが監視対象のフォルダーから実行可能ファイルを起動しているかどうかを認識できません。この場合、イベントはまったく生成されません。

実行可能ファイルがいつ起動されるか (および他の多くの「イベント」) を起動前にキャッチし、実行可能ファイルのコードがメモリにロードされる前に何らかのアクションを実行するには、下位 (カーネル) レベルで何かを記述する必要があります。つまり、ドライバーをビルドする必要があります。この特定のケースでは、(ミニフィルター) ファイル システム ドライバーです。

これは、Minifilter Windows ドライバーの基本を理解するための出発点として適しています。

https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/file-system-minifilter-drivers

于 2019-03-24T12:23:43.547 に答える