【发布时间】:2021-06-19 23:24:39
【问题描述】:
在 SO 上找到以下 sn-p: https://stackoverflow.com/a/35658917/9265719.
它执行命令而不创建窗口。 CreateProcessA() 为 cmd.exe 返回 TRUE,但对于 C:\Program Files(x86)\Windows Kits\10\Debuggers\x64\ 中的任何程序,它返回 FALSE 和 GetLastError() 返回 2 (ERROR_PATH_NOT_FOUND)。
为什么无法为该目录下的程序创建进程?
#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();
}
【问题讨论】:
-
通常是 Files 和 (x86) 之间的空格 - 所以 Program Files (x86) 但不是 程序文件(x86)
-
一般系统报错是正确的,就在这里。
-
如果我遇到这样的错误,我总是尝试将相同的路径粘贴到资源管理器中作为快速的健全性检查,通常会有一个你看不到的错字,资源管理器会拒绝路径也是
标签: c++ windows winapi createprocess