C++ как сделать ожидание завершения процесса
Моя цель сделать так, чтобы программа начинала выполнять дальнейший код только после того, как cmd.exe выполнит команду и умрёт. Так, чтобы после смерти процесса cmd.exe программа начинала выполнять команду cout << "test" << endl;
Сам код:
#include <iostream>
#include "windows.h"
using namespace std;
int main()
{
ShellExecuteW(0, L"open", L"cmd.exe", L"/C pause", 0, SW_SHOW);
cout << "test" << endl;
}
Когда я компилирую пример от user7860670
У меня вылетает компилятор с ошибкой:
if ($?) { g++ writer.cpp -o writer } ; if ($?) { .\writer } D:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\mattc\AppData\Local\Temp\cc7ezUqJ.o:writer.cpp:(.text+0x23): undefined reference to '__imp_CoInitializeEx' D:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\mattc\AppData\Local\Temp\cc7ezUqJ.o:writer.cpp:(.text+0x17f): undefined reference to '__imp_CoUninitialize' collect2.exe: error: ld returned 1 exit status
Ответы (4 шт):
На самом деле так делать нельзя. В данном случае, ты выполняешь запуск через Shell, не имея хендла на процесс.
Ты, конечно, можешь сделать что-то типо фиксации процесса через проверку запущен ли ещё этот процесс, но если ты будешь проверять cmd.exe, то в системе таких процессов может быть несколько. В таком случае алгоритм будет не полноценным.
Для нормальной работы тебе нужно использовать WinAPI. А именно - CreateProcess. https://learn.microsoft.com/en-us/windows/win32/procthread/creating-processes
Пример использования ShellExecuteExW с WaitForSingleObject:
#define WIN32_LEAN_AND_MEAN
#include <combaseapi.h>
#include <shellapi.h>
#include <Windows.h>
#include <iostream>
#include <memory>
#include <cstdlib>
int main()
{
if (not SUCCEEDED(::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED bitor COINIT_DISABLE_OLE1DDE)))
{
::std::cerr << "CoInitializeEx failed" << ::std::endl;
::std::exit(EXIT_FAILURE);
}
{
SHELLEXECUTEINFOW info
{
.cbSize{sizeof(info)}
, .fMask{SEE_MASK_NOCLOSEPROCESS}
, .lpVerb{L"open"}
, .lpFile{L"cmd.exe"}
, .lpParameters{L"/C pause"}
, .nShow{SW_SHOW}
};
if ((FALSE == ::ShellExecuteExW(::std::addressof(info))) or (not info.hProcess))
{
::std::cerr << "ShellExecuteExW failed" << ::std::endl;
::std::exit(EXIT_FAILURE);
}
if (WAIT_OBJECT_0 != ::WaitForSingleObject(info.hProcess, INFINITE))
{
::std::cerr << "WaitForSingleObject failed" << ::std::endl;
::std::exit(EXIT_FAILURE);
}
::CloseHandle(info.hProcess);
}
::CoUninitialize();
::std::cout << "done" << ::std::endl;
::std::system("pause");
return EXIT_SUCCESS;
}
Могу предложить решение с использованием библиотеки cstdlib:
#inclide <iostream>
#include <cstdlib>
using namespace std;
int main()
{
system("cd /d C:/Windows/System32 && cmd.exe");
cout << "test" << endl;
}
Запускается командная строка с правами администратора, код самой программы не выполняется до закрытия командной строки командой "exit".
Я так и не смог завершить проект на C++, но я сделал точно такой же проект на Rust. Rust более легче и эффективнее в этом плане, т. к. получилось все коротко и сам раст быстрее, чем C++.