9

ReadDirectoryChangesW() を使用して Windows のディレクトリの下の変更を監視する C コードを開発しています。ReadDirectoryChangesW() と FILE_NOTIFY_INFORMATION 構造に関連する MSDN エントリ、および他のいくつかのドキュメントを読みました。この時点で、監視自体に明らかな問題はなく、複数のディレクトリを監視できました。問題は、この関数によって FILE_NOTIFY_INFORMATION 構造体に入れられるファイル名が正規のものではないことです。

MSDN によると、それらは長い形式でも短い形式でもかまいません。このケースを処理するために短いパス名と長いパス名の両方をキャッシュすることを提案する投稿をいくつか見つけました。残念ながら、Windows 7 システムでの私自身のテストによると、これは問題を解決するのに十分ではありません。これは、各ファイル名に 2 つの代替手段しかないためです。問題は、パス名で EACH COMPONENT が長い形式または短い形式のいずれかである可能性があることです。次のパス名はすべて同じファイルを参照できます。

c:\PROGRA~1\MYPROG~1\MYDATA~1.TXT

c:\PROGRA~1\MYPROG~1\MyDataFile.txt

c:\PROGRA~1\MyProgram\MYDATA~1.TXT

c:\PROGRA~1\MyProgram\MyDataFile.txt

c:\Program Files\MYPROG~1\MYDATA~1.TXT

...

cmd.exe を使用したテストからわかる限り、それらはすべて完全に受け入れられます。基本的に、各ファイルの有効なパス名の数は、パス名の構成要素の数に応じて指数関数的に増加します。

残念ながら、ReadDirectoryChangesW() は、各操作を引き起こすシステム コールに提供されたファイル名で出力バッファを埋めているようです。たとえば、cmd.exe コマンドを使用してファイルの作成、名前変更、削除などを行う場合、FILE_NOTIFY_INFORMATION にはコマンド ラインで指定されたファイル名が含まれます。

これで、ほとんどの場合、GetLongPathName() とその仲間を使用して、使用する一意のパスを取得できました。残念ながら、ファイルを削除するときにはそれを行うことはできません。通知を受け取るまでに、ファイルはすでに削除されており、Get*PathName() 関数は機能しません。

現時点では、より広範なキャッシュを使用して、アプリケーションが各ファイルに使用する代替パス名を決定することを考えています。 . そして、親ディレクトリの変更イベントからの創造的なデータ マイニングと、その場合の実際のディレクトリのチェックにフォールバックすることを考えています。

これを行うためのより簡単な方法について何か提案はありますか?

PS1: Change Journal はこれを効果的に処理しますが (願わくば)、NTFS との関係とアプリケーションの管理者権限がないため、使用できるとは思いません。絶対にやむを得ない場合を除いて、私はむしろそこに行きたくありません。

PS2: 主に Unix でコーディングしていることを覚えておいてください。

4

1 に答える 1

2

すべての組み合わせをキャッシュする必要はありません。各サブパスをキャッシュして、長い形式に変換できるようにするとうまくいきます。たとえば、これを保存します。

  • C:\PROGRA~1 => c:\Program Files
  • c:\Program Files\MYPROG~1 => c:\Program Files\MyProgram
  • c:\Program Files\MyProgram\MYDATA~1.TXT => c:\Program Files\MyProgram\MyDataFile.txt
  • c:\Program Files\MyProgram\MYDATA~2.TXT => c:\Program Files\MyProgram\MyDataFile2.txt

の通知を受け取った場合はc:\PROGRA~1\MYPROG~1\MYDATA~1.TXT、それを ごとに分割し、\各部分を検索して長い形式にします。

MyDataFile.txtそれを忘れずMYDATAFILE.TXTに、同じファイルを指してください。したがって、大文字と小文字を区別せずに比較するか、すべてを大文字に変換してください。

c:\PROGRA~1\MYPROG~1\MYDATA~1.TXTが削除された場合でも、onGetLongPathName()を引き続き使用できますc:\PROGRA~1\MYPROG~1

于 2010-11-14T21:26:33.020 に答える