| 425 | } |
| 426 | |
| 427 | std::tuple<int, std::string, std::string > SystemShell(const std::string & command, bool useCmd, bool blockOnExecution) |
| 428 | { |
| 429 | assert(blockOnExecution); // non blocking not implemented |
| 430 | |
| 431 | int resultValue; |
| 432 | std::string resultString; |
| 433 | std::string resultErrorString; |
| 434 | |
| 435 | #if defined(_WIN32) |
| 436 | SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; |
| 437 | HANDLE hReadOut = NULL, hWriteOut = NULL, hReadErr = NULL, hWriteErr = NULL; |
| 438 | |
| 439 | // Create pipes for stdout and stderr |
| 440 | CreatePipe(&hReadOut, &hWriteOut, &sa, 0); |
| 441 | CreatePipe(&hReadErr, &hWriteErr, &sa, 0); |
| 442 | |
| 443 | // Ensure the read handles are not inherited |
| 444 | SetHandleInformation(hReadOut, HANDLE_FLAG_INHERIT, 0); |
| 445 | SetHandleInformation(hReadErr, HANDLE_FLAG_INHERIT, 0); |
| 446 | |
| 447 | // useful for debugging |
| 448 | bool showConsole = false; |
| 449 | |
| 450 | STARTUPINFOA si = { 0 }; |
| 451 | PROCESS_INFORMATION pi = { 0 }; |
| 452 | si.cb = sizeof(si); |
| 453 | if (!showConsole) |
| 454 | { |
| 455 | si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; |
| 456 | si.hStdOutput = hWriteOut; |
| 457 | si.hStdError = hWriteErr; |
| 458 | si.wShowWindow = SW_HIDE; |
| 459 | } |
| 460 | |
| 461 | std::string cmd = command; |
| 462 | if (useCmd) |
| 463 | cmd = "cmd /C \"" + command + "\""; |
| 464 | BOOL success = CreateProcessA( NULL, cmd.data(), NULL, &sa, TRUE, showConsole?CREATE_NEW_CONSOLE:CREATE_NO_WINDOW, NULL, NULL, &si, &pi ); |
| 465 | CloseHandle(hWriteOut); |
| 466 | CloseHandle(hWriteErr); |
| 467 | |
| 468 | if (success) |
| 469 | { |
| 470 | std::string output; |
| 471 | char buffer[4096]; |
| 472 | DWORD bytesRead; |
| 473 | int loopCounter = 0; |
| 474 | |
| 475 | while(true) |
| 476 | { |
| 477 | DWORD waitResult = WaitForSingleObject(pi.hProcess, 50); |
| 478 | |
| 479 | DWORD available = 0; |
| 480 | |
| 481 | // Read stdout |
| 482 | while (PeekNamedPipe(hReadOut, NULL, 0, NULL, &available, NULL) && available > 0) |
| 483 | { |
| 484 | if (ReadFile(hReadOut, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) |
no test coverage detected