2012-04-12 4 views
3

Я пытаюсь создать функцию, которая будет порождать экземпляр программы, а затем передать некоторые данные в его STDIN, а затем прочитать вывод процесса с использованием C++. Я посмотрел пример MSDN, расположенный here, который довольно запутан для меня, и когда я пытаюсь использовать этот пример, я получаю некоторые неприятные коды ошибок, и это не сработает.Запись в процесс STDIN через окна Windows

HANDLE hWriteOUT, hReadOUT, hWriteIN, hReadIN; 
    SECURITY_ATTRIBUTES saPipe = {0}; 
    PROCESS_INFORMATION procInfo = {0}; 
    STARTUPINFO procSi; 
    DWORD dwWritten, dwRead; 
    char buf[512]; 

    saPipe.nLength = sizeof(SECURITY_ATTRIBUTES); 
    saPipe.bInheritHandle = TRUE; 
    saPipe.lpSecurityDescriptor= NULL; 
    CreatePipe(&hReadOUT, &hWriteOUT, &saPipe, 0); 
    SetHandleInformation(hReadOUT, HANDLE_FLAG_INHERIT, 0); 
    CreatePipe(&hReadIN, &hWriteIN, &saPipe, 0); 
    SetHandleInformation(hReadIN, HANDLE_FLAG_INHERIT, 0); 

    ZeroMemory(&procSi, sizeof(STARTUPINFO)); 
    procSi.cb = sizeof(STARTUPINFO); 
    procSi.hStdError = hWriteOUT; 
    procSi.hStdOutput = hWriteOUT; 
    procSi.hStdInput = hReadIN; 
    procSi.dwFlags |= STARTF_USESTDHANDLES; 

    CreateProcess(NULL, "cmd", NULL, NULL, TRUE, 0, NULL, NULL, &procSi, &procInfo); 
    //Gives me an error code of 18 but returns a 1 when a 0 indicates failure. 

    WriteFile(hWriteIN, "notepad", sizeof("notepad"), &dwWritten, NULL); 
    cout << GetLastError(); //This gives me error code 18 (ERROR_NO_MORE_FILES) 
    ReadFile(hReadOUT, buf, 512, &dwRead, NULL); 
    cout << buf; //This prints "Microsoft Windows [version 6.1.7601] 
    CloseHandle(hWriteIN); 

код не в трубу строки «блокнот» в cmd.exe, но успех в запуске командной оболочки. Если я смотрю в диспетчере задач, появляется несколько экземпляров командной строки, но не блокноты. Кроме того, функция ReadFile() является единственной, которая, казалось, сработала, но она даже не читает из процесса с каналами (блокнот, который должен был быть порожден) вместо этого, это чтение из CMD. И что еще хуже, это усекает все, кроме первой строки, которую он читает! (CMD печатает «Microsoft Windows ... \ n Авторское право ... \ n C: \ Users \ Foo> ... \ n", но `ReadFile() только захватывает первую строку)

ответ

5

Код ведет себя так, как ожидалось. Есть несколько вещей, которые вы, кажется, недоразумения:

1) Вам нужно отправить ENTER ("\ n") в конце команды, если вы хотите запустить cmd.exe. Обычно желательно указать команду, которую вы хотите запустить в CreateProcess, например, вы можете указать «cmd/c notepad» в качестве командной строки вместо «cmd».

2) Вы подключили свои трубы к стандартным входам и выводам процесса cmd.exe, поэтому, конечно, вы видите вывод из этого процесса. Если вы не хотите видеть вывод из cmd.exe, не запускайте его; запустите приложение, которое вы хотите напрямую, например, вы можете указать «блокнот» в качестве командной строки для запуска.

3) При чтении из трубы ReadFile возвращает только один блок данных за раз, поэтому вам нужно вызвать его в цикле.

4) Блокнот - это процесс графического интерфейса, поэтому он не использует stdin или stdout в любом случае. Предположительно, это был просто плохо подобранный пример, и вы действительно хотите запустить приложение из командной строки?

5) Если не указано иное, код ошибки (возвращаемый GetLastError) имеет смысл только тогда, когда функция не удалась. Ни одна из функций, которые вы используете, является исключением из этого случая, поэтому нет необходимости проверять код ошибки, если функция не возвращает ноль, чтобы указать, что она не выполнена.

2

Я знаю, что слишком поздно ответить на этот вопрос, но с вашим кодом есть что-то еще не так. кажется SetHandleInformation(hReadOUT, HANDLE_FLAG_INHERIT, 0); и SetHandleInformation(hReadIN, HANDLE_FLAG_INHERIT, 0); сломают вещи. Я не уверен, почему, но после попытки запустить ваш код, cmd не смог прочитать значения из pipe, пока я не удалю эти две строки.

+0

Я пропустил этот. Первый вызов должен быть в порядке, но второй должен быть для 'hWriteIN', а не' hReadIN', так как дескриптор 'hReadIN' должен быть унаследован подпроцессом. –

Смежные вопросы