DWORD _res = 22;
QString strResult;
HANDLE hPipeRead, hPipeWrite;
SECURITY_ATTRIBUTES saAttr = { sizeof(SECURITY_ATTRIBUTES) };
saAttr.bInheritHandle = TRUE; //Pipe handles are inherited by child process.
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe to get results from child's stdout.
if ( !CreatePipe(&hPipeRead, &hPipeWrite, &saAttr, 0) ) {
qCritical() << QObject::tr("Cannot create thread");
return;
}
qDebug() << QObject::tr("Thread successfully created");
STARTUPINFO si = { sizeof(STARTUPINFO) };
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.hStdOutput = hPipeWrite;
si.hStdError = hPipeWrite;
si.wShowWindow = SW_HIDE; // Prevents cmd window from flashing. Requires STARTF_USESHOWWINDOW in dwFlags.
PROCESS_INFORMATION pi = { 0 };
BOOL fSuccess = CreateProcessW( NULL, (LPWSTR)command.toStdWString().c_str(), NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (! fSuccess)
{
CloseHandle( hPipeWrite );
CloseHandle( hPipeRead );
qCritical() << QObject::tr("Cannot create procces");
return;
}
qDebug() << QObject::tr("Proccess successfully created");
int i = 0;
bool bProcessEnded = false;
for (; !bProcessEnded ;)
{
// Give some timeslice (50ms), so we won't waste 100% cpu.
bProcessEnded = WaitForSingleObject( pi.hProcess, 50) == WAIT_OBJECT_0;
// Even if process exited - we continue reading, if there is some data available over pipe.
for (;;)
{
i++;
char buf[1024];
DWORD dwRead = 0;
DWORD dwAvail = 0;
if (!::PeekNamedPipe(hPipeRead, NULL, 0, NULL, &dwAvail, NULL))
break;
if (!dwAvail) // no data available, return
break;
DWORD temp = sizeof(buf) - 1;
if (!::ReadFile(hPipeRead, buf, qMin(temp, dwAvail), &dwRead, NULL) || !dwRead)
// error, the child process might ended
break;
buf[dwRead] = 0;
strResult += buf;
}
} //for
if(GetExitCodeProcess(pi.hProcess, &_res) == 0) _res = GetLastError();
CloseHandle( hPipeWrite );
CloseHandle( hPipeRead );
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );