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

问题描述

我被难住了...

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

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

我知道我可以完全放弃这个,只依靠某种返回文件被写入..但很想了解发生了什么,以及是否有更容易解决它的方法。例如,我希望有一个神奇的设置,可以强制退出代码成为我们的 [Main] 方法返回的内容,而不管以后操作系统想要它是什么。

这是存根中的主要方法:

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 正在着手修复,应该很快就会推出。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...