System.Diagnostics.Process Exit Code is 0xc0000005 instead of 0 on one specific machine

-1

I'm stumped...

We have an old 32 bit application that is launching a 64 bit stub application to send email via Outlook 64, using MapiEmail::Email::SendMail. I should be getting 0 or 1 back from the stub as the Process Exit Code, but on one laptop we're getting 0xC0000005 back.. even though it is still successfully sending the email.

If I comment out the SendMail line in the stub I get the expected ExitCode of 0. Also if I display the result of SendMail in the stub (via System::Windows::Forms::MessageBox::Show), the ExitCode as reported by Process::ExitCode also ends up being 0.

I know I could ditch this entirely and just rely on some sort of return file getting written.. but would love to understand what's going on and if there's a way to more easily address it. For example, I'm hoping there's a magic setting that will force the exit code to be what our [Main] method returns, regardless of whatever the OS later on wants it to be.

Here's the primary method in the stub:

bool SendMailInterop::SendEmail(std::string & name, std::string & from, std::string & to, std::string & cc, std::string & subject, std::string & body, std::string & attachment)
{
    String^ result = "";
    try
    {
        MapiHelper::InitializeMapi();

        String^ _name = gcnew String(name.c_str());
        String^ _from = gcnew String(from.c_str());
        String^ _to = gcnew String(to.c_str());
        String^ _cc = gcnew String(cc.c_str());
        String^ _body = gcnew String(body.c_str());
        String^ _subject = gcnew String(subject.c_str());
        String^ _attachment = gcnew String(attachment.c_str());

        Email^ email = gcnew Email();

        result = email->SendEmail(_name, _from, _to, _cc, _subject, _body, _attachment);

        //Interesting. If I do the following, the ExitCode of the System.Diagnostics.Process object
        //we use to invoke this stuff is correctly 0. If I leave it commented out, we'll get 0xC0000005
        //in the one test laptop 
        //System::Windows::Forms::MessageBox::Show(result) 

        delete email;

        MapiHelper::UninitializeMapi();
    }
    catch (...)
    {
    }
    return (result == "OK [0]");
}

Here's the invoking code (our app is C++, calling this C# via interop)

System.Diagnostics.Process sendEmail64 = new Process();
            sendEmail64.StartInfo.CreateNoWindow = true;
            sendEmail64.StartInfo.UseShellExecute = true;
            sendEmail64.StartInfo.FileName = stubExePath;
            sendEmail64.StartInfo.Arguments = String.Format(@"""{0}""", file);
            sendEmail64.EnableRaisingEvents = true;
            sendEmail64.Exited += new EventHandler(SendEmail64_Exited);
            sendEmail64.Start();
:
Some hacky wait looping
:
MessageBox.Show("exit code: 0x" + sendEmail64.ExitCode.ToString("X"));
c#
process
c++-cli
mapi
asked on Stack Overflow Jan 10, 2021 by Orlando • edited Jan 10, 2021 by Alan Birtles

1 Answer

0

Ever since the common Office runtime (licensing, performance monitoring, etc.) was moved into the MAPI system (the common MSO runtime gets initialized when you call MAPIInitialize), if you app exits quickly enough, MSO runtime does not have enough time to completely initialize when it attempts to shut down, resulting in a crash.

MS is working on a fix, which should be available soon.

answered on Stack Overflow Jan 10, 2021 by Dmitry Streblechenko • edited Jan 11, 2021 by Dmitry Streblechenko

User contributions licensed under CC BY-SA 3.0