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


Автор: mspuz 2.3.2006, 22:36
У меня есть программа(А), которая по таймеру запускает другую программу(В). В программе В возможны системные сбои и мне бы хотелось, чтобы после отработки, программа В возвращала результаты - все хорошо, либо произошла ошибка. Как это осуществить??? Пока на уме лишь создание программой В файла txt, в котором будет подробный отчет, который программа А считывает и заносит в БД Журнал. Но наверняка есть что-то покруче!!!!

Автор: Guedda 2.3.2006, 22:40
Есть, конечно.
Программой В послылай SendMessage программе А константу, а программой A принимай сообщения.

Автор: Snowy 2.3.2006, 22:42
1. Запускаешь программу через CreateProcess.
2. Ждешь ее завершения (примеры ожидания в FAQ)
3. Вызванную программу завершаешь по Halt(код);
4. В вызывающей программе получаешь этот код через GetExitCodeProcess.

Автор: mspuz 3.3.2006, 10:15
У меня могут быть различного рода ошибки и значение "завершился"-"незавершился" меня не совсем устраивают. Например Программа В не смогла выполнить SQL-запрос, она формирует сообщение, в котором сказанно в какой процедуре это произошло и саму строчку SQL-запроса и это все надо передать в программу А. Можно ли это организовать через SendMessage??? И еще, я запускаю программу через CreatProcess, но не могу ждать её завершения, т.к. мне нужно запускать другие программы паралельно и от них от всех получать отчеты о проделанной работе.

Автор: Guedda 3.3.2006, 10:19
Создаешь константы типа:
Код

const
  MESSAGE_NOTSQL = $0001;
  MESSAGE_NOTDATA = $0002;
  //и так далее


Потом послыаешь это своей второй программе. Программа ловит SM, и сравнивает с константами. Вот и все.

Автор: remax 3.3.2006, 10:46
Все зависит от цели...
1) Проще всего и информативней (как, впрочем, mspuz и собирался), чтобы программа (запускаемая) вела файл протокола, например - в обычном текстовом файле при возникновении интересующих событий открываем на запись командой append, записываем подробно информацию, закрываем CloseFile. Поскольку формат данных произвольный - фиксирум все что необходимо вплоть до времени возникновения события.
2) Есть специальные средства(например, в библиотеке JEDI), позволяющие вести специализированный файлы протоколов типа .CSV. Их использование предпочтительней с точки зрения стандартизации и унификации. Кроме того, для них уже есть готовый инструментарий.
3) Если необходимо, чтобы вызывающая программа каким-то образом реагировала, то проще всего использовать предложенный Snowy подход через Halt/GetExitCodeProcess. Это вообще стандартные действия для объединения разных программ еще со времен DOS. В принципе, можно анализировать возвращаемый код даже в BAT-файлах. smile
4) Если во время работы запускаемой программы возникает необходимость неоднократной перадачи информации, то здесь лучше воспользоваться SendMessage, как предлагает Guedda . В принципе, с помощью этого подхода можно организовать даже обратную связь.


Автор: Демо 3.3.2006, 11:03
Если нужна немедленная реакция на события в вызванной программе, то тогда, конечно, метод ведения протокола не подходит.

Решений такой проблемы предостаточно:
- Pipes
- Socket
- Messages
- Технологии COM/DCOM

Автор: Snowy 3.3.2006, 11:15
Поиск по форуму по слову WM_COPYDATA.
Никаких проблем с передачей любых данных между приложениями нет.

Автор: mspuz 3.3.2006, 13:07
Блин, чето я туплю, ну никак не могу найти подробного описания WM_COPYDATA, подскажите что неправильно???
Отправляющая часть:

Код
var
hw:THandle;
cd:TCopyDataStruct;
begin
 hw:=FindWindow('TForm1','Ïðèíèìàþùèé');
 cd.dwData:=10;
 cd.cbData:=SIZEOF(Memo1.Text);
 cd.lpData:[email protected];
 SendMessage(hw,WM_COPYDATA,0,Integer(@cd));
end;


Принимающая часть

Код
var
 cds:PCopyDataStruct;
begin
 cds:=Msg.CopyDataStruct;
 Memo1.Text:=String(PCopyDataStruct(cds.lpData));
end;



Я использую Memo для примера, но на самом деле хочу использовать переменную типа TStringList, в которую помещу нужные данные и переправлю программе.

Автор: Snowy 3.3.2006, 13:11
Цитата(mspuz @ 3.3.2006, 13:07 Найти цитируемый пост)
 cd.lpData:[email protected];
Так делать нельзя.
Сначала присвой текст в стринговую переменную, а потом ее передавай:
Код

 s:=Memo1.Lines.Text;
 cd.lpData:=pointer(s);

Добавлено @ 13:13
Вот пример передачи стринга из одной программы в другую:
http://forum.vingrad.ru/index.php?showtopic=83144&view=findpost&p=642109

Автор: mspuz 3.3.2006, 13:41
Snowy, YES!!!! Заработало!!! Обалдеть!!! Огромное спасибо!!! А можно для справки???
Что такое - cd.dwData
Какая разница между pointer и @ (сработало с pointer)

Автор: Romikgy 3.3.2006, 13:51
Цитата(mspuz @ 3.3.2006, 12:41 Найти цитируемый пост)
pointer и @

имхо одинаково
Добавлено @ 13:52
Код

dwData

Specifies up to 32 bits of data to be passed to the receiving application. 

Автор: Snowy 3.3.2006, 13:57
Цитата(mspuz @ 3.3.2006, 13:41 Найти цитируемый пост)
Что такое - cd.dwData
Это любое число. Можешь его использовать, а можешь нет. Его можно использовать, например, для того, чтобы различать, что именно ты шлешь: строку, какую-то свою структури или что-то другое на свое усмотрение.
А можно вообще не использовать.

Цитата(mspuz @ 3.3.2006, 13:41 Найти цитируемый пост)
Какая разница между pointer и @ (сработало с pointer)
@ - это получить адрес.
а pointer - прямое преобразование переменной в поинтер.
То есть @s - даст нам указатель на переменную s.
А pointer(s) - даст нам указатель на первый символ строки. Аналогично можно сделать так: @s[1]
Верно и то и другое, но не @s - так мы получим указатель на указатель.

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