简体   繁体   中英

RPC server is unavailable

I'm getting an intermittent error when using Outlook interop within my program. I get users reporting this error every now and then, but it's impossible to reproduce on my end. What's even stranger is that if they restart the program and try again, the error is gone.

Here's the code I'm using to get a reference to Outlook.

public class CommonStuff
{
    public static void Initialize()
    {
        olk = new Microsoft.Office.Interop.Outlook.Application();
        olk.ItemSend += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemSendEventHandler(OutlookInterop_ItemSend);
    }

    public static Microsoft.Office.Interop.Outlook.Application GetOutlook()
    {
        if (Process.GetProcessesByName("OUTLOOK").Count() == 0) //previous attempt at fixing this issue, and i'm not sure if i even need this
        {
            olk = new Microsoft.Office.Interop.Outlook.Application();
        }
        return olk;
    }
}

And the code that's used when sending the actual email.

    public void SendEmail()
    {
        Microsoft.Office.Interop.Outlook.MailItem eMail = (Microsoft.Office.Interop.Outlook.MailItem)CommonStuff.GetOutlookApp().CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem);
        eMail.Subject = String.Format("Subject");
        eMail.To = "email@things.com";
        eMail.Companies = "Company";
        eMail.Body = "blah blah blah";
        eMail.Attachments.Add(GetCrystalReportPDF());
        ((Microsoft.Office.Interop.Outlook._MailItem)eMail).Display();
    }

Unfortunately I don't know where exactly the error is happening because I can't reproduce the bug. Does anyone have any clues as to what's going on?

This is the classic kind of problem with process interop, you get to troubleshoot all of the bugs and crashes of that other process as well. "RPC server is not available" is a very generic error and doesn't mean anything more than "the process doesn't work anymore". A few simple reasons for that, it could simply have crashed or the user terminated it. Outlook is in general a troublemaker, it isn't exactly the most stable program in Office.

Your work-around with Process.GetProcessesByName() is a fair attempt but it is unlikely to work. Users commonly already have Outlook running for their own use, you'll see that instance as well. You can't tell if that process you see is the one that you started and matches your olk instance or is the one that user is looking at.

The proper workaround is to re-create your olk instance when you get the exception. That can be hard to deal with since it might be generated while you are deeply nested in your code. But it is best to not fix that case, because that hints at your code inducing the crash, you don't want to hide that problem. Implement a "canary test", just sniff at an innocent property before you start doing something non-trivial. If that induces the exception then recreate the instance. Do test this, I'm not 100% sure that the old olk instance is going to bomb your program when it gets finalized. You ought to get a repro by killing Outlook.exe with Task Manager.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM