views:

37

answers:

2

I have an application that uses MSWord automation to edit some documents, after they save and close word I need to grab the modified file and put it back on the repository, there is only one scenario where I can't get it to work and that is when the user makes changes to the file, selects to close word and selects yes to save the file

there are 2 events that I'm using: DocumentBeforeSave Quit

on the Quit event I'm trying to load the .docx file from disk but on this particular scenario I get an IOException because the file is still in use, somehow I need to wait until after the Quit event has been processed, which is when Word is actually closed and the file is no longer being used

right now I have it working using this

      word.Visible = true; 
        while (!wordDone) { //gets changed to true on the Quit event
            System.Threading.Thread.Sleep(100);
        }
        bool error = false;
        do {
            try { //need to load the contents of the modified file
                ls.Content = System.IO.File.ReadAllBytes(provider.GetFileName());
                error = false;
            }
            catch (System.IO.IOException) {
                error = true;
                System.Threading.Thread.Sleep(200);
            }
        } while (error);

while this works it is very ugly, I need a way to fire an event after the Quit event has been handled, or block the current thread while word is still running, or get an event after the document has been saved, the bottom line is I need a clean way to load the file after it has been saved and word is closed. DocumentAfterSave would be awesome, but doesn't seem to exist.

I Also tried unhooking the Quit handler and calling word.Quit on the Quit handler, that made no difference

I'm also investigating the use of ManualResetEvent or related classes, so far it almost works, but I still need to pause after it has been signaled to make sure word is closed and the file is no longer in use

+1  A: 

I used to have the same problem. Using ReleaseComObject on all COM-related objects did the trick (that is, on your Word document object and your Word.Application object). That way you ensure that all dirty locks are removed after the COM object has been destroyed. Close the document and application with the Interop API. I use:

   var localWordapp = new Word.Application();
   localWordapp.Visible = false;
   Word.Document doc = null;
   // ...
    if (doc != null)
    {
      doc.Close();
      System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
    }
    localWordapp.Quit();
    System.Runtime.InteropServices.Marshal.ReleaseComObject(localWordapp);
Anders Oestergaard Jensen
On a side note: Also remember to clean up after yourself when you catch unexpected exceptions. Otherwise you might have WINWORD.EXE instances floating around in your memory. And that is not funny.
Anders Oestergaard Jensen
I have no programmatic control of when word gets closed, that's a user action, I just get the notification on the Quit event
BlackTigerX
Where would I make this call to doc.Close()? I put it on my Quit event handler and I get an ugly exception
BlackTigerX
According to this msdn link the ReleaseComObject only applies up to 2003 http://msdn.microsoft.com/en-us/library/aa679807(office.11).aspx
BlackTigerX
+2  A: 

I faced similar problem in the past as well. I dont think there is any nice clean way but instead of doing it like your above, how about considering this (will suit if you have a controlled environment)

  • Create word app
  • Get the Process ID immediately by using GetProcesses matching Winword and the last one in the list return should be the one you are after. This is not 100% reliable in multiuser environment.
  • After word quit, use the Thread.Sleep loop to ensure the PID no longer exist.
  • Reading the docx for your custom operations
Fadrian Sudaman
That actually worked for what I needed, I'll post the working code in a bit
BlackTigerX
And then the users opens another Word document that will be opened in the same Word instance, and Word never quits when the users closes your file .
The_Fox