views:

638

answers:

4

Hey Everyone..

I'm writing an automated test to determine whether or not rtf files are successfully opened by MS Word. So far I looping through all the rtfs within a given directory and opening them. Later I will have to catch exceptions to generate a report (log the file name that crashed word).

I am processing a large number of files. My application is currently opening a new instance of Word for each file. Can someone tell me how to close Word?

public class LoadRTFDoc
{
    private object FileName;
    private object ReadOnly;
    private object isVisible;
    private object Missing;
    private ApplicationClass WordApp;
    private object Save;
    private object OrigFormat;
    private object RouteDoc;

    public LoadRTFDoc(object filename)
    {
        this.WordApp = new ApplicationClass();
        this.FileName = filename;
        ReadOnly = false;
        isVisible = true;
        Missing = System.Reflection.Missing.Value;
        Save = System.Reflection.Missing.Value;
        OrigFormat = System.Reflection.Missing.Value;
        RouteDoc = System.Reflection.Missing.Value;

    }


    public void OpenDocument()
    {
        WordApp.Visible = true;
        WordApp.Documents.Open(ref FileName, ref Missing, ref ReadOnly, ref Missing, ref Missing,
                                   ref Missing, ref Missing, ref Missing, ref Missing, ref Missing, ref Missing,
                                   ref isVisible, ref Missing, ref Missing, ref Missing, ref Missing);
        WordApp.Activate();
    }
    public void CloseDocument()
    {
        WordApp.Documents.Close(ref Save, ref OrigFormat, ref RouteDoc);
    }

}

I am executing the CloseDocument() method after each document is opened. Anyone have some insight for me on this?

Thanks!

+1  A: 

Use System.Runtime.InteropServices.ReleaseComObject
and pass it the reference of your word object instance, WordApp.

Sung Meister
+2  A: 

WordApp.Quit followed by ReleaseComObect as said by dance2die.

shahkalpesh
+2  A: 
WordApp.Quit()

will exit the application.

However, the safest way is to get a handle to the process and kill the winword process. In C# the following code would do that:

foreach (Process p in Process.GetProcessesByName("winword"))
{
    if (!p.HasExited)
    {
        p.Kill();
    }
}

The reason is that it will happen frequently (I assume, especially since you are testing documents created not by Word) that Word will hang with an open message box, e.g. a repair dialog. In that case killing the process is the easiest way to close the application.

I would suggest that you first try to close Word using Application.Quit. If this does not work it indicates a problem with your input file (most likely because a repair dialog is blocking Word). You should record this as an error in your log and then proceed killing the winword process.

Another problem you might face is Word's document recovery feature blocking the application on startup (and thus preventing a document from being opened until the recovery dialog box is clicked away). Document recovery can be disabled by deleting the following registry key under both HKCU and HKLM prior to starting Word (replace 12.0 with 11.0 for Word 2003 and 10.0 for Word XP):

Software\Microsoft\Office\12.0\Word\Resiliency

It goes without saying that killing Word is a rather rude approach, however, it is simple and rather robust. The code above will just kill any instance of Word for a user. If you want to kill only a specific instance things get more difficult. You would have to retrieve the process id of a specific Word instance. Typically this can be done by searching for the window title of the instance, e.g. using WinAPI functions like FindWindowByCaption and GetWindowThreadProcessId.

0xA3
A: 

You are all correct. My problem what that I was creating an instance of ApplicationClass within a loop. Whoops. I then used the Quit() after closing each document to kill the winword.exe process.

Thanks you guys!

-Nick

Nick