R – Word Automation InvalidCastException RPC / COM Exception

automationcomexceptionms-wordrpc

I'm developing word automation application and I'm facing serious issue with unexpected RPC/COM cast exception

[System.InvalidCastException: Nie
można rzutować obiektu modelu COM typu
'System.__ComObject' na typ interfejsu
'Microsoft.Office.Interop.Word._Application'.
Ta operacja nie powiodła się, ponieważ
wywołanie metody QueryInterface dla
składnika modelu COM w celu uzyskania
interfejsu o identyfikatorze IID
'{00020970-0000-0000-C000-000000000046}'
nie powiodło się z powodu
następującego błędu: Serwer RPC jest
niedostępny. (Wyjątek od HRESULT:
0x800706BA).]

translation from polish to english:

Unable to cast System.__ComObject to
Microsoft.Office.Interop.Word._Application.
The reason is that QueryInterface for
IID
'{00020970-0000-0000-C000-000000000046}'
failed – RPC server is unavailable –
error code HRESULT: 0x800706BA

Here the brief of wordapp module:

Initialization – after user is logged in.

using Microsoft.Office.Interop.Word;

    public class WordApp       
    {
        Application app = null;
        object m = System.Reflection.Missing.Value; 
        object oFalse = false;  
        object oTrue = true;

….

            app = Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application.12")) as Application;
            app.Visible = false;
            app.DisplayAlerts = WdAlertLevel.wdAlertsNone;
            app.PrintPreview = false;

I'm using Activator.CreateInstance instead of app = new Application() – here the explanation.

Then user can execute 2 actions in wordapp module

a) print prepared docx document

        System.Windows.Forms.PrintDialog pd = new System.Windows.Forms.PrintDialog();
        ...

        this.app.ActivePrinter = pd.PrinterSettings.PrinterName;
        object oNumcopies = pd.PrinterSettings.Copies;
        object oRange = WdPrintOutRange.wdPrintAllDocument;
        object inputname = fullPath;
        Document doc = app.Documents.Add(
                              ref inputname,
                              ref m,
                              ref m,
                              ref m);
        try
        {
            // Print the document 
            doc.PrintOut(ref oFalse, ref oFalse, ref oRange,
                    ref m, ref m, ref m,
                    ref m, ref oNumcopies, ref m, ref m,
                    ref oFalse, ref m, ref m,
                    ref m, ref m, ref m, ref m,
                    ref m);
        }
        finally
        {
            doc.Close(ref oFalse, ref m, ref m);
            doc = null;
        }

b) convert docx to mht

        object inputname = docxname;
        object outputname = htmlname;
        object fileType = WdSaveFormat.wdFormatWebArchive;

        Document doc = app.Documents.Add( 
                              ref inputname,
                              ref m,
                              ref m,
                              ref m);
        try
        {
            doc.SaveAs(ref outputname, ref fileType,
                ref m, ref m, ref m, ref m, ref m, ref m, ref m,
                ref m, ref m, ref m, ref m, ref m, ref m, ref m);
        }
        finally
        {
            doc.Close(ref oFalse, ref m, ref m);
            doc = null;
        }

When user logout, then I release word instance:

            object oSaveChanges = WdSaveOptions.wdDoNotSaveChanges;
            app.Quit(
         ref oSaveChanges,
         ref m,
         ref m);

The exception is thrown out in random places – but the most common place is near app.Documents.Add. After that exception it's not possible to app.Quit. It seems that word instance is dead.

I found that thing in eventlog (application scope):

EventType offdiag12, P1
585d8a02-f370-4c04-85b6-fccad7e80459255ec053-6dbd-4a22-9e59-112a79de8c6a,
P2 NIL, P3 NIL, P4 NIL, P5 NIL, P6
NIL, P7 NIL, P8 NIL, P9 NIL, P10 NIL.

I run office diagnostic and it didn't find any error.

Is there possible to enable / find more error informations from system?

This code runs perfectly well on my dev machine (vista). The issue occurs at customers machines (usually winxp sp2/sp3).

Is there an error in my code or what?

The only one thing I need to add.
WordModule init/close/print functions are called from main thread and savetomht from backgroundworkders' thread.

Best Answer

What you describe often refers to the following situation. You use a COM out-proc server (a COM object instantiated in a separate process rather then in the same process as your program) and for some reason that COM server encounters a fatal error and terminates unexpectedly. The COM object you were using no longer exists. Since RPC is used for interacting with out-proc COM servers and the server side no longer exists after termination you receive the error message saying that the RPC server is unavailable which is true but looks confusing.

You have to research and eliminate the reason of COM server termination. The most likely reasons are the following:

  • some unreasonable input values you pass to the calls and
  • an unhandled exception in an event handler. If you have any handling for events fired from a COM component you should catch all the exceptions that may be thrown inside your handler and not let them propagate outside the handler.
Related Topic