0
  • This is my first question on the platform, apologies if i have not followed any rules while asking the question.
  • a similar question was asked here but it has no replies.

Background: I am working on a windows application which generate email items (*.msg file) and save them in windows directory. The content of the email body, subject is coming from a word document. One document could be used for hundreds of email items.

I am working with Microsoft Visual Studio Professional 2019 and Microsoft Outlook 16 object Library (V9.6)

Problem: I am able to generate email files correctly, But randomly the application encounter below error.

The remote procedure call failed. (0x800706BE) on mailItem.SaveAs(mailItemPath, Outlook.OlSaveAsType.olMSG);

and as soon as application throw this error, my outlook application gets closed.

What I have tried

  1. I have tried this on other machines, including a remote machine.
  2. I have tried manually clearing objects after each call.
  3. i have tried saving the email in the user's draft folder instead of directory none of them helped.

the last thing which I have tried was, starting the outlook process again. var outlookFilePath = System.IO.Directory.GetFiles(@"C:\Program Files\Microsoft Office", "OUTLOOK.EXE", SearchOption.AllDirectories); Process.Start(outlookFilePath[0]);

Though this helps, but it is not a solution but a work around.

Below is my function

public void SaveEmailItems(Outlook.Application outlookApp, Word.Document documentFrom, string[] sourceFilesPath, int index, int letterType)
        {
            string functionName = "SaveEmailItem";
            Outlook.MailItem mailItem = null;
            Outlook.Inspector itemInspector = null;
            Word.Document outlookDocument = null;
            Word.Range oRange = null;
            bool isOutlookActive = false;
            try
            {
                //create a new outlook Item
                mailItem = outlookApp.CreateItem((Outlook.OlItemType.olMailItem)) as Outlook.MailItem;
                Logger.WriteLog(functionName, "new mail item created.");
                itemInspector = mailItem.GetInspector;
                //outlookDocument = itemInspector.WordEditor;

                mailItem.Display();
              
                //Word editor is required to create email content with formatting.
                outlookDocument = itemInspector.WordEditor;
                Logger.WriteLog(functionName, "mail item displayed.");

                itemInspector.WindowState = Outlook.OlWindowState.olMinimized;
                mailItem.To = toRecipients + "//";
                mailItem.Subject = subjectLine;
                mailItem.Body = "";
                //email body

               
                oRange = documentFrom.Content;
                try
                {
                    oRange.Copy();
                    outlookDocument.Content.PasteSpecial();
                }
                catch
                {   
                    oRange.Copy();
                    outlookDocument.Content.PasteSpecial();
                }
                Logger.WriteLog(functionName, "Email Body Created.");

                //Save to Location
                //remove '/'' windows does not allow file name with '/'
                clientName = clientName.Replace("/", "").Trim();
                clientName = clientName.Replace("\\", "").Trim();
                string mailItemPath = (sourceFilesPath[6] + "\\" + cd + "\\" + letterType + "_" + clientName + "_" + index + ".msg");
                if (mailItemPath.Length > 259)
                {
                    //Max length for windows path is 260
                    Logger.WriteLog(functionName, "Length of the path was too big so using only client name.");
                    mailItemPath = (sourceFilesPath[6] + "\\" + cd + "\\" + letterType + "_" + clientColumnValue + "_" +
                                    index + ".msg");
                }
                Logger.WriteLog(functionName, "mail Item Path - " + mailItemPath);
               

                mailItem.SaveAs(mailItemPath, Outlook.OlSaveAsType.olMSG);
                //mailItem.Save();
               
                isOutlookActive = true;
                Logger.WriteLog(functionName, "MAIL ITEM SAVED for entity name - " + clientName + "at index - " + index + ".msg");
            }
            catch (COMException exception)
            {
                Logger.WriteLog(functionName, "An unknown COMException occurred while generating emails.");
                Logger.WriteLog(functionName, "Exception - " + exception.Message);
                Logger.WriteLog(functionName, "Exception - " + exception.StackTrace);
                throw new COMException();
            }

            finally
            {
                //Discard the item
                if (oRange != null)
                {
                    Marshal.FinalReleaseComObject(oRange);
                    oRange = null;
                }

                if (outlookDocument != null)
                {
                    Marshal.FinalReleaseComObject(outlookDocument);
                    outlookDocument = null;
                }
               
                if (isOutlookActive && itemInspector != null)
                {
                    itemInspector.Close(Outlook.OlInspectorClose.olDiscard);
                    Marshal.FinalReleaseComObject(itemInspector);
                    itemInspector = null;
                }

                if (isOutlookActive && mailItem != null)
                {
                    mailItem.Close(Outlook.OlInspectorClose.olDiscard);
                    Marshal.FinalReleaseComObject(mailItem);
                    mailItem = null;
                    Logger.WriteLog(functionName, "mail item closed");
                }
                //Clipboard.Clear();
                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }

Any help or pointer will be appreciated, Thanks in advance.

Scott
  • 1

1 Answers1

0

The remote procedure call failed. (0x800706BE)

There can be multiple reasons why it happens. Let's consider them in depth:

  1. When the Outlook application is closed for any reason (crashed, closed and etc.) you will not be notified about that. Because you deal with a COM server. See System.Runtime.InteropServices.COMException (0x800706BE) when getting contact.LastName for more information.

    To keep Outlook alive you can try to get any Explorer window and keep its instance (visible or not) until you need Outlook running in memory. The Explorers.Add method creates a new instance of the explorer window.

  2. It is not clear how and when the application is run. But Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.

    If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution. Read more about that in the Considerations for server-side Automation of Office article.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Thanks @astafiev for taking time and answering the question, it cleared some queries however I never reached to the bottom of the issue so I changed my approach and now the program is working absolutely fine. – Scott Mar 24 '22 at 07:14