System.Diagnostics.Process 退出代码是 0xc0000005,而不是一台特定机器上的 0

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

我难住了...

我们有一个旧的 32 位应用程序正在启动一个 64 位存根应用程序以通过 Outlook 64 发送电子邮件,使用 MapiEmail::Email::SendMail。我应该从存根中返回 0 或 1 作为进程退出代码,但在一台笔记本电脑上我们返回 0xC0000005。即使它仍然成功发送电子邮件。

如果我在存根中注释掉 SendMail 行,我得到的预期 ExitCode 为 0。此外,如果我在存根中显示 SendMail 的结果(通过 System::Windows::Forms::MessageBox::Show),[= 报告的 ExitCode 27=] 也最终为 0.

我知道我可以完全放弃它,只依赖于某种 ​​return 文件被写入.. 但很想了解发生了什么,以及是否有更容易解决它的方法。例如,我希望有一个神奇的设置可以强制退出代码成为我们的 [Main] 方法 returns,无论 OS 稍后想要它是什么。

这是存根中的主要方法:

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]");
}

这是调用代码(我们的应用程序是 C++,通过互操作调用此 C#)

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"));

自从通用 Office 运行时(许可、性能监控等)被移入 MAPI 系统(通用 MSO 运行时在您调用 MAPIInitialize 时被初始化),如果您的应用退出得足够快, MSO 运行时在尝试关闭时没有足够的时间来完全初始化,从而导致崩溃。

MS 正在修复,应该很快就会可用。