7

Windowsでは、フォルダに変更されたサブファイルがあるかどうかを確認する簡単な方法はありますか?

確認しましたが、サブファイルが変更されてもフォルダーの最終更新日が更新されません。

この動作を変更するように設定できるレジストリエントリはありますか?

重要な場合は、NTFSボリュームを使用しています。

最終的には、C++プログラムからこの機能を利用したいと思います。

フォルダが大きすぎるため、ディレクトリ全体を再帰的にスキャンしても機能しません。

更新:変更が発生している間、プロセスを実行せずにこれを行う方法が本当に必要です。したがって、ファイルシステムウォッチャーのインストールは私には最適ではありません。

Update2:アーカイブビットも最終変更日と同じ問題があるため、機能しません。ファイルのアーカイブビットは設定されますが、フォルダは設定されません。

4

8 に答える 8

6

この記事 は役に立ちます。基本的に、次のような 1 つ以上の通知オブジェクトを作成します。

ハンドル dwChangeHandles[2];
dwChangeHandles[0] = FindFirstChangeNotification(
      lpDir, // 監視するディレクトリ
      FALSE, // サブツリーを監視しない
      FILE_NOTIFY_CHANGE_FILE_NAME); // ファイル名の変更を監視する

   if (dwChangeHandles[0] == INVALID_HANDLE_VALUE)
   {
     printf("\n エラー: FindFirstChangeNotification 関数が失敗しました。\n");
     ExitProcess(GetLastError());
   }

// サブツリーでディレクトリの作成と削除を監視します。  
   dwChangeHandles[1] = FindFirstChangeNotification(
      lpDrive, // 監視するディレクトリ
      TRUE, // サブツリーを監視する
      FILE_NOTIFY_CHANGE_DIR_NAME); // ディレクトリ名の変更を監視

   if (dwChangeHandles[1] == INVALID_HANDLE_VALUE)
   {
     printf("\n エラー: FindFirstChangeNotification 関数が失敗しました。\n");
     ExitProcess(GetLastError());
   }

次に、通知を待ちます。

ながら (TRUE)
   {
   // 通知を待ちます。
      printf("\n通知を待っています...\n");

      DWORD dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,
         FALSE、無限);

      スイッチ (dwWaitStatus)
      {
         ケース WAIT_OBJECT_0:

         // ディレクトリ内でファイルが作成、名前変更、または削除されました。
         // 通知を再開します。
             if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE )
             {
               printf("\n エラー: FindNextChangeNotification 関数が失敗しました。\n");
               ExitProcess(GetLastError());
             }
             壊す;

         ケース WAIT_OBJECT_0 + 1:

         // 通知を再開します。
             if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE )
             {
               printf("\n エラー: FindNextChangeNotification 関数が失敗しました。\n");
               ExitProcess(GetLastError());
             }
             壊す;

         ケース WAIT_TIMEOUT:

         // タイムアウトが発生しました。これは、他の値の場合に発生します
         // Wait 呼び出しで INFINITE が使用され、変更は発生しません。
         // シングルスレッド環境では、
         // 無限待機。

            printf("\nタイムアウト期間に変更はありません。\n");
            壊す;

         デフォルト:
            printf("\n エラー: 未処理の dwWaitStatus.\n");
            ExitProcess(GetLastError());
            壊す;
      }
   }
}
于 2008-09-11T14:54:57.993 に答える
3

これはおそらくやり過ぎですが、MSのIFS キットまたは OSR のFDDKが代替手段になる可能性があります。ファイルシステムへのすべての変更を簡単に監視して、独自のファイルシステム フィルター ドライバーを作成します。

于 2008-12-02T20:11:42.213 に答える
2

ReadDirectoryChangesW

この CodeProject 記事のいくつかの優れたサンプル コード

于 2008-10-03T20:45:39.313 に答える
1

おそらく、こちらで説明されているように、DeviceIoControl で NTFS 5 変更ジャーナルを使用できます。

于 2008-09-11T16:17:26.140 に答える
1

変更が発生したときにプロセスを実行できない場合は、ファイルシステムをスキャンして変更日時を確認する以外にできることはあまりありません。ただし、これには、各ファイルの最後の日付/時刻を保存して比較する必要があります。

アーカイブ ビットを使用すると、これを高速化できます(ただし、バックアップ ソフトウェアが台無しになる可能性があるため、慎重に進めてください)。

アーカイブ ビットは、多くのコンピュータ ファイル システム、特に FAT、FAT32、および NTFS に存在するファイル属性です。アーカイブ ビットの目的は、アーカイブとも呼ばれるバックアップの目的で、ファイルへの増分変更を追跡することです。

アーカイブ ビットはバイナリ ビットであるため、1 または 0 のいずれかになります。この場合、より頻繁にセット (1) およびクリア (0) と呼ばれます。オペレーティング システムは、ファイルが作成、移動、名前変更、または何らかの方法で変更されるたびに、アーカイブ ビットを設定します。したがって、アーカイブ ビットは、最後のバックアップ以降の「変更済み」と「未変更」の 2 つの状態のいずれかを表します。

アーカイブ ビットは、ファイルを読み取るだけでは影響を受けません。ファイルがコピーされるとき、元のファイルのアーカイブ ビットは影響を受けませんが、コピーのアーカイブ ビットはコピーが作成された時点で設定されます。

したがって、プロセスは次のようになります。

  1. すべてのファイルのアーカイブ ビットをクリアする
  2. 時間の経過とともにファイル システムを変更する
  3. すべてのファイルをスキャンします - アーカイブ ビットが設定されているすべてのファイルが変更されました

これにより、プログラムが状態を保持する必要がなくなります。また、ディレクトリ エントリ (ビットが格納されている場所) のみを参照し、それらがクラスター化されているため、非常に高速になるはずです。

ただし、変更中にプロセスを実行できる場合は、FileSystemWatcherクラスを確認する必要があります。これをどのように使用するかの例を次に示します。

.NETにも存在します(この種の問題を将来検索する人向け)

おそらく、変更を監視し、後で読むためのファイルを作成するプロセスをマシン上で実行したままにすることができます。

-アダム

于 2008-09-11T14:35:05.403 に答える
0

誰かが言及した二重の投稿から: WMI Event Sink

それでもより良い答えを探しています。

于 2008-09-11T14:51:43.773 に答える
0

.NET の使用に抵抗がない場合は、FileSystemWatcherクラスがこれをかなり簡単に処理します。

于 2008-09-11T14:36:28.240 に答える
0

簡単なことではありません-実行中のアプリがある場合は、他の回答で提案されているように、Win32 ファイル変更通知 API (FindFirstChangeNotification) を使用できます。警告: 2000 年頃のトレンド マイクロ リアルタイム ウイルス スキャナでは、変更がグループ化され、ファイル システムの変更リストを要求するときに非常に大きなバッファを使用する必要がありました。

実行中のアプリがない場合は、ntfs ジャーナリングをオンにして、ジャーナルの変更をスキャンできますhttp://msdn.microsoft.com/en-us/library/aa363798(VS.85).aspxですが、これは変更の数がファイルの数より大きい場合、ディレクトリ全体をスキャンするよりも遅くなります。

于 2008-09-11T14:39:32.977 に答える