views:

68

answers:

3

We use a FileSystemWatcher to monitor documents opened from our Document Management system, and if the user saves the document, we ask if they would also like them updated in our system.

We have a problem with XLS files in Excel 2007 (have not verified that the problem does not exist in 2003, but it only seems to be files that open in compatibility mode in 2007) where the Changed event fires immediately upon opening the file, and then once more upon closing the file, even if nothing has changed or the user chooses not to save upon closing. This same behavior does not exist when opening XLSX files.

I wrote a test app to verify the behavior, which you can find at (http://www.just2guys.net/SOFiles/FSWExcel.zip). In the app, there is one FileSystemWatcher for each NotifyFilter type, so that it is apparent why the Changed event was fired.

Any way you can think of to only prompt the user when the document is actually saved in some way by the user? I can start monitoring the file after Process.Start is called, which allows me to skip the message upon opening the document, but I still get one upon closing the document, even when nothing was changed.

A: 

Excel creates a temporary file each time it opens a file - this is probably the event you are seeing. Check the Name property of FileSystemEventArgs and ignore the event if the filename starts with '~'.

Mark Ransom
No, that isn't it. First off, it is the Changed event (rather than Created), and second, I am filtering on the specific filename in the Filter property. It definitely fires the changed event for that specific file, but only when it is an XLS file, not for XLSX
Rick Mogstad
+3  A: 

I noticed this with Word, and you can simply reproduce it:

If you open a .doc or an .xls file with an Office application, the timestamp changes to the time the document was opened.

If you close the application, the timestamp is reset to its original value (only if you did ont save).

So for Office files, you need two additional checks:

  • on Open, when timestamp is set to current time, check that the file can be opened exclusively

  • on Close, check whether the timestamp is "close to" the current date and time, or check the file's Archive flag

devio
So, I can get rid of the Open one by starting monitoring immediately after calling the Process.Start, but the Close is what was giving me grief. It seems like checking the timestamp to see that it is within a certain amount of time from the current time would work, and prompt if it is. Wouldn't your open check fail in the same way if they pressed the Save button while still in the document? Perhaps I am reading it wrong. I will try out your suggestion for the close, and mark appropriately.
Rick Mogstad
This is still messy, since user saves don't fire the LastWrite notification for office docs, but they do for everything else, but this helped me move forward quite a lot, and I am pretty confident I can come up with a solution for it.
Rick Mogstad
+1  A: 

File system watcher is usually evil. It burns a lot of people because it registers events before the file is completely written.

We have been able to get around it by either removing it in lieu of a sleep loop pattern, adding a static delay (Thread.Sleep) before taking action, or a combo of the two (receiving the event, spawning a thread, and looping in the thread until you think that nothing is updating it by checking the last mod date/time).

StingyJack
The interesting thing is that I think we avoid that problem in both cases that we use it because we don't trigger any access of the file immediately during the event. In one case, it is added to a queue to be processed later, and in the other, we prompt the user, both of which take enough time to allow the file to completely save. I will keep this in mind, though, if we use it in any other place.
Rick Mogstad