Форум программистов, компьютерный форум, киберфорум
Наши страницы

Lazarus

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 16, средняя оценка - 4.88
DEM_DWG
8 / 8 / 1
Регистрация: 03.01.2013
Сообщений: 94
#1

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

08.01.2013, 11:04. Просмотров 2247. Ответов 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):

Закрывается консольное приложение - Lazarus
Закрывается консольное приложение. При создании имеет стандартный вид program project1; {$mode objfpc}{$H+} uses {$IFDEF...

Как сделать, чтобы консольное приложение в Lazarus читало символы псевдографики? - Lazarus
Вот эти символы: │,┤,╡,╢,╖,╕,╣,║,╗,╝,╜,╛,┐,└,┴,┬,├,─,┼,╞,╟,╚,╔,╩,╦,╠,═,╬,╧,╨,╤,╥,╙,╘,╒,╓,╫,╪,┘,┌,┌. Он их при выводе на экран показывает...

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

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

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

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

5
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
25535 / 17088 / 5416
Регистрация: 22.10.2011
Сообщений: 30,257
Записей в блоге: 7
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
Сообщений: 94
08.01.2013, 11:35  [ТС] #3
Проблема в башке моей глупой....
Чей то не разберусь с какими параметрами функцию запускать
Delphi
1
function ExecuteFile(FileName,StdInput: string; TimeOut: integer; var StdOutput:string) : boolean;
И какие параметры она выдает...
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
25535 / 17088 / 5416
Регистрация: 22.10.2011
Сообщений: 30,257
Записей в блоге: 7
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
Сообщений: 94
08.01.2013, 13:41  [ТС] #5
Ругается на
SA : TSecurityAttributes;
ProcInf : TProcessInformation;
Не пойму что добавлять в uses
И можно ли будет отправлять сообщение после запуска программы...
Т.е. мы её запустили с параметрами она дала ответ, а дальше то какую функцию запускать чтобы получить новое сообщение....
Вы уж извиняйте, я в Лазаре ламер, но глядишь соображать начну
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
25535 / 17088 / 5416
Регистрация: 22.10.2011
Сообщений: 30,257
Записей в блоге: 7
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
Привет! Вот еще темы с ответами:

База данных "Касса" (консольное приложение) - Lazarus
создать консольное приложение – номер билета, – номер рейса, – цена, – дата продажи, – фамилия кассира. 2. Получить список...

Запустить внешнее приложение, передать ему параметры и получить результат - Lazarus
Здравствуйте. Проблема такая: RunCommand(exe_name,,output); Думаю, что такое exe_name и exe_param, пояснять не надо) Дебаг показал,...

Как Консольное-приложение в Lazarus сдружить c кодировкой Unicode или Unicode Big Endian или UTF-8 - Lazarus
Нужно чтобы Lazarus отображал символы псевдографики желательно все, но в основном вот эти......

Передать параметры в консольное приложение программно - C#
Привет всем. Интересует возможность программно передать параметры командной строки в консольное приложение .NET перед его запуском. (тоесть...


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

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

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