-
Собственно задача Нужно отправить определённой программе команду с помощью SendMessage(WM_CopyData), дождаться пока прийдёт ответ от нее (тоже она отправляет с помощью WMCopyData и SendMessage) и возвращитить его как резалт функции. Это конечно можно сделать асинхронно всё. Т.е. отправил команду. Потом получил ответ в оконную функцию и запустил нужную функцию или присвоил его переменной какой-то. Но хотелось бы как. Из любого места в программе вызвал функцию MYSENDCOMMAN('тут команда') и она возвратила результат который ей пришел от другой программы. Реально ли этол вообще сделать?
Пытался сделать так. в MYSENDCOMMAN отправляю сообщение, потом делаю бесконечный цыкл где происходит application.processmessage который обрываеться когда приходит WM_CopyData в оконную функцию. Только вот проблема что в оконную функцию это сообщение уже не приходит так капк подозреваю что цыкл который бесконечный с application.processmessage недает этому свершиться. Может знает кто-то как вообще можно это реализовать?...
-
> Жэня (12.03.10 22:24)
для обмена данными между процессами есть множество методов: 1) Сообщения 2) Сокеты 3) Именованные каналы 4) Файлы отображенные в память 5) Майлслоты всякие 6) DCOM
Сообщения не лучший способ в твоем случае
-
> MYSENDCOMMAN('тут команда') и она возвратила результат который > ей пришел от другой программы. Реально ли этол вообще сделать? >
что из себя представляет результат? Если целое число, то SendMessage как раз это и позволит сделать.
-
ну тут спецификация такая что нужно именно сообщениями поэтому других вариантов нету
да, я вкурсе что sendmessage возвращает результат, тольво вот он не integer и нужно именно получить резалт что шлёт программа через wm_copydata
-
> Жэня
Две посылки WM_COPYDATA всегда будут асинхронны. Одной WM_COPYDATA тоже не обойдешься, т.к принимающая сторона не может менять данные в сообщении. Если уж приспичило именно сообщениями, то может их использовать в паре с MMF
-
ну тут нето чтобы приспичило, вторая прога это третья разработка и она так работает.//
-
> Жэня (13.03.10 00:09) [5]
Сделать из асинхронного синхронное конечно всегда можно, но надо ли? Это как корове седло.
-
Если нельзя, но все-же очень хочется, то можно. Пусть принимающая сторона на SendMessage возвращает хэндл выданный GlobalAlloc, откуда можно будет прочитать результирующие данные.
-
> Пусть принимающая сторона на SendMessage возвращает хэндл > выданный GlobalAlloc, откуда можно будет прочитать результирующие > данные.
Из другого процесса ?
-
Ну и вот это конечно очень сильно удивило:
> вкурсе что sendmessage возвращает результат, тольво вот > он не integer
-
> Игорь Шевченко © (13.03.10 00:39) [8] > > > > Пусть принимающая сторона на SendMessage возвращает хэндл > > выданный GlobalAlloc, откуда можно будет прочитать результирующие > > данные. > > > Из другого процесса ?
А это проблемма?
-
я всмысле что sendmessage возвращает целое только программа та возвращает не целое... поэтому определять успешность команды сендмеседж неподходит.
В любом случае решил уже проблему. ReplyMessage(1); спасла, просто вызывался цыкл в оконной функции и небыло ответа на сообщение, поэтому не слались другие. Всем спасибо
-
Rouse_ © (13.03.10 00:47) [10]
Возвратить Handle, полученный по GloballAlloc в другом процессе - не проблема.
Прочитать данные оттуда представляется проблемой, нет ? Как-то до сих пор не приходилось слышать об обмене между процессами по Handle GlobalAlloc, все больше через MMF.
У меня такой пробел в образовании ?
-
> Игорь Шевченко © (13.03.10 01:11) [12] > У меня такой пробел в образовании ?
Стесняюсь спросить, CreateStreamOnHGlobal работает только в рамках твоего процесса?
-
Rouse_ © (13.03.10 01:26) [13]
Ты не стесняйся, ты лучше код приведи, когда один процесс выделяет память по GlobalAlloc, передает этот HGlobal в другой процесс, а другой эту память использует. Хотя бы через CreateStreamOnHGlobal, или через GlobalLock + чтение/запись
-
> Rouse_ © (13.03.10 01:26) [13]
> Игорь Шевченко © (13.03.10 01:32) [14]
Бедн(ый)ая Жэня. Он(а) совсем о другом спрашивал(а). (((
-
> Игорь Шевченко © (13.03.10 01:32) [14] > > Rouse_ © (13.03.10 01:26) [13] > > Ты не стесняйся, ты лучше код приведи
Хм, мдя, что-то я зарапортовался, глядя на код своего снапина :) Ну тогда вот так: Отправляющая сторона: procedure TForm2.Button1Click(Sender: TObject);
var
P: PDWORD;
CDS: TCopyDataStruct;
begin
CDS.dwData := GetCurrentProcessId;
CDS.cbData := 0;
CDS.lpData := nil;
P := PDWORD(SendMessage(StrToInt(Edit1.Text),
WM_COPYDATA, Handle, Integer(@CDS)));
if P <> nil then
begin
ShowMessage(IntToHex(P^, 8));
VirtualFree(P, 4, MEM_RELEASE);
end;
end; Принимающая сторона: type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure Foo(var Message: TWMCopyData); message WM_COPYDATA;
end;
var
Form1: TForm1;
implementation
procedure TForm1.Foo(var Message: TWMCopyData);
var
P: Pointer;
Data: DWORD;
hProc: THandle;
lpNumberOfBytesWritten: DWORD;
begin
Data := $DEADBEEF;
Message.Result := 0;
hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_WRITE, False,
Message.CopyDataStruct^.dwData);
if hProc <> 0 then
try
P := VirtualAllocEx(hProc, nil, 4, MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(hProc, P, @Data, 4, lpNumberOfBytesWritten);
if lpNumberOfBytesWritten = 4 then
Message.Result := Integer(P);
finally
CloseHandle(hProc);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Caption := IntToStr(Handle);
end;
|