Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Здесь нужно купить рекламу за 25 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Ответ
 
Опции темы
Старый 25.06.2008, 23:40   #1
Артем5555555
Новичок
Джуниор
 
Регистрация: 25.06.2008
Сообщений: 2
По умолчанию перехват консольного ввода\вывода

Доброго времени суток! Заранее прошу прощения, если попал не в тему. Ситуация следующая: есть консольная программка. Запуск с двумя параметрами в командной строке. После запуска программы в консоли вываливается запрос на третий параметр. Так вот нужно из внешней программы (delphi), запустить эту консольную программку с двумя параметрами и подать вовремя требуемый третий параметр. Как это все можно реализовать?
Артем5555555 вне форума   Ответить с цитированием
Старый 26.06.2008, 00:03   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Качаем архив DelphiWorld... там есть многочисленные описание работы с вводом выводом консольных приложений
к примеру: ( для того чтобы "не был" флудом )
Код:
procedure ExecConsoleApp(CommandLine: AnsiString; Output: TStringList; Errors:
  TStringList);
var
  sa: TSECURITYATTRIBUTES;
  si: TSTARTUPINFO;
  pi: TPROCESSINFORMATION;
  hPipeOutputRead: THANDLE;
  hPipeOutputWrite: THANDLE;
  hPipeErrorsRead: THANDLE;
  hPipeErrorsWrite: THANDLE;
  Res, bTest: Boolean;
  env: array[0..100] of Char;
  szBuffer: array[0..256] of Char;
  dwNumberOfBytesRead: DWORD;
  Stream: TMemoryStream;
begin
  sa.nLength := sizeof(sa);
  sa.bInheritHandle := true;
  sa.lpSecurityDescriptor := nil;
  CreatePipe(hPipeOutputRead, hPipeOutputWrite, @sa, 0);
  CreatePipe(hPipeErrorsRead, hPipeErrorsWrite, @sa, 0);
  ZeroMemory(@env, SizeOf(env));
  ZeroMemory(@si, SizeOf(si));
  ZeroMemory(@pi, SizeOf(pi));
  si.cb := SizeOf(si);
  si.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
  si.wShowWindow := SW_HIDE;
  si.hStdInput := 0;
  si.hStdOutput := hPipeOutputWrite;
  si.hStdError := hPipeErrorsWrite;

  (* Remember that if you want to execute an app with no parameters you nil the
     second parameter and use the first, you can also leave it as is with no
     problems.                                                                 *)
  Res := CreateProcess(nil, pchar(CommandLine), nil, nil, true,
    CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, @env, nil, si, pi);

  // Procedure will exit if CreateProcess fail
  if not Res then
  begin
    CloseHandle(hPipeOutputRead);
    CloseHandle(hPipeOutputWrite);
    CloseHandle(hPipeErrorsRead);
    CloseHandle(hPipeErrorsWrite);
    Exit;
  end;
  CloseHandle(hPipeOutputWrite);
  CloseHandle(hPipeErrorsWrite);

  //Read output pipe
  Stream := TMemoryStream.Create;
  try
    while true do
    begin
      bTest := ReadFile(hPipeOutputRead, szBuffer, 256, dwNumberOfBytesRead,
        nil);
      if not bTest then
      begin
        break;
      end;
      Stream.Write(szBuffer, dwNumberOfBytesRead);
    end;
    Stream.Position := 0;
    Output.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;

  //Read error pipe
  Stream := TMemoryStream.Create;
  try
    while true do
    begin
      bTest := ReadFile(hPipeErrorsRead, szBuffer, 256, dwNumberOfBytesRead,
        nil);
      if not bTest then
      begin
        break;
      end;
      Stream.Write(szBuffer, dwNumberOfBytesRead);
    end;
    Stream.Position := 0;
    Errors.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;

  WaitForSingleObject(pi.hProcess, INFINITE);
  CloseHandle(pi.hProcess);
  CloseHandle(hPipeOutputRead);
  CloseHandle(hPipeErrorsRead);
end;

(* got it from yahoo groups, so no copyrights for this piece :p and and example
   of how to use it. put a button and a memo to a form.                      *)

procedure TForm1.Button1Click(Sender: TObject);
var
  OutP: TStringList;
  ErrorP: TStringList;
begin
  OutP := TStringList.Create;
  ErrorP := TstringList.Create;

  ExecConsoleApp('ping localhost', OutP, ErrorP);
  Memo1.Lines.Assign(OutP);

  OutP.Free;
  ErrorP.Free;
end;

Последний раз редактировалось rpy3uH; 25.07.2008 в 21:35.
BOBAH13 вне форума   Ответить с цитированием
Старый 26.06.2008, 00:11   #3
Артем5555555
Новичок
Джуниор
 
Регистрация: 25.06.2008
Сообщений: 2
По умолчанию

Спасибо за ответ!
Артем5555555 вне форума   Ответить с цитированием
Старый 25.09.2008, 17:17   #4
Vovandows
Пользователь
 
Аватар для Vovandows
 
Регистрация: 22.09.2008
Сообщений: 11
По умолчанию Неработает

У меня чето эта процедура неработает, в Memo1.Lines выводит вот это:

ЏаЁ Їа®ўҐаЄҐ бўп§Ё *Ґ г¤*«®бм ®Ў**аг¦Ёвм 㧥« localhost. Џа®ўҐам⥠Ё¬п 㧫* Ё Ї®ўв®аЁвҐ Ї®ЇлвЄг.
Vovandows вне форума   Ответить с цитированием
Старый 25.09.2008, 17:36   #5
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

"При проверке связи не удалось обнаружить узел localhost. Проверьте имя узла и повторите попытку" ?
Используй OEMToAnsi(OemSt, AnsiStr: PChar): Bool;.
пыщь
JTG вне форума   Ответить с цитированием
Старый 25.09.2008, 17:38   #6
Alter
Старожил
 
Аватар для Alter
 
Регистрация: 06.08.2007
Сообщений: 2,230
Сообщение

Цитата:
Сообщение от Vovandows Посмотреть сообщение
У меня чето эта процедура неработает, в Memo1.Lines выводит вот это:

ЏаЁ Їа®ўҐаЄҐ бўп§Ё *Ґ г¤*«®бм ®Ў**аг¦Ёвм 㧥« localhost. Џа®ўҐам⥠Ё¬п 㧫* Ё Ї®ўв®аЁвҐ Ї®ЇлвЄг.
Это "OEM -> DOS" кодировка, измените кодировку символов в Memo.
А написанно в том что привели: "При проверке связи *е уд*лось об**ружить узел localhost. Проверьте имя узл* и повторите попытку".
___________________________________ ______
Опередили меня
Alter вне форума   Ответить с цитированием
Старый 17.10.2008, 19:33   #7
Izhic
Форумчанин
 
Аватар для Izhic
 
Регистрация: 08.10.2008
Сообщений: 667
По умолчанию

Друзья, А у меня вот такая проблема. В тему.
Допустим ловим процентs получается:
1% Load
2% Load
3% Load
........
100% Load.
Ну вы поняли выводиться весь процесс далее и далее а не как в cmd.
Вопрос как поправить чтобы этого избежать? или программно тока самому по формату?

Я так понял иначе ни как , хотя странно , могу же Я в cmd : пометить , выделить всё, копировать. Так почему (ИМХО) нету ничсего как просто всё содержимое копировать подобным образом?
Izhic вне форума   Ответить с цитированием
Старый 17.10.2008, 21:10   #8
rpy3uH
добрый няша
СуперМодератор
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,808
По умолчанию

непонятно. Ещё раз нормально объясни
rpy3uH вне форума   Ответить с цитированием
Старый 17.10.2008, 22:09   #9
Izhic
Форумчанин
 
Аватар для Izhic
 
Регистрация: 08.10.2008
Сообщений: 667
Смех

Цитата:
Сообщение от rpy3uH Посмотреть сообщение
непонятно. Ещё раз нормально объясни
Я ловлю поток cmd через
ReadFile(hReadOut, sBufferOut[1], l_BUFFER_SIZE, bReadOut, nil)

Однако допустим мы ловим сообщения архиватора и он отображает, процесс архивации в реальном времени. При этом строка состояния остаётся на одном месте.
//чтото типа readln не происходит. Просто обовление последних строк
А в моём потоке не отбражается делали ли они какуюто очистку экрана ли нет. Он просто отображет мне последние сообщения и они у меня идут в memo потоянно вниз. И получается. Постоянные "readln"
Хочу сделать что бы у меня тоже оставалось на одном месте. Но не знаю как.
//КАк вариант если формат похожий , сделать проверку чтото вроде regexp, и тогда удалить
// последнюю строку и вставить эту тогда состояние будет изменяться на одном месте.
-------------------------------
//что Я сказал...
Don't worry be happy

Последний раз редактировалось Izhic; 17.10.2008 в 22:16.
Izhic вне форума   Ответить с цитированием
Старый 17.10.2008, 22:26   #10
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Что нельзя так сделать ? TMemo.Lines[TMemo.Lines.Count - 1] := 'Новая полученная строка'; вроде так если память не подводит
BOBAH13 вне форума   Ответить с цитированием
Ответ
Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Поиск и копирование текста из консольного окна Mago Паскаль, Turbo Pascal, PascalABC.NET 8 25.07.2008 15:04
Программа ввода и вывода последовательности символов(Assembler) WST Помощь студентам 1 01.04.2008 12:33
Си против Си++ - сис. ввода-вывода Sota Общие вопросы C/C++ 4 31.07.2007 17:52
Перехват вывода консольного приложения Роман Радер Общие вопросы Delphi 0 12.02.2007 19:40