Форум программистов, компьютерный форум, киберфорум
Наши страницы
Lazarus
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
DEM_DWG
8 / 8 / 1
Регистрация: 03.01.2013
Сообщений: 101
1

Передать сообщение в консольное приложение

08.01.2013, 11:04. Просмотров 2366. Ответов 5
Метки нет (Все метки)

К сожалению не получается ни как передать сообщения в консольное приложение на Питоне из программы сделанной в Лазарусе...
Запуск консольной программы у меня получается, тут ничего сложного....
Delphi
1
SysUtils.ExecuteProcess('python.exe', 'module1.py');
Но вот отправить в это же приложение какую то команду у меня не получается....
Справку по Executing External Programs
Прочитал внимательно но там тоже примеров такого взаимодействия нету....
Есть TProcess, но он не позволяет отправлять сообщение в консоль, хотя в принципе, если не получится работать в режиме обмена сообщениями с приложением на Питоне, то придется использовать именно TProcess....
Подскажите пожалуйста как можно это сделать, а то 2-й день голову ломаю....

Добавлено через 10 часов 11 минут
Нашел на DELPHI пример с использованием пайпов....
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
function ExecuteFile(FileName,StdInput: string; TimeOut: integer; var StdOutput:string) : boolean;
 
label Error;
 
type
  TPipeHandles = (IN_WRITE,  IN_READ,
                  OUT_WRITE, OUT_READ,
                  ERR_WRITE, ERR_READ);
 
type
  TPipeArray = array [TPipeHandles] of THandle;
 
var
  i         : integer;
  ph        : TPipeHandles;
  SA        : TSecurityAttributes;
  Pipes     : TPipeArray;
  StartInf  : TStartupInfo;
  ProcInf   : TProcessInformation;
  Buf       : array[0..1000] of byte;
  Bytes     : DWord;
  TimeStart : TDateTime;
 
begin
  Result := false;
  for ph := Low(TPipeHandles) to High(TPipeHandles) do Pipes[ph] := INVALID_HANDLE_VALUE;
 
  // Создаем пайпы
 
  sa.nLength := sizeof(sa);
  sa.bInheritHandle := TRUE;
  sa.lpSecurityDescriptor := nil;
 
  if not CreatePipe(Pipes[IN_READ],Pipes[IN_WRITE], @sa, 0 ) then goto Error;
  if not CreatePipe(Pipes[OUT_READ],Pipes[OUT_WRITE], @sa, 0 ) then  goto Error;
  if not CreatePipe(Pipes[ERR_READ],Pipes[ERR_WRITE], @sa, 0 ) then  goto Error;
 
  // Пишем в STDIN
 
  WriteFile(Pipes[IN_WRITE],PChar(StdInput+^Z)^,Length(stdInput)+1,Bytes,nil);
 
  // Хендл записи в StdIn надо закрыть - иначе выполняемая
  // программа может не прочитать или прочитать не весь StdIn.
 
  CloseHandle(Pipes[IN_WRITE]);
  Pipes[IN_WRITE] := INVALID_HANDLE_VALUE;
 
  FillChar(StartInf,sizeof(TStartupInfo),0);
  StartInf.cb := sizeof(TStartupInfo);
  StartInf.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
 
  StartInf.wShowWindow := SW_SHOW; // Или SW_HIDE если надо запустить невидимо
 
  StartInf.hStdInput := Pipes[IN_READ];
  StartInf.hStdOutput := Pipes[OUT_WRITE];
  StartInf.hStdError := Pipes[ERR_WRITE];
 
  if not CreateProcess(nil, PChar(FileName), nil,
                       nil, True, NORMAL_PRIORITY_CLASS,
                       nil, nil, StartInf, ProcInf) then goto Error;
 
  TimeStart := Now;
 
  repeat
    Application.ProcessMessages;
    i := WaitForSingleObject(ProcInf.hProcess,100);
    if i = WAIT_OBJECT_0 then break;
    if (Now-TimeStart)*SecsPerDay>TimeOut then break;
  until false;
 
  if i<>WAIT_OBJECT_0 then goto Error;
 
  // Закрываем хендл записи в STDOUT чтобы прочитать консольный вывод
 
  CloseHandle(Pipes[OUT_WRITE]);
  Pipes[OUT_WRITE] := INVALID_HANDLE_VALUE;
 
  // Читаем STDOUT
   
  StdOutput := '';
  repeat
    Bytes:= 0;
    ReadFile(Pipes[OUT_READ],Buf,SizeOf(Buf),Bytes,nil);
    if Bytes=0 then break;
    i := Length(StdOutput);
    SetLength(StdOutput,i+Bytes);
    Move(Buf[0],StdOutput[i+1],Bytes);
  until false;
 
  for ph := Low(TPipeHandles) to High(TPipeHandles) do
  if Pipes[ph]<>INVALID_HANDLE_VALUE then CloseHandle(Pipes[ph]);
 
  CloseHandle(ProcInf.hProcess);
  CloseHandle(ProcInf.hThread);
  Result := true;
  Exit;
 
Error:
  if ProcInf.hProcess<>INVALID_HANDLE_VALUE then
  begin
    CloseHandle(ProcInf.hThread);
    i := WaitForSingleObject(ProcInf.hProcess, 1000);
    CloseHandle(ProcInf.hProcess);
    if i<>WAIT_OBJECT_0 then
    begin
      ProcInf.hProcess := OpenProcess(PROCESS_TERMINATE, FALSE, ProcInf.dwProcessId);
      if ProcInf.hProcess <> 0 then
      begin
        TerminateProcess(ProcInf.hProcess, 0);
        CloseHandle(ProcInf.hProcess);
      end;
    end;
  end;
  for ph := Low(TPipeHandles) to High(TPipeHandles) do
  if Pipes[ph]<>INVALID_HANDLE_VALUE then CloseHandle(Pipes[ph]);
end;
Нельзя ли этот код переделать для Лазаря.....
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.01.2013, 11:04
Ответы с готовыми решениями:

Закрывается консольное приложение
Закрывается консольное приложение. При создании имеет стандартный вид...

Как сделать, чтобы консольное приложение в Lazarus читало символы псевдографики?
Вот эти символы:...

консольное приложение
Как из консольного приложения сделать неконсольное,а чтобы формы открывал???

Консольное приложение: файлы и записи
Хранение данных обеспечить в виде файла, состоящего из записей (record)...

Передача данных в консольное приложение. TPJPipe и TByteStream
Общая постановка задачи - передать в стороннее консольное приложение некоторые...

5
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26488 / 17789 / 7037
Регистрация: 22.10.2011
Сообщений: 31,306
Записей в блоге: 6
08.01.2013, 11:29 2
В чем проблема? В строке с WriteFile? Обходится элементарно:

Pascal
1
2
3
4
5
6
var sI : string;
// ...
 
  // Пишем в STDIN
  sI := StdInput + ^Z;
  WriteFile(Pipes[IN_WRITE],PChar(SI)^,Length(stdInput)+1,Bytes,nil);
, на работоспособность не проверял, но компилироваться должно.
0
DEM_DWG
8 / 8 / 1
Регистрация: 03.01.2013
Сообщений: 101
08.01.2013, 11:35  [ТС] 3
Проблема в башке моей глупой....
Чей то не разберусь с какими параметрами функцию запускать
Delphi
1
function ExecuteFile(FileName,StdInput: string; TimeOut: integer; var StdOutput:string) : boolean;
И какие параметры она выдает...
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26488 / 17789 / 7037
Регистрация: 22.10.2011
Сообщений: 31,306
Записей в блоге: 6
08.01.2013, 11:56 4
Получает имя файла, который надо запустить, и строку, которую надо передать в поток ввода (STD_INPUT_HANDLE) этой программы. А также таймаут, чтобы отследить зависание. Возвращает (через параметр StdOutput) то, что вызываемая программа вернула через свой STD_OUTPUT_HANDLE. Сам результат функции ExecuteFile - это признак успешного выполнения вызываемой программы.

То есть, вызов может быть вот таким:

Pascal
1
2
3
4
5
6
var sOut : string;
 
if ExecuteFile('myfile.exe', 'param1 param2', 5000, sOut) then
   ShowMessage('Ответ программы: ' + sOut)
else
   ShowMessage('Упс. Что-то пошло не так...');
0
DEM_DWG
8 / 8 / 1
Регистрация: 03.01.2013
Сообщений: 101
08.01.2013, 13:41  [ТС] 5
Ругается на
SA : TSecurityAttributes;
ProcInf : TProcessInformation;
Не пойму что добавлять в uses
И можно ли будет отправлять сообщение после запуска программы...
Т.е. мы её запустили с параметрами она дала ответ, а дальше то какую функцию запускать чтобы получить новое сообщение....
Вы уж извиняйте, я в Лазаре ламер, но глядишь соображать начну
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
26488 / 17789 / 7037
Регистрация: 22.10.2011
Сообщений: 31,306
Записей в блоге: 6
08.01.2013, 14:05 6
Цитата Сообщение от DEM_DWG Посмотреть сообщение
Не пойму что добавлять в uses
Как всегда, Windows.
Цитата Сообщение от DEM_DWG Посмотреть сообщение
И можно ли будет отправлять сообщение после запуска программы...
Нет. Этот код не предназначен для подобного использования.

Посмотри сюда: Консольный редирект в обе стороны, здесь решается задача, которую ты описываешь. На Дельфи.
0
08.01.2013, 14:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2013, 14:05

консольное приложение, описывающее ф-цию нахождения ср.арифм. отр.чисел. Исправление ошибок
type ssilka = ^ integer; vector = array of ssilka; Считая, что все элементы...

База данных "Касса" (консольное приложение)
создать консольное приложение – номер билета, – номер рейса, – цена, –...

В тексте, заключённом между @ и @ заменить каждый символ на его код в формате #<числовой код> (консольное приложение)
Народ, выручайте! Нужно консольное приложение сделать в лазарусе, вот задание:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru