传递给CreateProcess的参数没有像我预期的那样被解析

时间:2012-03-13 19:14:06

标签: c++ windows winapi createprocess

我正在尝试使用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()函数的内部可能会改变“无论什么”,而不会踩到其他内存。至少,当我这样做时,这是我的想法。

4 个答案:

答案 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,...);