【问题标题】:QProcess::Crashed. Avoiding Windows 10 crash message of external programQProcess::崩溃。避免外部程序的 Windows 10 崩溃消息
【发布时间】:2018-10-22 13:57:09
【问题描述】:

假设我们要运行外部命令行应用程序,例如“dir”并假设它崩溃了:

namespace util
{

        bool execChildProcess(const std::string & cmd,  std::string & cmdOutput)
        {
           QProcess process;
           QString qStrCmd = QString::fromStdString(cmd);
           process.start(qStrCmd);

           if(process.exitStatus() == QProcess::Crashed )
           {
               std::cout<<"QProcess::Crashed"<<std::endl;
               process.kill();
           }

           if(process.waitForFinished() && process.exitStatus() == QProcess::NormalExit )
           {
               QString output(process.readAllStandardOutput());
               cmdOutput = output.toStdString();
               std::cout<<"Result: "<<cmdOutput<<std::endl;
               return true;
           }
           else
           {
                   switch(process.error())
                   {
                    case QProcess::FailedToStart :
                        std::cout<<"QProcess::FailedToStart"<<std::endl;
                        break ;
                    case QProcess::Crashed :
                        std::cout<<"QProcess::Crashed"<<std::endl;
                        break ;
                    case QProcess::Timedout:
                        std::cout<<"QProcess::Timedout"<<std::endl;
                        break ;
                    case QProcess::WriteError:
                        std::cout<<"QProcess::WriteError"<<std::endl;
                        break ;
                    case QProcess::ReadError:
                        std::cout<<"QProcess::ReadError"<<std::endl;
                        break ;
                    case QProcess::UnknownError:
                        std::cout<<"QProcess::UnknownError"<<std::endl;
                        break ;
                    }
                    process.kill();
           }
           return false;
        }
}

int main(int argc, char* argv[])
{
        std::string output;
        bool res = util::execChildProcess("dir", output);
}

在我们关闭此消息后捕获崩溃:

消息关闭后,代码会终止进程,但不会在之前终止。

我们如何使用 QProcess 避免此消息(我不知道它是否也发生在 ubuntu 中,但我想要一个跨平台的解决方案,以防它也发生在 ubuntu 中)。

【问题讨论】:

    标签: c++ qt visual-c++ qprocess qtcore


    【解决方案1】:

    在您的过程中致电SetErrorMode(SEM_NOGPFAULTERRORBOX);错误模式由子进程继承。您可以在开始该过程后立即恢复它:

    QProcess process;
    ...
    auto errMode = GetErrorMode();
    SetErrorMode(errMode | SEM_NOGPFAULTERRORBOX);
    connect(&process, &QProcess::stateChanged, [errMode](QProcess::ProcessState state) { if (state != QProcess::Starting) SetErrorMode(errMode); });
    process.start();
    ...
    

    你也可以在目标进程中执行SetErrorMode(SEM_NOGPFAULTERRORBOX)。为此,您可以创建一个包含此调用的.DLLinject it into the target process

    可以通过如下方式获取目标进程句柄:

    HANDLE getHandle(const QProcess *process) {
      auto pid = process->processId();
      return pid->hProcess;
    }
    

    【讨论】:

    • 所有Solutions here 都使用了注册表方法的变体,包括提到的SetErrorMode 解决方案,您认为注册表方法解决方案是否激进?
    【解决方案2】:

    可以将应用程序排除在 windows 下的自动调试之外,从而摆脱调试弹出窗口。

    windows下编辑注册表项:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug

    AutoExclusionList子键中添加一个REG_DWORD值,其中名称为可执行文件的名称,值为1。

    您不必在应用程序中手动执行此操作,您可以像这样使用 Qt QSettings

    QSettings settings("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug",
    QSettings::NativeFormat);
    auto key = settings.childKeys().at(x);
    

    然后你可以使用QSettings::setValue将密钥设置为1。

    MSDN页面下的完整信息和参考Configuring Automatic Debugging

    对于 Ubuntu,应该控制它,因为该进程已被杀死。

    【讨论】:

    • 我使用 regedit 命令行进行了编辑。我需要重新启动 Windows 吗?我只关闭终端。外部程序是一个可移植的二进制文件 .exe,它不是通过 Windows 向导安装在系统中的。它不起作用。
    • 我想不需要重新启动,但我不确定它是否没有安装向导。
    【解决方案3】:

    正如Mohammad Kanan 所指出的,我们可以在编辑注册表项中禁用错误​​对话框,但在这种情况下,对于 Windows 10 pro,它位于:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\Windows 错误报告

    找到名为的值

    DontShowUI

    如果该名称不存在,则添加一个新的 DWORD 值。该键的默认值为0,双击编辑,修改为1并保存

    【讨论】:

      猜你喜欢
      • 2021-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-16
      • 1970-01-01
      • 2015-11-16
      • 2017-03-14
      • 2010-11-04
      相关资源
      最近更新 更多