3

I have a small C# Winforms Application that is using Word.Interop to Take a Single Mail Merge Document, copy each section, paste that section into it's own document, and save it individually.

Error

I keep (sometimes randomly) getting the error message: Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED)). I have tested my below code and when I use breakpoints, I never receive this message. However, if I let it run uninhibited, it seems to error out at my line oNewWord.ActiveDocument.Range(0, 0).Paste();. What is even weirder, sometimes I get the Exception Message as expected, other times processing seems to just hang up and when I press PAUSE in Visual Studio, it shows me as currently at my Exception Message box line.

Anyone know how to resolve this?

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
            {

            }
        }
Analytic Lunatic
  • 3,853
  • 22
  • 78
  • 120
  • 3
    http://blogs.artinsoft.net/Mrojas/archive/2012/09/28/Office-Interop-and-Call-was-rejected-by-callee.aspx – Hans Passant Dec 17 '13 at 16:18
  • @HansPassant, thanks for the reply. Any ideas on modifying my code to use option one? I've found that setting the instances `Visible = False` causes issues where I try to `Activate` forms. – Analytic Lunatic Dec 17 '13 at 16:54
  • Why on Earth would you pick the option you don't like? The band-aid is to sleep for a while after the MailMerge.Execute() call. The real fix is to use IOleMessageFilter as shown. – Hans Passant Dec 17 '13 at 16:58
  • I'm not sure what you mean by "Why on Earth would you pick the option you don't like?" I didn't say that I don't like it, just that I've previously had issues with my current code if the instances aren't visible to `Activate()`. I was simply asking if you could see some easy modifications to where I didn't need to use `Activate()` to where I can hide all my processing until I present the full mail merge doc at the end (which is what I'd prefer to do anyway). – Analytic Lunatic Dec 17 '13 at 17:14
  • @HansPassant, In any case, I appreciate the help. I thought the third option would be complicated, but figured out how to implement it and now I'm no longer receiving the `Rejected Callee` error. Thanks! – Analytic Lunatic Dec 17 '13 at 20:10
  • @HansPassant - Thank you - the day before a deployment I started getting this error and came across your post at 8pm. Life saver. And my app will be moved to SSIS asap. Many thanks again. – SteveB Mar 17 '16 at 20:09

2 Answers2

2

As Andrew Barber point out that my way cause performance loss when handling exception.

And the article referenced by Hans Passant did provide a GREAT way with option 3.

----below will cause performance loss

when it is busy, need a retry after some period of time.

may this function be helpful to retry

use lambda (delegate) as parameter

Usage 1

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

Usage 2

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

Usage 3

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

ps: when interop MSword using this function, the code _application.Selection.PasteSpecial(); failed


    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;
    }
}
Community
  • 1
  • 1
pie
  • 169
  • 1
  • 8
  • That seems like a bad idea. You're just thrashing at it until it works, likely causing *lots* of Exceptions to be created. Your `ErrorCode` does not match the error experienced here, probably because you didn't create this answer specifically for this question; you re-posted it [on MSDN](http://social.msdn.microsoft.com/Forums/vstudio/en-US/5c75d58d-cc3d-4214-941f-ca4b61941ec9/call-rejected-by-callee-word-2010-delphi?forum=worddev) and to four other questions here. Also along those lines, `Func` won't work here. – Andrew Barber Aug 13 '14 at 18:20
  • Sorry for bothering you. Thanks for your formatting. I know it's not a good idea. This code is used in my simple tool for inter operating with MSWord, the ErrorCode is really the same as 0x80010001 in runtime and can catch the exception precisely. Func just make retry easier when using this **ugly** way to access MSWord Application's propertys. – pie Aug 14 '14 at 10:35
0

i had the same problem, after upgrading to office 2016 from office 2010 (win 10 64 bit), my problem : word was not the default program for editing document, so i made word as default program from "Control Panel\All Control Panel Items\Default Programs\Set Default Programs" and it solved.

yair
  • 9
  • 1