【问题标题】:Delphi 2009: How to communicate between Windows service & desktop application under Vista?Delphi 2009:如何在 Vista 下的 Windows 服务和桌面应用程序之间进行通信?
【发布时间】:2010-11-18 14:42:11
【问题描述】:

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

【问题讨论】:

  • 太棒了!我问了几乎同样的问题,而且我也比较谦虚,但我得到的只是批评而不是答案...... ;-)

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    查看Exchange Data between two apps across PC on LAN 中的答案,这与当今的问题几乎相同。通过 TCP 的本地通信是标准的。正如我在回复中所说,使用“远程过程调用”类型接口的解决方案效果很好。我使用RemObjects SDK 来处理这类事情,如果您以后愿意,它可以很容易地扩展以控制整个网络。

    这两种方法都允许您创建一个对于大多数代码来说都是“透明”的连接,并且您只需调用一个接口,该接口通过网络发送数据并返回结果。然后你就可以按照平常的方式进行编程,而忘记套接字等的细节。

    【讨论】:

    • 服务是否必须具有特殊权限才能使用网络,即使它只是在本地侦听?
    • @Rob,这取决于服务运行的帐户。
    • 无论是使用系统帐户还是用户帐户,我在使用 RemObjects 时都没有遇到任何问题。这个问题更多地与域用户权限有关,而不是独立的 TCP/IP 套接字访问。
    • 服务可以使用 TCP 套接字(RAW 套接字除外),而无需考虑用户帐户。
    【解决方案3】:

    使用 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 和更高版本中处理的。

    【讨论】:

      【解决方案4】:

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

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

      如果你想搜索更多关于这个主题的信息,这种通信称为进程间通信,但更好的搜索词是 IPC。

      【讨论】:

      • 这绝对是真的吗?我已经完成了几个充当 TCP 服务器和 TCP 客户端的 Windows 服务。它们都作为“本地系统”运行良好。我一直认为限制是网络资源(//machine/resource/...)。
      • 第一个断言完全是假的。我曾经编写过的每个 Windows 服务都是某种网络守护进程。唯一需要时髦权限的地方是还需要能够显示 UI。
      • 是的,我记错了,不允许创建到外部资源的网络连接,或者你必须作为NetworkService运行。我删除了第一个断言。但是,命名管道仍然是与您的服务通信的更好方式(在查找有关 IPC 的 vista 兼容性文章时遇到问题)
      • 我选择命名管道方法是因为 (1) 客户端和服务器都在同一台机器上,并且 (2) 我不想处理 TCP/IP 连接的端口#冲突/配置.
      【解决方案5】:

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

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

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

      【讨论】:

      • 使用 TCP 不需要使用 NetworkService 帐户。它也适用于 LocalSystem 和 LocalService 帐户。
      【解决方案6】:

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

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

      约翰

      【讨论】:

        猜你喜欢
        • 2011-12-09
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多