我有一个应用程序需要由第二个应用程序调用。这些应用程序需要在没有配置的情况下找到彼此(最好不接触注册表)并在终端服务环境中正常运行。我听说使用命名管道的.net 远程处理可能是实现此目的的一种方法,但我不明白如何将管道限制为只能在创建它的会话中访问。谢谢
更新:我对 WCF 很好,问题不是特定于远程处理,而是如何将命名管道设置为会话的本地。
我有一个应用程序需要由第二个应用程序调用。这些应用程序需要在没有配置的情况下找到彼此(最好不接触注册表)并在终端服务环境中正常运行。我听说使用命名管道的.net 远程处理可能是实现此目的的一种方法,但我不明白如何将管道限制为只能在创建它的会话中访问。谢谢
更新:我对 WCF 很好,问题不是特定于远程处理,而是如何将命名管道设置为会话的本地。
如果您的应用程序在 Windows Vista 或 Windows 7 上运行,并且您正在使用 WCF NetNamedPipeBinding,您将自动获得只能从同一会话中访问的服务,前提是实现管道服务端的进程没有SeCreateGlobalPrivilege 权限。实际上,这通常意味着服务器可以是交互式会话中启动的任何程序,前提是它不是以管理员身份运行的。
原因与 WCF 创建的命名共享内存对象有关,该对象用于将实际管道名称(GUID)发布给潜在客户端。我在我的博客上解释了这个机制。如果服务进程有SeCreateGlobalPrivilege,则这个发布对象创建在对所有会话可见的全局内核命名空间中;如果它没有此权限,则该对象将在仅在同一会话中可见的本地内核命名空间中创建。请注意,这并不提供绝对的安全性:如果管道名称 GUID 以其他方式公开,则命名管道本身理论上可以从另一个会话(使用本机 API 调用而不是 WCF 客户端堆栈)访问。
如果您需要支持较早的操作系统,或者如果您希望管道本身具有绝对安全性,则需要在 WCF 服务通道堆栈创建管道后通过修改管道上的 DACL 来显式实施限制。这需要对标准绑定进行一些修改,我在这里展示了如何做到这一点。您还需要编写一些不是特别简单的 P/Invoke 代码来发现正确的登录会话 SID,以便在 DACL 中为其创建 ACE。在 .NET 4 中,WCF 服务堆栈本身发现并使用登录会话 SID 来限制创建新管道实例的权限,因此您可以使用 Reflector 来看看它是如何做到这一点的 - 请参阅:System.ServiceModel.Channels.SecurityDescriptorHelper.GetProcessLogonSid()
.
我一直在研究这个确切的问题。到目前为止,我发现(但尚未尝试)的最佳解决方案是使用会话 id创建一个唯一的命名管道名称。
我建议为此使用Windows Communication Foundation。
您可以选择在不使用注册表的情况下配置所有不同的通信选项,包括使用命名管道、套接字等。