Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Вниз

Named pipes trouble   Найти похожие ветки 

 
Чапаев ©   (2004-06-01 10:34) [0]

Задача: при нажатии на кнопку программа запускает другую программу, если та
ещё не запущена и выдаёт MessageBox об успешном запуске. Вторая программа
создаёт глобальный объект (мьютекс), который сигнализирует о том, что эта
программа запущена, создаёт именованный канал и регистрирует некоторое
оконное сообщение. По нажатию на вторую кнопку первая программа передаёт
второй через канал некий текст и отправляет оповещение.

Теперь собственно проблема. Если MessageBox не закрыть, вторая программа
получает мусор. Если же его закрыть или не выдавать совсем, всё передаётся
правильно.

Первая программа:
unit RunnerU;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ShellApi, Constants;

type
 TForm1 = class(TForm)
   btnCheckRun: TButton;
   mmXML: TMemo;
   btnSendXml: TButton;
   procedure btnCheckRunClick(Sender: TObject);
   procedure FormCreate(Sender: TObject);
   procedure btnSendXmlClick(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   Pipe:THandle;
   MsgNumber:Cardinal;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnCheckRunClick(Sender: TObject);
begin
 if OpenMutex(MUTEX_ALL_ACCESS,True,MutexName)=0
   then
     if
ShellExecute(Application.Handle,"open",ProgramName,"","",SW_SHOW)<32
       then raise Exception.Create("Can""t run "+ProgramName);
       else MessageBox(0,"Program runned successfully","OK",MB_OK or
MB_ICONINFORMATION) //Debug
   else MessageBox(0,"Program already runned","OK",MB_OK or
MB_ICONINFORMATION); //Debug
 while OpenMutex(MUTEX_ALL_ACCESS,True,MutexName)=0 do;

Pipe:=CreateFile("\\.\pipe\"+PipeName,GENERIC_WRITE,0,nil,OPEN_EXISTING,0,0)
;
 if Pipe=INVALID_HANDLE_VALUE then
   raise Exception.Create("Can""t open pipe");
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 MsgNumber:=RegisterWindowMessage(MessageName);
 if MsgNumber=0 then
   raise Exception.Create("Can""t register message");
end;

procedure TForm1.btnSendXmlClick(Sender: TObject);
var
 ActualWritten:Cardinal;
 Recipients:PDWORD;
begin
 WriteFile(Pipe,mmXML.Text[1],Length(mmXML.Text),ActualWritten,nil);
 New(Recipients);
 Recipients^:=BSM_APPLICATIONS;
 BroadcastSystemMessage(BSF_IGNORECURRENTTASK or
BSF_POSTMESSAGE,Recipients,MsgNumber,0,Length(mmXML.Text));
 Dispose(Recipients);
end;

end.

Вторая программа:
unit RunnableU;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   mmXML: TMemo;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
   Pipe:THandle;
   Msg:Cardinal;
   Mutex:THandle;
 protected
   procedure WndProc(var Mssg:TMessage);override;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

uses Constants;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
 Mutex:=OpenMutex(MUTEX_ALL_ACCESS,true,MutexName);
 if Mutex<>0 then begin
   raise Exception.Create("Program already runned");
   Halt;
 end;

Pipe:=CreateNamedPipe("\\.\pipe\"+PipeName,PIPE_ACCESS_INBOUND,PIPE_TYPE_BYT
E or PIPE_WAIT,1,100000,1000000,1000,nil);
 if Pipe=INVALID_HANDLE_VALUE then begin
   raise Exception.Create("Can""t create pipe");
   Halt;
 end;
 Msg:=RegisterWindowMessage(MessageName);
 if Msg=0 then begin
   raise Exception.Create("Can""t register message");
   Halt;
 end;
 Mutex:=CreateMutex(nil,True,MutexName);
 if Mutex=0 then begin
   raise Exception.Create("Can""t create mutex");
   Halt;
 end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 CloseHandle(Mutex);
 CloseHandle(Pipe);
end;

procedure TForm1.WndProc(var Mssg: TMessage);
var
 ActRead:Cardinal;
 S:string;
begin
 if Mssg.Msg=Msg
   then begin
     SetLength(S,Mssg.LParam);
     ReadFile(Pipe,S[1],Mssg.LParam,ActRead,nil);
     mmXML.Clear;
     mmXML.Lines.Add(S);
   end
   else
     inherited;
end;

end.


 
Игорь Шевченко ©   (2004-06-01 10:58) [1]


>     ReadFile(Pipe,S[1],Mssg.LParam,ActRead,nil);


В этой строчке проверять код возврата.

Весьма вероятно, что сообщение, посылаемое по BSM, выбирается в цикле выборки сообщений MessageBox"а.


 
Чапаев ©   (2004-06-01 11:18) [2]

Угу... Действительно, ReadFile возвращает False. Только всё же непонятно... MessageBox принадлежит первой программе, почему же данные по каналу не доходят до второй? Ведь само-то сообщение она ловит...


 
Игорь Шевченко ©   (2004-06-01 11:32) [3]


> MessageBox принадлежит первой программе, почему же данные
> по каналу не доходят до второй? Ведь само-то сообщение она
> ловит...


А глупый вопрос: как ты можешь нажать на вторую кнопку, пока MessageBox на экране ? Может, для пущей синхронизации использовать Application.MessageBox ?


 
Чапаев ©   (2004-06-01 11:33) [4]

>А глупый вопрос: как ты можешь нажать на вторую кнопку, пока MessageBox на экране ?
Ну она ж немодальная...


 
Игорь Шевченко ©   (2004-06-01 11:56) [5]


> Ну она ж немодальная...


А сделать MessageBox модальным по отношению к ней, может, поможет ?


 
Чапаев ©   (2004-06-01 12:08) [6]

Оно-то поможет, но я не понимаю, почему с каналом проблемы получаются?


 
Игорь Шевченко ©   (2004-06-01 12:21) [7]


> но я не понимаю, почему с каналом проблемы получаются?


На мой взгляд очень похоже на ситуацию, что сообщение приходит раньше, чем данные в канал помещены...Winsight или Spy++ могут помочь прояснить ситуацию.

И кстати, что возвращает WriteFile ? Тоже ведь код возврата не проверяется..


 
Чапаев ©   (2004-06-01 12:27) [8]

>И кстати, что возвращает WriteFile ? Тоже ведь код возврата не проверяется..
Хе. Возвращает False. Вопрос снимается.


 
Игорь Шевченко ©   (2004-06-01 12:37) [9]

Чапаев ©   (01.06.04 12:27)

GIGO - garbage in, garbage out :)

Удачи!



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.028 c
3-1087435598
alex_pv
2004-06-17 05:26
2004.07.11
Access и ADO, блокировка таблицы


1-1088264007
Damager
2004-06-26 19:33
2004.07.11
Total Commander 6


1-1088085346
Alex____
2004-06-24 17:55
2004.07.11
Как откомпилировать исходник ~70 Mb?


14-1087984728
Adder
2004-06-23 13:58
2004.07.11
%))


1-1088596423
Snip
2004-06-30 15:53
2004.07.11
TListView





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский