Delphi 2009:如何在Windows服务和&amp ;;之间进行通信Vista下的桌面应用程序?

时间:2009-08-11 12:58:23

标签: delphi windows-services windows-vista delphi-2009 ipc

桌面应用程序如何与Vista / Windows2008 / Windows7下的Windows服务进行通信?应用程序需要向服务发送小字符串并接收字符串响应。两者都是用Delphi 2009编写的。(请提供示例代码)

6 个答案:

答案 0 :(得分:6)

要走的路是named pipes,您可能需要查看不同Integrity levels之间的通信。

This article探讨了如何在vista中执行此操作。虽然它是用c ++编写的,但它只是基本的Windows API调用,所以它应该足够快地转换为Delphi。

如果您想要搜索有关此主题的更多信息,此通信称为进程间通信,但更好的搜索词是IPC。

答案 1 :(得分:5)

使用Indy,您可以相对轻松地在应用之间创建TCP连接。特别是如果你只需要发送字符串消息。对于客户端(在您的情况下是桌面应用程序),它基本上是

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

对于服务器(在您的情况下将是服务)

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;

只需实现HandleCommunication方法即可。只要客户决定发送内容,就会调用它。例如:

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只允许服务具有图形用户界面或具有网络访问权限,因此如果您的服务需要GUI(无论如何应该避免,请参阅此question),这可能会出现问题。我不知道Windwos Vista及其后来如何处理这个问题。

答案 2 :(得分:3)

查看Exchange Data between two apps across PC on LAN中的答案,这些答案现在几乎是同一个问题。通过TCP的本地通信是标准的。正如我在回答中所说,使用“远程过程调用”类型接口的解决方案效果很好。我使用RemObjects SDK进行此类操作,如果您希望以后更容易扩展以控制整个网络。

这两个允许您创建一个连接,大多数代码都是“透明”的,您只需调用一个通过线路发送数据并获得结果的接口。然后,您可以编写通常的编程方式,并忘记套接字的详细信息等。

答案 3 :(得分:3)

您必须将服务用户从localsystem更改为networkservice,然后该服务可以正常使用TCPIP。我有几个服务使用TCPIP作为外部控制挂钩。只需确保您的服务端口是可配置的,这样您就可以处理任何冲突。

我的一些控制接口基于从内部HTTP服务器提供的XML页面。这允许我使用可以到达该机器上的端口的任何Web浏览器远程检查服务的状态。与其他方法相比,使用HTTP的优势在于,当您需要在现有网络硬件上工作时,它可以很好地工作。

如果您只在本地进行通信,那么命名管道mail slots or a memory mapped file可能是最好的方法。

答案 4 :(得分:2)

我没有尝试过,但我认为你可以使用命名管道。

答案 5 :(得分:1)

我在我的服务应用程序中使用了一个组件集,免费软件,其源代码名为Simple IPC。

搜索torry.net。在与桌面应用程序通信时,它在我的所有服务应用程序中都运行良好。

约翰