QProcess :: Разбился.Как избежать сообщения о падении Windows 10 внешней программы - PullRequest
0 голосов
/ 12 мая 2018

Предположим, что мы хотим запустить приложение внешней командной строки, например, "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 голосов
/ 12 мая 2018

Как указал Мохаммад Канан , мы можем отключить диалог ошибок в разделе редактирования реестра, но в этом случае для Windows 10 pro он находится под:

HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows \ Отчеты об ошибках Windows

Найдите значение с именем

DontShowUI

или добавьте новое значение DWORD с этим именем, если оно не существует. Значение этого ключа по умолчанию равно 0. Дважды щелкните его, чтобы изменить, измените значение на 1 и сохраните

0 голосов
/ 14 мая 2018

Звоните 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) в целевом процессе.Для этого вы можете создать .DLL, который включает этот вызов, и внедрить его в целевой процесс .

Целевой дескриптор процесса может быть получен следующим образом:

HANDLE getHandle(const QProcess *process) {
  auto pid = process->processId();
  return pid->hProcess;
}
0 голосов
/ 12 мая 2018

Возможность исключить приложение из автоматической отладки под окнами, что позволяет избежать появления всплывающего окна отладки.

Под окнами отредактируйте раздел реестра:

HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows 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 Настройка автоматической отладки

Для Ubuntu его следует контролировать, учитывая, что процесс убит.

...