Word Automation InvalidCastException RPC/COM异常

Word Automation InvalidCastException RPC/COM异常,exception,com,automation,ms-word,rpc,Exception,Com,Automation,Ms Word,Rpc,我正在开发word自动化应用程序,遇到了一个严重的问题,出现了意外的RPC/COM强制转换异常 [System.InvalidCastException:Nie można rzutowaćobiektu模型 “系统”是典型的交互对象 “Microsoft.Office.Interop.Word.\u应用程序”。 这是我的歌剧,波涅瓦 wywołanie metody QueryInterface dla 乌兹卡尼亚西部的斯卡德尼卡模型公司 国际身份识别机构IID “{00020970-0000

我正在开发word自动化应用程序,遇到了一个严重的问题,出现了意外的RPC/COM强制转换异常

[System.InvalidCastException:Nie można rzutowaćobiektu模型 “系统”是典型的交互对象 “Microsoft.Office.Interop.Word.\u应用程序”。 这是我的歌剧,波涅瓦 wywołanie metody QueryInterface dla 乌兹卡尼亚西部的斯卡德尼卡模型公司 国际身份识别机构IID “{00020970-0000-0000-C000-0000000000 46}” nie powiodło sięz powodu następującego błdu:Serwer RPC笑话 niedostępny.(Wyjątek od HRESULT: 0x800706BA)。]

波兰语到英语的翻译:

无法强制转换系统。\u\u对象到 Microsoft.Office.Interop.Word.\u应用程序。 原因是,对 IID “{00020970-0000-0000-C000-0000000000 46}” 失败-RPC服务器不可用- 错误代码HRESULT:0x800706BA

以下是wordapp模块简介:

初始化-用户登录后

using Microsoft.Office.Interop.Word;

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

我使用的是Activator.CreateInstance,而不是app=new Application()

然后用户可以在wordapp模块中执行2个操作

a) 打印准备好的docx文档

        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) 将docx转换为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;
        }
当用户注销时,我将释放word实例:

            object oSaveChanges = WdSaveOptions.wdDoNotSaveChanges;
            app.Quit(
         ref oSaveChanges,
         ref m,
         ref m);
异常在随机位置抛出,但最常见的位置是app.Documents.Add附近。在该异常之后,app.Quit是不可能的。“实例”这个词似乎已经过时了

我在事件日志(应用程序范围)中发现了这一点:

事件类型offdiag12,P1 585d8a02-f370-4c04-85b6-fccad7e80459255ec053-6dbd-4a22-9e59-112a79de8c6a, P2零、P3零、P4零、P5零、P6 零,P7零,P8零,P9零,P10零

我运行office诊断,它没有发现任何错误

是否有可能从系统中启用/查找更多错误信息

这段代码在我的开发机器(vista)上运行得非常好。问题发生在客户的计算机上(通常是winxp sp2/sp3)

我的代码中有错误吗

我只需要补充一件事。
WordModule init/close/print函数是从主线程调用的,而savetomht是从BackgroundWorkers的线程调用的。

我不知道,但这里有一些基于一般经验的建议。您可以尝试使用distinct
m
s,而不是在所有参数之间共享一个参数(其想法是,如果值在内部被弄乱,可能会产生不可预测的结果)。您还可能希望尽可能提供合理的值(而不是
m
s)。API的某些版本可能比其他版本更宽容。

您描述的内容通常涉及以下情况。您使用COM out proc服务器(COM对象在单独的进程中实例化,而不是在与程序相同的进程中实例化),并且由于某种原因,COM服务器遇到致命错误并意外终止。您使用的COM对象已不存在。由于RPC用于与out proc COM服务器交互,并且终止后服务器端不再存在,因此您会收到错误消息,表示RPC服务器不可用,这是真的,但看起来很混乱

您必须研究并消除COM服务器终止的原因。最可能的原因如下:

  • 传递给调用和
  • 事件处理程序中未处理的异常。如果您对COM组件触发的事件有任何处理,那么您应该捕获可能在处理程序内部抛出的所有异常,而不让它们在处理程序外部传播

是的,我同意可能是这样。现在的问题是,我不知道如何检测word应用程序实例关闭的原因。是否有可能为word启用日志记录错误?不知道如何启用日志记录,但您可以尝试推断问题的根源。你有事件处理程序吗?如果是这样,它们中是否有任何一个在外部传播异常?您是否为最有可能不应该为null的参数传递null?我不认为这是无效参数的问题,因为调用这些office函数通常有效,不包括office禁用时的调用。我不了解事件处理程序。我唯一能做的就是取消隐藏word,并将消息级别设置为all,然后观察是否出现任何消息。您可以尝试在加载COM服务器的进程中附加调试器。当进程崩溃时,您可以检查调用堆栈。但不太可能有帮助。
            object oSaveChanges = WdSaveOptions.wdDoNotSaveChanges;
            app.Quit(
         ref oSaveChanges,
         ref m,
         ref m);