Вывод на консоль программы Grab - PullRequest
3 голосов
/ 09 июля 2011

Я создаю программу сетевого администрирования для компании, с которой я сейчас работаю по контракту (не имеет значения, я полагаю)

В рамках программы мне бы хотелось иметь консоль / telnet (тип) клон.У меня есть рабочая система каталогов, где я могу по существу читать все файлы в каталогах и изменять каталоги.У меня также есть простой протокол FTP.Однако я хотел бы произвольно говорить с разными программами со стандартными процедурами ввода / вывода программно.Я не против методов внедрения DLL и других методов, так как это доброкачественная программа.Если возможно, было бы здорово, если бы я мог просто легко использовать консоль.(system (), возможно, будет работать, однако это не позволяет продолжить общение или чтение из вывода)

Пока я думаю о том, чтобы взять переменные среды PATH и использовать их для команд std (ipconfig, netstat)и т. д.) Моя сетевая библиотека облегчает общение, но я просто не знаю, как взаимодействовать с консолью программы ...

TL; DR:

AreСуществуют ли предопределенные способы стандартного консольного взаимодействия между программами?

Ответы [ 3 ]

5 голосов
/ 09 июля 2011

Как упоминал Джерри, вы ищете трубу ( CreatePipe ).На самом деле два из них - один для ввода и один для вывода.Затем вы создаете новый процесс с ним, установленным как stdin / stdout / stderr в STARTUPINFO , переданном в CreateProcess .Затем вы можете использовать WriteFile , ReadFile , PeekNamedPipe и друзей для общения.

Полный пример доступен на MSDN:

http://msdn.microsoft.com/en-us/library/ms682499(v=vs.85).aspx

И убедитесь, что вы не попадаете в эти распространенные ловушки (которые, к счастью, Рэймонд Чен только что случайно задокументировал):

PS, это гораздо проще в Python с модулем подпроцесс .

5 голосов
/ 09 июля 2011

Самым простым способом обычно является порождение дочерней программы с _popen.Это даст вам ручку для записи в стандартный ввод ребенка или чтения из стандартного вывода ребенка.

Если вам нужно сделать и то, и другое, все становится намного ужаснее в спешке.Обычно вам приходится создавать анонимные каналы самостоятельно и указывать их в вызове CreateProcess, что, честно говоря, является болью.

2 голосов
/ 13 августа 2011

Хорошо, я узнал ТОННО об этом в последнее время.А вот некоторая информация, которая может оказаться полезной для некоторых людей =]

Код для создания процесса с использованием каналов / дескрипторов файлов в виде Stdin / out / err:

    STARTUPINFO startInfo;

    PROCESS_INFORMATION procInfo;

    memset((void*) &startInfo, 0, sizeof (startInfo));
    memset((void*) &procInfo,  0, sizeof (procInfo));

    startInfo.cb = sizeof (startInfo);
    startInfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);

    startInfo.wShowWindow = SW_HIDE; //No Console Window, Thanks.

    startInfo.hStdInput   = (HANDLE)inHandle;
    startInfo.hStdOutput  = (HANDLE)outHandle;
    startInfo.hStdError   = (HANDLE)errHandle;

    char* pe = "cmd\0"; 
    //This is the program to execute (eg: c:\\Windows\\System32\\cmd.exe)

    CreateProcess(NULL,pe,NULL,NULL,TRUE,0,NULL,NULL,&startInfo,&procInfo);

    return procInfo.hProcess;

сейчасвсе это прекрасно и здорово, но есть еще один маленький кусочек информации, который действительно помог мне здесь.Вы можете использовать файловые дескрипторы для своих дескрипторов (in / out / err), чтобы вы могли использовать прямые сокеты без изменений, и у вас будет прямой доступ к входу и выходу процесса.

Итак, мой текущий метод создания скрытой консоли - это локально соединить два сокета, а затем использовать один из них в качестве дескрипторов stdInput && stdOutput && stdError для дочерней программы, которая вызывает cmd.Это быстро и легко.

Если вы не знаете, как соединить несколько розеток, просто загляните в руководство beej

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...