我正在尝试使用devcon.exe来检查各种硬件的状态。在示例中,我正在尝试检查我的SATA HBA状态,但是devcon正在抱怨它。这是代码:
int main(int argc, char** argv) {
std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00");
char* pCmdLine(new char[cmdLine.length() + 10]);
memset(pCmdLine, 0, cmdLine.length() + 10);
for(int i(0); i < cmdLine.length(); i++)
pCmdLine[i] = cmdLine.at(i);
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi = {0};
if(!CreateProcess(NULL, pCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
std::cout << "Create child process failed. Error code: "
<< GetLastError() << std::endl;
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
问题在于,当执行上述操作时,devcon抱怨说“找不到匹配的设备”。但是,如果我将该命令行从调试器复制/粘贴到我的命令提示符并按Enter键(或者当然删除调试器围绕它的所有包含引号),该命令将按预期完美地执行。
我在处理字符串时出错了什么?以上是在MSDN上读取CreateProcess()文档的结果(发现不一定需要第一个参数,而cmd args根本不应该去那里)。我分配10个额外字节的内存来复制字符串的原因是,在CreateProcess()函数的内部可能会改变“无论什么”,而不会踩到其他内存。至少,当我这样做时,这是我的想法。
答案 0 :(得分:5)
Command line metacharacters are parsed by the command processor。特别是您使用^
来阻止CMD.EXE在符号处打破命令。但是您正在绕过CMD.EXE直接执行该程序。因此,^
会传递给被他们搞糊涂的devcon.exe
。
解决方案:删除^
个字符。
你的问题实际上与你的头衔相反。传递给CreateProcess
的命令行将直接传递给应用程序,与您指定的完全相同。
答案 1 :(得分:1)
std::string cmdLine("\"C:\\Users\\afalanga\\Documents\\Visual Studio 2010\\Projects\\PlayGround\\Debug\\devcon.exe\" status PCI\\VEN_8086^&DEV_3A22^&SUBSYS_75201462^&REV_00
大概有^
个插入符号来自命令行解释器中输入的命令中的残留,用于关闭&
的特殊含义。
只需删除插入符号。
另请注意,您当前的代码会泄漏内存。
为避免这种情况,请执行此操作。
string commandLineArg = cmdLine + '\0';
... CreateProcess( 0, &commandLineArg[0], ... )
答案 2 :(得分:0)
你可以尝试这样:
CreateProcess(NULL, pCmdLine.c_str(), ...);
答案 3 :(得分:0)
我用过:
TCHAR var[] = _T(" C:\\filepathe\\foo");
CreateProcess(NULL, var,...);