Excel 2007 が互換モードで XLS ファイルを開くと、ただちに FileSystemWatcher.Changed が起動します。
-
18-09-2019 - |
質問
当社は FileSystemWatcher を使用して、当社の文書管理システムから開かれた文書を監視し、ユーザーが文書を保存する場合、その文書を当社のシステムでも更新するかどうかを尋ねます。
Excel 2007 の XLS ファイルには問題があり (問題が 2003 に存在しないことは確認されていませんが、2007 では互換モードで開くファイルのみのようです)、ファイルを開くとすぐに Changed イベントが発生します。何も変更されていないか、ユーザーが閉じるときに保存しないことを選択した場合でも、ファイルを閉じるときにもう一度実行されます。XLSX ファイルを開く場合、これと同じ動作は存在しません。
動作を検証するためのテスト アプリを作成しました。(http://www.just2guys.net/SOFiles/FSWExcel.zip)。アプリには、NotifyFilter タイプごとに 1 つの FileSystemWatcher があり、それが一目瞭然です。 なぜ Changed イベントが発生しました。
ユーザーが実際に何らかの方法でドキュメントを保存した場合にのみ、ユーザーにプロンプトを表示する方法はありますか?Process.Start が呼び出された後にファイルの監視を開始できるため、ドキュメントを開くときにメッセージをスキップできますが、何も変更されていない場合でも、ドキュメントを閉じるときにメッセージが表示されます。
解決
Word でこれに気づきましたが、簡単に再現できます。
Office アプリケーションで .doc または .xls ファイルを開くと、タイムスタンプはドキュメントを開いた時刻に変わります。
アプリケーションを閉じると、タイムスタンプは元の値にリセットされます (保存しなかった場合のみ)。
したがって、Office ファイルの場合は、さらに 2 つのチェックが必要です。
「開く」で、タイムスタンプが現在時刻に設定されている場合、ファイルが排他的に開けることを確認します。
閉じるときに、タイムスタンプが現在の日付と時刻に「近い」かどうかを確認するか、ファイルのアーカイブ フラグを確認します。
他のヒント
ファイルシステムウォッチャーは、通常は悪です。それは、ファイルが完全に書き込まれる前にイベントを登録するので、それは多くの人々を燃やします。
私たちは、どちらかがスレッドを生成、行動を起こす前に、静的遅延(のThread.sleep)、または2(受信イベントのコンボを追加し、睡眠ループパターンの代わりに、それを除去することによって、それを回避することができましたあなたは何も最後のmodの日付/時刻をチェックして、それを更新していないことを考えるまで、と)スレッドでループ。
Excelは、ファイルを開くたびに一時ファイルを作成します。 FileSystemEventArgsのNameプロパティをチェックし、ファイル名は「〜」で始まる場合は、イベントを無視します。