Выполнить процесс командной строки с C ++ и изящно закрыть на Windows 10 - PullRequest
0 голосов
/ 05 февраля 2020

Как часть моего автоматизированного набора тестов, у меня есть программа C ++ (A), которая выполняет командную строку Process (B), используя CreateProcess().

Процесс завершается только тогда, когда он получает сигнал SIGINT (по независящим от меня причинам).

Я могу завершить процесс (B) из (A), используя CloseHandle() и / или TerminateProcess(), однако это не вызывает деструктор (B), предотвращающий его изящное закрытие (запись материала на диск и закрытие соединений с БД) и приводящий к сбою тестов.

Каков наилучший подход к изящному закрытию (B), позволяя очистить его после себя? Должен ли я использовать вспомогательный исполняемый файл с IP C, удаленный поток ...?

Я пробовал решения в следующих вопросах SA:

Редактировать: @Remy Лебо прав, мне следовало написать код:

Текущий подход:

Закрыть дескриптор процесса. Это немедленно убивает процесс.

PROCESS_INFORMATION process_info;
... // CreateProcess()
CloseHandle(process.hProcess);
CloseHandle(process.hThread);

Подход 2:

Отсоедините текущую консоль, а затем снова подключите. Это приводит к сбою исходного набора тестов.

PROCESS_INFORMATION process_info;
... // CreateProcess
DWORD thisConsoleId = GetCurrentProcessId();
bool consoleDetached = (FreeConsole() != FALSE);
if (AttachConsole(process_info.dwProcessId)) {
  std::cout << "Attached process to console" << std::endl;
  SetConsoleCtrlHandler(NULL, true);
  if (GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)) {
    std::cout << "Ctrl-c sent to process" << std::endl;
  } else {
    std::cout << "Could not send ctrl-c (" << GetLastError() << ")" << std::endl;
  }
  FreeConsole();
} else {
    std::cout << "Unable to attach process to console (" << GetLastError() << ")" << std::endl;
}

if (consoleDetached) {
  // Create a new console if previous was deleted by OS
  if (AttachConsole(thisConsoleId)) {
    int errorCode = GetLastError();
    // 31=ERROR_GEN_FAILURE
    if (errorCode == 31) {
      AllocConsole();
    }
  }
}

Подход 3:

Присоединение к консоли без освобождения. Это убивает все, включая набор тестов.

PROCESS_INFORMATION process_info;
... // CreateProcess
AttachConsole(process_info.dwProcessId);
SetConsoleCtrlHandler(NULL, TRUE);
GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0);
...