Word Automation InvalidCastException Исключение RPC / COM - PullRequest
2 голосов
/ 26 марта 2009

Я занимаюсь разработкой приложения для автоматизации слова и столкнулся с серьезной проблемой, за исключением непредвиденного исключения приведения RPC / COM

[System.InvalidCastException: Nie mozna rzutować obiektu modelu COM type 'System .__ ComObject' на типовой интерфейсе 'Microsoft.Office.Interop.Word._Application. Ta operacja nie powiodła się, ponieważ wywołanie metody QueryInterface dla składnika modelu COM w celu uzyskania Интерфейс о Идентификаторе IID '{00020970-0000-0000-C000-000000000046} nie powiodło się z powodu następującego błędu: Серверский RPC шут niedostępny. (Wyjątek od HRESULT: 0x800706BA).]

перевод с польского на английский:

Невозможно привести систему .__ ComObject to Microsoft.Office.Interop.Word._Application. Причина в том, что QueryInterface для IID '{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 () - здесь объяснение .

Затем пользователь может выполнить 2 действия в модуле wordapp

а) распечатать подготовленный документ документа

        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;
        }

б) конвертировать 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;
        }

Когда пользователь выходит из системы, я освобождаю экземпляр слова:

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

Исключение выбрасывается в случайных местах, но наиболее распространенное место находится рядом с app.Documents.Add. После этого исключения приложение app.Quit невозможно. Кажется, что слово экземпляр мертв.

Я нашел эту вещь в журнале событий (область приложения):

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

Я запустил офисную диагностику, и он не нашел ошибок.

Можно ли включить / найти больше информации об ошибках из системы?

Этот код прекрасно работает на моей машине разработчика (Vista). Эта проблема возникает на компьютерах клиентов (обычно это winxp sp2 / sp3).

В моем коде ошибка или что?

Единственное, что мне нужно добавить. WordModule init / close / print функции вызываются из основного потока и savetomht из потока фоновых рабочих

Ответы [ 2 ]

4 голосов
/ 27 марта 2009

То, что вы описываете, часто относится к следующей ситуации. Вы используете COM-сервер out-proc (COM-объект, созданный в отдельном процессе, а не в том же процессе, что и ваша программа), и по какой-то причине COM-сервер обнаружил фатальную ошибку и неожиданно завершил работу. COM-объект, который вы использовали, больше не существует. Поскольку RPC используется для взаимодействия с внешними COM-серверами, а серверная сторона больше не существует после завершения, вы получаете сообщение об ошибке, в котором говорится, что сервер RPC недоступен, что является истинным, но выглядит запутанным.

Вы должны выяснить и устранить причину завершения COM-сервера. Наиболее вероятные причины:

  • некоторые необоснованные входные значения, которые вы передаете вызовам, и
  • необработанное исключение в обработчике событий. Если у вас есть какая-либо обработка событий, запускаемых из COM-компонента, вы должны перехватить все исключения, которые могут быть сгенерированы внутри вашего обработчика, и не позволять им распространяться за пределы обработчика.
1 голос
/ 26 марта 2009

Не знаю, но вот несколько советов, основанных на общем опыте. Вы можете попробовать использовать отдельные m вместо того, чтобы делить единицу между всеми параметрами (идея заключается в том, что, если значение путается внутри, это может иметь непредсказуемые результаты). Вы также можете попытаться предоставить разумные значения (а не m s) везде, где можете. Некоторые версии API могут быть более щедрыми, чем другие.

...