2

Word Automation アプリケーションを開発していますが、予期しない RPC/COM キャスト例外で深刻な問題に直面しています。

[System.InvalidCastException: COM typ 'System.__ComObject' から typ インターフェジス 'Microsoft.Office.Interop.Word._Application' に変更されました。Ta operacja niepowiodłasię、poniewa流wywołaniemetody queryinterface dlaskładnikamodelu com w celu uzyskania interfejsu o itidefikatorze '{00020970-0000-0000-c000-0000000000000000000000000000000000000000000000000000000000000000000000000000000000 (Wyjątek od HRESULT: 0x800706BA)]

ポーランド語から英語への翻訳:

System.__ComObject を Microsoft.Office.Interop.Word._Application にキャストできません。その理由は、IID '{00020970-0000-0000-C000-000000000046}' の QueryInterface が失敗したことです - 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;

app = new Application() の代わりに Activator.CreateInstance を使用しています

次に、ユーザーは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 はできません。単語インスタンスが死んでいるようです。

イベントログ(アプリケーションスコープ)でそのことを見つけました:

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。

Office Diagnostics を実行しましたが、エラーは見つかりませんでした。

システムからより多くのエラー情報を有効にする/見つけることは可能ですか?

このコードは、私の開発マシン (vista) で問題なく動作します。この問題は、顧客のマシン (通常は winxp sp2/sp3) で発生します。

コードにエラーがありますか?

私が追加する必要がある唯一のこと。WordModule の init/close/print 関数はメイン スレッドから呼び出され、savetomht は backgroundworkder のスレッドから呼び出されます。

4

2 に答える 2

5

あなたが説明することは、多くの場合、次の状況を指します。COM アウトプロセス サーバー (プログラムと同じプロセスではなく別のプロセスでインスタンス化された COM オブジェクト) を使用していて、何らかの理由で COM サーバーが致命的なエラーに遭遇し、予期せず終了した場合。使用していた COM オブジェクトは存在しません。RPC はアウトプロセス COM サーバーとの対話に使用され、サーバー側は終了後に存在しなくなるため、RPC サーバーが利用できないというエラー メッセージが表示されます。

COM サーバーの終了の理由を調査して排除する必要があります。最も可能性の高い理由は次のとおりです。

  • 呼び出しに渡すいくつかの不合理な入力値と
  • イベント ハンドラーでハンドルされない例外。COM コンポーネントから発生したイベントを処理する場合は、ハンドラー内でスローされる可能性があるすべての例外をキャッチし、ハンドラーの外部に伝播させないようにする必要があります。
于 2009-03-27T05:08:14.173 に答える
1

わかりませんが、一般的な経験に基づいたいくつかの提案があります。mすべてのパラメーター間で 1 つの s を共有するのではなく、別個の s を使用してみてください (値が内部でめちゃくちゃになっていると、予測できない結果になる可能性があるという考えです)。mまた、可能な限り妥当な値 (s ではなく) を提供してみてください。API の一部のバージョンは、他のバージョンよりも寛容である場合があります。

于 2009-03-26T17:43:11.963 に答える