Vic
Vic

Reputation: 935

Delphi 2009: How to communicate between Windows service & desktop application under Vista?

How can a desktop application communicate with a Windows service under Vista/Windows2008/Windows7? The application needs to send small strings to the service and receive string responses back. Both are written in Delphi 2009. (Please provide sample code also)

Upvotes: 5

Views: 9310

Answers (7)

Shlomo Abuisak
Shlomo Abuisak

Reputation: 111

I used this component for years TMailslot Component for Delphi 32
Version: 1.4
Author: Aleksey Kuznetsov

Upvotes: 0

Davy Landman
Davy Landman

Reputation: 15429

The way to go is named pipes, you'll probably have to take a look at the communication across different Integrity levels.

This article explores how to do this in vista. Although it's written in c++ it's just basic Windows API calls, so it should translate fast enough to Delphi.

If you want to search for more on this subject, this communication is called Inter Process Communication, but a better search term is IPC.

Upvotes: 6

John J
John J

Reputation:

I use in my service applications a component set, freeware with sourcecode called Simple IPC.

Search torry.net. It has worked very well in all of my service apps when communicating with a desktop app.

John

Upvotes: 1

skamradt
skamradt

Reputation: 15538

You have to change the service user from localsystem to networkservice and then the service can use TCPIP fine. I have several services which use TCPIP for an external control hook. Just make sure your service port is configurable so you can handle any collisions.

A few of my control interfaces are based on XML pages served from an internal HTTP server. This allows me to remotely check on status of the service using any web browser which can reach the port on that machine. The advantage of using HTTP over other methods is that it works well when you need to work over existing network hardware.

If your ONLY going to be communicating locally, then named pipes, mail slots or a memory mapped file might be the best method.

Upvotes: 3

jpfollenius
jpfollenius

Reputation: 16602

Using Indy you can relatively easy create a TCP connection between your apps. Especially if you only need to send string messages. For the client (in your case the desktop application) it's basically

var
  Client : TIdTCPClient;
...
Client.Host := 'localhost';
Client.Port := AnyFreePortNumber;
Client.Connect;
Client.IOHandler.Writeln (SomeString);
Response := Client.Readln;
...
Client.Disconnect;

For the server (would be the service in your case)

var
  Server  : TIdTCPServer;
  Binding : TIdSocketHandle;
...
Server.DefaultPort := SameFreePortNumberAsInClient;
Binding := Server.Bindings.Add;
Binding.IP := '127.0.0.1';    
Binding.Port := Server.DefaultPort;
Server.OnConnect := HandleConnection;
Server.OnDisconnect := HandleDisconnection;
Server.OnExecute := HandleCommunication;
Server.Active := True;

Just implement the HandleCommunication method. It is called whenever the client decides to send something. Example:

procedure MyClass.HandleCommunication (AContext : TIdContext);
var
  Request : String;
begin
  Request := AContext.Connection.IOHandler.Readln;
  if (Request = Command1) then
    HandleCommand1
  else if (Request = Command2) then
    HandleCommand2
  ...
end;

IIRC a service is only allowed to have a graphical user interface OR have network access, so this might be a problem if your service needs a GUI (which you should avoid anyway, see this question). I don't know how this is handled in Windwos Vista and later though.

Upvotes: 5

mj2008
mj2008

Reputation: 6747

Have a look at the answers in Exchange Data between two apps across PC on LAN which is pretty much the same question nowadays. Local comms via TCP is standard. As I said in my response there, solutions that use "Remote Procedure Call" type interfaces work well. I use RemObjects SDK for this sort of thing, and it makes it easy to expand to control across the network if you wish to later.

Both of these allow you to create a connection that for most of your code is "transparent", and you just call an interface which sends the data over the wire and gets results back. You can then program how you usually do, and forget the details of sockets etc.

Upvotes: 3

dan-gph
dan-gph

Reputation: 16899

I haven't tried it, but I think you could use named pipes.

Upvotes: 2

Related Questions