【问题标题】:Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))呼叫被被呼叫者拒绝。 (来自 HRESULT 的异常:0x80010001 (RPC_E_CALL_REJECTED))
【发布时间】:2014-01-05 11:59:56
【问题描述】:

我有一个小型 C# Winforms 应用程序,它使用 Word.Interop 获取单个邮件合并文档,复制每个部分,将该部分粘贴到它自己的文档中,然后单独保存。

我不断(有时随机)收到错误消息:Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))。我已经测试了下面的代码,当我使用断点时,我从未收到此消息。但是,如果我让它不受限制地运行,它似乎在我的行 oNewWord.ActiveDocument.Range(0, 0).Paste(); 处出错。更奇怪的是,有时我会按预期收到异常消息,有时处理似乎只是挂断,当我在 Visual Studio 中按 PAUSE 时,它显示当前在我的异常消息框行。

有人知道如何解决这个问题吗?

代码:

public void MergeSplitAndReview()
        {
            try
            {
                // Mail Merge Template
                Word.Application oWord = new Word.Application();
                Word.Document oWrdDoc = new Word.Document();

                // New Document Instance
                Word.Application oNewWord = new Word.Application();
                Word.Document oNewWrdDoc = new Word.Document();

                object doNotSaveChanges = Word.WdSaveOptions.wdDoNotSaveChanges;

                // Documents must be visible for code to Activate()
                oWord.Visible = true;
                oNewWord.Visible = true;

                Object oTemplatePath = docLoc;
                Object oMissing = System.Reflection.Missing.Value;

                // Open Mail Merge Template
                oWrdDoc = oWord.Documents.Open(oTemplatePath);

                // Open New Document (Empty)
                // Note: I tried programmatically starting a new word document instead of opening an exisitng "blank",
                //       bu when the copy/paste operation occurred, formatting was way off. The blank document below was
                //       generated by taking a copy of the FullMailMerge.doc, clearing it out, and saving it, thus providing
                //       a kind of formatted "template".
                string newDocument = projectDirectory + "\\NewDocument.doc";
                oNewWrdDoc = oNewWord.Documents.Open(newDocument);

                // Open Mail Merge Datasource
                oWrdDoc.MailMerge.OpenDataSource(docSource, oMissing, oMissing, oMissing,
                   oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing);

                // Execute Mail Merge (Opens Completed Mail Merge Documents Titled "Letters1")
                oWrdDoc.MailMerge.Execute();

                int docCnt = oWord.ActiveDocument.Sections.Count - 1;
                int cnt = 0;
                while (cnt != docCnt)
                {
                    cnt++;
                    string newFilename = "";

                    // Copy Desired Section from Mail Merge
                    oWord.ActiveDocument.Sections[cnt].Range.Copy();
                    // Set focus to the New Word Doc instance
                    oNewWord.Activate();
                    // Paste copied range to New Word Doc




                    oNewWord.ActiveDocument.Range(0, 0).Paste(); // THIS IS THE POINT WHERE I GET THE ERROR MENTIONED WHEN NOT USING A BREAKPOINT.



                    foreach (ListViewItem lvI in lvData.Items)
                    {
                        if (lvI.Checked) // Get first checked lvI in lvData to use for generating filename
                        {
                            updateAddrChngHistory(lvI.SubItems[18].Text);

                            string fileSys = lvI.SubItems[14].Text.ToUpper();
                            string memNo = lvI.SubItems[0].Text;

                            newFilename = fileSys + "%" + memNo + "%" + "" + "%" + "" + "%" + "CORRESPONDENCE%OUTGOING - ACKNOWLEDGEMENT%" + DateTime.Now.ToString("yyyy-MM-dd-hh.mm.ss.ffffff") + ".doc";

                            lvI.Remove(); // Delete from listview the lvI used for newFilename
                            break;        // Break out of foreach loop
                        }
                    }

                    // Save New Word Doc
                    oNewWord.ActiveDocument.SaveAs2(docTempDir + newFilename);
                    // Clear New Word Doc
                    oNewWord.ActiveDocument.Content.Select();
                    oNewWord.Selection.TypeBackspace();
                }
                // Hides my new word instance used to save each individual section of the full Mail Merge Doc
                oNewWord.Visible = false;
                // MessageBox.Show(new Form() { TopMost = true }, "Click OK when finished.");
                MessageBox.Show(new Form() { TopMost = true }, "Click OK when finished.");

                oNewWord.ActiveDocument.Close(doNotSaveChanges); // Close the Individual Record Document
                oNewWord.Quit();                                 // Close Word Instance for Individual Record
                oWord.ActiveDocument.Close(doNotSaveChanges);    // Close the Full Mail Merge Document (Currently ALSO closes the Template document)
                // oWord.Documents.Open(docTempDir + "FullMailMerge.doc");

                oWord.Quit(doNotSaveChanges);                    // Close the Mail Merge Template
                MessageBox.Show("Mail Merge Completed, Individual Documents Saved, Instances Closed.");
            }
            catch (Exception ex)
            {
                LogException(ex);
                MessageBox.Show("Source:\t" + ex.Source + "\nMessage: \t" + ex.Message + "\nData:\t" + ex.Data);
                // Close all Word processes
                Process[] processes = Process.GetProcessesByName("winword");
                foreach (var process in processes)
                {
                    process.Close();
                }
            }
            finally
            {

            }
        }

【问题讨论】:

  • @HansPassant,感谢您的回复。关于修改我的代码以使用选项一的任何想法?我发现设置实例 Visible = False 会导致我尝试使用 Activate 表单时出现问题。
  • 为什么你会选择你不喜欢的选项?创可贴是在 MailMerge.Execute() 调用之后休眠一段时间。真正的解决方法是使用 IOleMessageFilter,如图所示。
  • 我不知道你说的“你到底为什么会选择你不喜欢的选项?”是什么意思?我并没有说我不喜欢它,只是如果Activate() 看不到实例,我之前的当前代码会遇到问题。我只是问你是否可以看到一些简单的修改,我不需要使用Activate() 到我可以隐藏所有处理的地方,直到我在最后展示完整的邮件合并文档(这是我更喜欢的)无论如何要做)。
  • @HansPassant,无论如何,我感谢您的帮助。我认为第三个选项会很复杂,但想出了如何实现它,现在我不再收到 Rejected Callee 错误。谢谢!

标签: c# automation ms-word office-interop mailmerge


【解决方案1】:

正如Andrew Barber 指出的那样,我的方式在处理异常时会导致性能损失

Hans Passant 引用的the article 确实为选项3 提供了一种很棒的 方式。

----下面会导致性能损失

当它忙时,需要一段时间后重试。

此功能是否有助于重试

使用 lambda(委托)作为参数

用法1

var selectionLocal = selection; 
var range = RunWithOutRejected(() => selectionLocal.Range);

用法2

RunWithOutRejected(
   () =>
       following.Value.Range.FormattedText.HighlightColorIndex =
         WdColorIndex.wdGray25);

用法3

var nameLocal = name;
var bookmark = RunWithOutRejected(() =>  
   winWordControl
   .GetDocument()
   .Bookmarks.Add(nameLocal, range));
name = RunWithOutRejected(() => bookmark.Name);
return new KeyValuePair(name, bookmark);

ps:使用该函数互操作MSword时,代码_application.Selection.PasteSpecial();失败


    public static T RunWithOutRejected<T>(Func<T> func)
    {
        var result = default(T);
        bool hasException;

        do
        {
            try
            {
                result = func();
                hasException = false;
            }
            catch (COMException e)
            {
                if (e.ErrorCode == -2147418111)
                {
                    hasException = true;
                }
                else
                {
                    throw;
                }
            }
            catch (Exception)
            {
                throw;
            }
        } while (hasException);

        return result;
    }
}

【讨论】:

  • 这似乎是个坏主意。你只是在它工作之前一直在努力,可能会导致 lots 的异常被创建。您的 ErrorCode 与此处遇到的错误不匹配,可能是因为您没有专门针对此问题创建此答案;您在这里重新发布了on MSDN 和其他四个问题。同样,Func&lt;T&gt; 在这里也行不通。
  • 抱歉打扰了。感谢您的格式化。我知道这不是一个好主意。这段代码用于我与MSWord互操作的简单工具中,ErrorCode在运行时与0x80010001完全相同,可以准确捕获异常。 Func 只是在使用这种 ugly 方式访问 MSWord 应用程序的属性时更容易重试。
【解决方案2】:

我遇到了同样的问题,从 office 2010(win 10 64 位)升级到 office 2016 后, 我的问题:word不是编辑文档的默认程序,所以 我从“控制面板\所有控制面板项目\默认程序\设置默认程序”中将单词设置为默认程序 它解决了。

【讨论】:

    猜你喜欢
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    相关资源
    最近更新 更多