Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как читать из консоли?


Автор: Гость_Чайник 16.10.2004, 07:39
Привет всем!

Можно ли GUI-проге запустить дочерний консольный процесс (не свой консоль!) и из него (из его STD_OUTPUT_HANDLE) читать данные?
Помогите, плиз!

Автор: chipset 16.10.2004, 16:09
CreateProcess в LPSTARTUPINFO есть параметр что то типа output, туда пропиши хэндл файла
и синхронизься с ним smile.gif
Добавлено @ 16:10
Всё остальное RTFMSDN

Автор: Гость_Чайник 16.10.2004, 16:50
chipset , cделал я как ты и говорил, но... :’( при первом же нажатии клавиши прога console.exe падает. А почему – хз. Помоги, плиз!
Код

void CHiDlg::OnBnClickedOk()
{
HANDLE h1 = ::CreateFile ("e:\\cout.txt", GENERIC_ALL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ASSERT(h1 != INVALID_HANDLE_VALUE);
HANDLE h2 = ::CreateFile ("e:\\cin.txt", GENERIC_ALL, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ASSERT(h2 != INVALID_HANDLE_VALUE);

STARTUPINFO srt;
memset(&srt, 0, sizeof(srt));
srt.cb = sizeof(srt);
srt.dwFlags = STARTF_USESTDHANDLES;
srt.hStdError = srt.hStdOutput =h1;
srt.hStdInput = h2;
PROCESS_INFORMATION inf;
memset(&inf, 0, sizeof(inf));
CreateProcess(NULL, "E:\\console.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL,&srt, &inf);
}


Автор: chipset 16.10.2004, 17:06
srt.dwFlags = STARTF_USESTDHANDLES;
зачем?

Автор: Гость_Чайник 16.10.2004, 18:58
без него тоже никакого результата :stena

Автор: p0s0l 16.10.2004, 19:42
Я делал это через трубы :) (pipes)
Вместо CreateFile сделай CreatePipe - получишь 2 хэндла - для ввода и вывода.
Их и укажи в srt. При создании pipe'а, нужно обязательно указать SECURITY_ATTRIBUTES. Будет примерно так:
Код
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

HANDLE hread, hwrite;
CreatePipe (&hread, &hwrite, &sa, 0);

   STARTUPINFO srt;
   memset(&srt, 0, sizeof(srt));
   srt.cb = sizeof(srt);
   srt.dwFlags = STARTF_USESTDHANDLES;
   srt.hStdError = srt.hStdOutput =hwrite;
   srt.hStdInput = hread;
   PROCESS_INFORMATION inf;
   memset(&inf, 0, sizeof(inf));
   CreateProcess(NULL, "E:\\console.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL,&srt, &inf);

Читать из пайпа - ReadFile...

Автор: Гость_Чайник 17.10.2004, 10:53
Пишу в pipe так, но ничего консоль не получает, хотя WriteFile возвращает TRUE. Я что-то не так делаю, но что именно?
Код

Sleep(2000);
DWORD dw = 0;
char buf[] = "Hello!";
while(!WriteFile (hwrite, buf, strlen(buf), &dw, 0));;
MessageBox("Ok");


Автор: p0s0l 17.10.2004, 12:49
Дык, надо было сразу сказать, что ты кроме того, что хочешь заполучить вывод, еще хочешь и ввод свой сделать...
В таком случае надо создавать 2 пайпа:
один - для ввода
другой - для вывода
У каждого пайпа, как ты уже замител, есть 2 хэндла: один - для записи в пайп, другой - для чтения из пайпа

Код
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;

HANDLE hin_read, hin_write, hout_read, hout_write;
CreatePipe (&hin_read, &hin_write, &sa, 0);
CreatePipe (&hout_read, &hout_write, &sa, 0);

   STARTUPINFO srt;
   memset(&srt, 0, sizeof(srt));
   srt.cb = sizeof(srt);
   srt.dwFlags = STARTF_USESTDHANDLES;
   srt.hStdError = srt.hStdOutput = hout_write;
   srt.hStdInput = hin_read;
   PROCESS_INFORMATION inf;
   memset(&inf, 0, sizeof(inf));
   CreateProcess(NULL, "E:\\console.exe", NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL,&srt, &inf);

// к примеру, пишем какую-то инфу:

 DWORD dw = 0;
 char buf[] = "Hello!";
 WriteFile (hin_write, buf, strlen(buf), &dw, 0); // обрати внимание на то, что используется хэндл ЗАПИСИ ВХОДНОГО пайпа

// ждём, пока консольное приложение завершится (конечно, ждать необязательно)
 WaitForSingleObject(inf.hProcess, INFINITE);

// теперь читаем из консоли:
 char buffer[1024];
 do {
   ReadFile (hout_read, &buffer, 1024, &dw, 0);
// в buffer - часть вывода консоли, можно куда-нить вывести
 } while (dw == 1024); // если dw==1024, то вероятно, еще что-то есть, что можно прочитать из консольного вывода
 

Автор: Гость_Чайник 17.10.2004, 15:06
p0s0l , СПАСИБО!
Теперь работает, я всё понял :)
Вот токо одна беда - в консоль отправляется из pipe все то, что стоит до первого пробела!!!

Автор: p0s0l 17.10.2004, 15:23
Пожалуйста! :)
Цитата
Вот токо одна беда - в консоль отправляется из pipe все то, что стоит до первого пробела!!!
А это как ? Приведи код, тогда посмотрим, в чём там трабл...

Автор: Guest 17.10.2004, 18:20
я уже сам разобрался :)
надо было в консоли принимать данные примерно так:
Код
cin.getline ( buf, 50, '\n');


P.S. На этом форуме сидят профи

СПАСИБО!!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)