2013-12-17 302 views
3

我有一個小的C#Winforms應用程序正在使用Word.Interop採取單個郵件合併文檔,複製每個部分,將該部分粘貼到它自己的文檔,並單獨保存。呼叫被被叫方拒絕。 (從HRESULT異常:0x80010001(RPC_E_CALL_REJECTED))

Error

我保持(有時隨機地)得到的錯誤消息:Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))。我測試了我的下面的代碼,當我使用斷點時,我從來沒有收到這個消息。但是,如果我讓它運行不受限制,它似乎錯誤在我的行oNewWord.ActiveDocument.Range(0, 0).Paste();。什麼是更奇怪的,有時我會按預期得到異常消息,其他時間處理似乎只是掛起來,當我在Visual Studio中按下暫停時,它顯示我當前在我的異常消息框行。

任何人都知道如何解決這個問題?

CODE:

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 
      { 

      } 
     } 
+3

http://blogs.artinsoft.net/Mrojas/archive/2012/09/28/Office-Interop-and-Call-was-rejected-by-callee.aspx –

+0

@HansPassant,感謝您的回覆。任何想法修改我的代碼使用選項一?我發現將實例'Visible = False'設置爲我嘗試「激活」表單的問題。 –

+0

爲什麼選擇你不喜歡的選項?創可貼是在MailMerge.Execute()調用後休息一會兒。真正的解決方法是使用IOleMessageFilter,如圖所示。 –

回答

2

由於​​,我的方式引起性能損失處理異常時,點了。

而且the article通過Hans Passant引用沒有提供GREAT方式與選項3

----下面會造成性能損失

當它是繁忙的,需要一段時間後重試。

可以此功能是有幫助的重試

使用拉姆達(代表)作爲參數

用法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; 
    } 
} 
+0

這似乎是一個糟糕的主意。你只需要對它進行顛覆,直到它能夠工作,可能會導致創建多個異常。你的'ErrorCode'與這裏遇到的錯誤不匹配,可能是因爲你沒有專門爲這個問題創建這個答案。你重新張貼它[在MSDN](http://social.msdn.microsoft.com/Forums/vstudio/en-US/5c75d58d-cc3d-4214-941f-ca4b61941ec9/call-rejected-by-callee-word- 2010-delphi?forum = worddev)以及其他四個問題。同樣沿着這些線路,'功能'不會在這裏工作。 –

+0

對不起,打擾你了。感謝您的格式。我知道這不是一個好主意。該代碼用於我的簡單工具,用於與MSWord進行交互操作,ErrorCode與運行時的0x80010001確實相同,並且可以精確捕獲異常。 Func 只是在使用這種**醜陋的**方式訪問MSWord應用程序的特性時重試更輕鬆。 – pie

1

我有同樣的問題,從2010年的辦公升級到Office 2016年以後(贏得10 64位), 我問題:單詞不是編輯文檔的默認程序,所以 我從「控制面板\所有控制面板項目\默認程序\設置默認程序」 作爲默認程序的詞,它解決了。

相關問題