Как часть моего автоматизированного набора тестов, у меня есть программа 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);