Found the below snippet here on SO: https://stackoverflow.com/a/35658917/9265719.
It executes a command without creating a window. CreateProcessA()
returns TRUE
for cmd.exe
but for any program in C:\Program Files(x86)\Windows Kits\10\Debuggers\x64\
it returns FALSE
and GetLastError()
returns 2 (ERROR_PATH_NOT_FOUND
).
Why is it failing to create a process for programs in this directory?
#include <iostream>
#include <windows.h>
//
// Execute a command and get the results. (Only standard output)
//
std::string ExecCmd(
char cmd[] // [in] command to execute
)
{
std::string 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))
return strResult;
STARTUPINFOA si = { sizeof(STARTUPINFOA) };
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 = ::CreateProcessA(NULL, cmd, NULL, NULL, TRUE,
CREATE_NO_WINDOW, NULL, NULL, &si, &pi);
if (!fSuccess)
{
DWORD dw = GetLastError();
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
return strResult;
}
bool bProcessEnded = false;
for (; !bProcessEnded;)
{
// Give some timeslice (50 ms), 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 (;;)
{
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;
if (!::ReadFile(hPipeRead, buf, min(sizeof(buf) - 1, dwAvail), &dwRead, NULL) || !dwRead)
// Error, the child process might ended
break;
buf[dwRead] = 0;
strResult += buf;
}
} //for
CloseHandle(hPipeWrite);
CloseHandle(hPipeRead);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return strResult;
} //ExecCmd
int main()
{
//char cmd[1000] = R"("C:\WINDOWS\system32\cmd.exe")";
char cmd[1000] = R"("C:\Program Files(x86)\Windows Kits\10\Debuggers\x64\cdb.exe")";
std::string op = ExecCmd(cmd);
std::cout << op.c_str();
}