#include #include #include #include #include auto main(int argc, char** argv) -> int { using pipe_handle = void*; auto stdout_read = pipe_handle(); // not needed auto stdout_write = pipe_handle(); // neede to obtain stdout of the child process auto security_attrs = SECURITY_ATTRIBUTES { .nLength = sizeof(SECURITY_ATTRIBUTES), // needed for god knows for .lpSecurityDescriptor = nullptr, // default security options .bInheritHandle = TRUE // child processes inherit this handle }; CreatePipe( &stdout_read, &stdout_write, &security_attrs, 0 // default buffer size for a pipe ); SetHandleInformation(stdout_read, HANDLE_FLAG_INHERIT, 0); // child processes inherit the handle auto start_info = STARTUPINFO { .cb = sizeof(STARTUPINFOA), // needed for god knows for .dwFlags = STARTF_USESTDHANDLES, // uses the pipe handles passed to it .hStdOutput = stdout_write // there's also stderr and stdin if you want to read/write from/to them }; auto proc_info = PROCESS_INFORMATION(); const auto exe_name = TEXT("C://Windows//System32//cmd.exe"); #ifdef UNICODE auto args = const_cast(LR"(/c "dir")"); // needed because CreateProcess needs char* #else auto args = const_cast(R"(/c "dir")"); #endif CreateProcess( exe_name, // executable name relative to the parent path, ignores env args, // arguments in a string form nullptr, // security attributes for the child process nullptr, // security attributes for the child process' thread TRUE, // should the process inherit the handles, yes you have to set this information in 123123 places for some reason 0, // idk some flags nullptr, // the child process uses the parent processes enviroment variables nullptr, // the child process uses the parent processes current directory &start_info, &proc_info // proc_info receives the information about the new process, out argument ); CloseHandle(stdout_write); // closing it sothat it doesn't block while using ReadFile; not needed std::cout << "Child process PID and TID: " << proc_info.dwProcessId << ", " << proc_info.dwThreadId << "\n\n"; // reading from the process auto output = std::vector(4096); auto bytes_read = DWORD(0); while(true) { auto bytes_avaiable = DWORD(0); const auto success = ReadFile( stdout_read, // device handle, here a pipe output.data() + bytes_read, // pointer to the buffer 4096 - bytes_read, // buffer size &bytes_avaiable, // the number of bytes read, out argument nullptr // not needed ); if((not success) or (bytes_avaiable == 0)) break; bytes_read += bytes_avaiable; std::cout << "Bytes read: " << bytes_avaiable << '\n'; } std::cout << "The whole process output (" << bytes_read << " total bytes read)" << ": \n[\n"; std::ranges::copy(output, std::ostream_iterator(std::cout)); std::cout << "]\n"; WaitForSingleObject(proc_info.hProcess, INFINITY); // waits till the child process exits CloseHandle(stdout_read); // closes the handle }