Word Automation InvalidCastException RPC / COM 异常

发布于 2024-07-15 12:29:21 字数 4084 浏览 7 评论 0原文

我正在开发文字自动化应用程序,并且面临意外的 RPC/COM 转换异常的严重问题

[System.InvalidCastException:聂 można rzutować obiektu modelu COM 类型 'System.__ComObject' na type interfejsu 'Microsoft.Office.Interop.Word._Application'。 Ta operacja nie powiodła się, ponieważ 使用方法 QueryInterface dla składnika modelu COM w celu uzyskania 干扰或身份识别 IID '{00020970-0000-0000-C000-000000000046}' nie powiodło się z powodu 背景:Serwer RPC 笑话 Niedostępny。 (Wyjątek od HRESULT: 0x800706BA)。]

从波兰语翻译成英语:

无法将 System.__ComObject 转换为 Microsoft.Office.Interop.Word._Application。 原因是 QueryInterface 独立ID '{00020970-0000-0000-C000-000000000046}' 失败 - 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;

....

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

我使用 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 附近。添加。 发生该异常后,将无法执行 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。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

痴情 2024-07-22 12:29:21

你所描述的情况往往是指以下情况。 您使用 COM 进程外服务器(在单独的进程中实例化的 COM 对象,而不是与程序在同一进程中实例化的 COM 对象),并且由于某种原因,COM 服务器遇到致命错误并意外终止。 您使用的 COM 对象不再存在。 由于 RPC 用于与进程外 COM 服务器交互,并且服务器端在终止后不再存在,因此您会收到错误消息,指出 RPC 服务器不可用,这是事实,但看起来令人困惑。

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

  • 传递给调用的一些不合理的输入值以及
  • 事件处理程序中未处理的异常。 如果您对 COM 组件触发的事件有任何处理,您应该捕获可能在处理程序内部引发的所有异常,并且不要让它们在处理程序外部传播。

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.
往日 2024-07-22 12:29:21

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

I don't know, but here are some suggestions based on general experience. You might try using distinct m s rather than sharing one between all parameters (the idea being that if the value is being messed with inside it could be having unpredictable results). You also may want to try providing reasonable values (rather than the m s) wherever you can. Some versions of the API may be more forgiving than others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文