Аргументы, передаваемые в CreateProcess, не анализируются, как я ожидал - PullRequest
1 голос
/ 13 марта 2012

Я пытаюсь использовать 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 жалуется, что «не найдено подходящих устройств». Тем не менее, если я скопирую / вставлю эту командную строку из отладчика в мою командную строку и нажму клавишу ввода (или, конечно, удалив все заключающие в кавычки, которые ставит ее отладчик), команда выполнится идеально, как и ожидалось.

Что я не так делаю в передаче строки? То, что выше, является результатом чтения документации CreateProcess () на MSDN (выяснилось, что первый аргумент не обязательно нужен, и аргументы cmd вообще не должны идти туда). Причина, по которой я выделяю 10 дополнительных байтов памяти для копирования строки, заключается в том, что «что угодно» может измениться в кишках функции CreateProcess (), и это может произойти без расторжения в другой памяти. По крайней мере, так я думал, когда делал это.

Ответы [ 4 ]

5 голосов
/ 13 марта 2012

Метасимволы командной строки анализируются командным процессором . В частности, вы используете ^, чтобы CMD.EXE не ломал команду в амперсанде. Но вы выполняете программу напрямую, минуя CMD.EXE. Следовательно, ^ проходит до devcon.exe, которого они смущают.

Решение: удалить символы ^.

Ваша проблема на самом деле противоположна вашему названию. Командная строка, которую вы передали CreateProcess, передается непосредственно в приложение в точности так, как вы ее указали .

1 голос
/ 13 марта 2012
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], ... )
0 голосов
/ 25 мая 2016

Я использовал:

TCHAR var[] = _T(" C:\\filepathe\\foo");

CreateProcess(NULL, var,...);
0 голосов
/ 13 марта 2012

Можете ли вы попробовать так:

CreateProcess(NULL, pCmdLine.c_str(), ...);

...