另外,QProcess ::坠毁。避免外部程序的Windows 10崩溃消息

时间:2018-05-12 08:38:54

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

假设我们要运行外部命令行应用程序,例如" 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);
}

我们关闭此消息后会发生崩溃:

enter image description here

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

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

3 个答案:

答案 0 :(得分:0)

在您的流程中致电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;
}

答案 1 :(得分:-1)

可以在Windows下从自动调试中排除应用程序,从而远离调试弹出窗口。

在Windows下编辑注册表项:

  

HKEY_LOCAL_MACHINE \ SOFTWARE \微软\窗户   NT \ CURRENTVERSION \的AeDebug

REG_DWORD值添加到AutoExclusionList子项,其中名称是可执行文件的名称,值为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,应该控制它,因为该进程被终止。

答案 2 :(得分:-1)

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

  

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

找到名为

的值
  

DontShowUI

或添加具有此名称的新DWORD值(如果它不存在)。此键的默认值为0.双击它进行编辑,将值更改为1并保存