?
Solved

Send Message from TService to Standard Exe

Posted on 2005-04-26
6
Medium Priority
?
810 Views
Last Modified: 2012-05-05
Hi experts,

I have a Tservice which I would like to send notification of some information to a standard exe. e.g. connection active or not, date of the last update. I havent come to discover many options to do this. If yes, would like to hear from you.

I am thinking about using CreateFileMappnig and use the shared memory to pass data around. However I am stuck at section where the std exe was not able to retrive the map handle after the service has started first. If I start the std exe first, then start the service, the message seems to be sending correctly from the service to the std exe. But if I turn on the service first , then the std app, the message was not received by the std exe.

Joshua

edit: I am sorry guys, I should have posted this to the Delphi language section. I only realize this after I click submit. And I cant seems to find any link to change the channel to delphi
0
Comment
Question by:joshuayip
  • 3
  • 3
6 Comments
 
LVL 22

Expert Comment

by:cookre
ID: 13873205
A common way of doing that sort of thing is with MSMQ.

If all you want to do is send notifications with no more than a DWORD, just use the windows message queue:

1) Create custom messageID with RegisterWindowMessage()
2) Send messages back and forth with PostMessage(), or, if you want synchrony, SendMessage().

0
 

Author Comment

by:joshuayip
ID: 13882047
Hi Cookre, thanks for your response.

That is what I did. I was able to send the message from the service through if I start the std exe first, then start the service. I notice that if I start the service first , my std exe was able to obtain the

In the std exe, at formcreate, I have
  TheMsgVal := RegisterWindowMessage(TheMsgConstant);
  TheMapHnd := ObtainMappingHandle;

Where ObtainMappingHandle is

function ObtainMappingHandle: THandle;
begin
  Result := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,MaxMapLen,TheMappingConstant);
  if Result <> 0 then                                
    if GetLastError = ERROR_ALREADY_EXISTS then      
      begin
        CloseHandle(Result);                      
        Result := OpenFileMapping(FILE_MAP_WRITE,False,TheMappingConstant);
      end;
end;


A sample code I have showed that I should override the WndProc.

procedure TForm1.WndProc(Var TheMsg: TMessage);
Var
  ThePtr : PChar;
  TmpBmp : TBitmap;
begin
  if TheMsg.Msg = TheMsgVal then
    case TheMsg.wParam of
      wpString   : if TheMapHnd <> 0 then
                     begin
                       ThePtr := MapViewOfFile(TheMapHnd,FILE_MAP_WRITE,0,0,0);
                       edtStringRec.Text := ThePtr;
                       UnmapViewOfFile(ThePtr);
                     end;
      wpValue    : edtValueRec.Text := IntToStr(TheMsg.lParam);
      wpBitmap   : begin
                     TmpBmp := TBitmap.Create;
                     try
                       TmpBmp.Handle := TheMsg.lParam;
                       Image2.Picture.Bitmap.Width := TmpBmp.Width;
                       Image2.Picture.Bitmap.Height := TmpBmp.Height;
                       Image2.Picture.Bitmap.Canvas.Draw(0,0,TmpBmp);
                     finally
                       TmpBmp.ReleaseHandle;
                       TmpBmp.Free;
                     end;
                   end;
      wpShutDown : LookForApp(True);
    end;
  Inherited WndProc(TheMsg);
end;

So this actually works, when I start the std exe first, then the service. But it doesnt work the other way round. I notice if I start the service first, then the std exe, the TheMapHnd was showign 0 (on timer, obtainmappinghandle)

-----
 On the service side, I also do the following
  TheMsgVal := RegisterWindowMessage(TheMsgConstant);
  TheMapHnd := ObtainMappingHandle;

On Timer ,

I do the following

if TheHWnd = 0 then
   TheHWnd := FindWindow('TForm1','Test Application #1');


  ThePtr := MapViewOfFile(TheMapHnd,FILE_MAP_WRITE,0,0,0);
  StrPLCopy(ThePtr,IntToStr(DummyCount),MaxMapLen);
  SendMessage(TheHWnd,TheMsgVal,wpString,0);
  UnmapViewOfFile(ThePtr);


Is there anything I am not doing correctly here? Thanks

Joshua




0
 
LVL 22

Expert Comment

by:cookre
ID: 13882225
Your second parm to CreateFileMapping() is null, resulting in a default security descriptor.  This means that only processes with rights equal to or higher than the creating process will have access to the map.

Presuming the service is started under the local system account, you'll have to specify user level security descriptor.

See CreateFileMapping():
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/createfilemapping.asp?frame=true
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:joshuayip
ID: 13883563
Thanks Cookre again for the reply.

I am not familiar with user level security descriptor that you have mentioned. I have looked the documentation. All I know is I have to create an object of type PSecurityAttributes , which has 3 properties I am suppose to initialize. (nLength, lpSecurityDescriptor, and bInheritHandle).  

An example of a security descriptor parameter for CreateFileMapping in delphi would be much appreciated. Thanks

Joshua
0
 
LVL 22

Accepted Solution

by:
cookre earned 250 total points
ID: 13891145
You want to specify a NULL DACL (as opposed to a null DACL) - the says that anyone can access the map.

There's some sample code here, about half-way down with the title Mutex Madness:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaskdr/html/drgui49.asp


0
 

Author Comment

by:joshuayip
ID: 13892513
Thanks for your reply again. It is madness in there. I have no idea what it is talking about. But I found some articles related to creating mutex
http://www.jrsoftware.org/iskb.php?mutexsessions
I have absolutely no idea what are mutexes before you mentioned it.

From your last reply you mentioned I should be specifying NULL DACL, as oppose to null DACL. I am sorry but I dont get this.

I guess this kind of service is kind of complicated for a new bie in service to write. Thanks again for your guidance.

Joshua
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
Loops Section Overview

862 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question