在C#中使用NetNamedPipeBinding获取EndpointNotFoundException;需要创建全局命名管道

时间:2011-09-19 22:00:41

标签: c# netnamedpipebinding

我正在运行一个Windows服务,我通过NetNamedPipeBinding向其发送消息。消息从客户端应用程序发送,该应用程序由GPO触发。我刚刚在新服务器上安装了服务和客户端,我收到以下消息:

System.ServiceModel.EndpointNotFoundException: 
There was no endpoint listening at 
net.pipe://localhost/VOXAServices/VOXADefaultPipe that could accept the
message. This is often caused by an incorrect address or SOAP action.
See InnerException, if present, for more details.

没有内在的例外。如果我通过双击桌面上的图标运行客户端应用程序,它运行没有问题。我管理Windows服务和客户端应用程序的代码,所以我可以改变我需要的任何东西。但到目前为止,我非常确信绑定,合同和地址都是正确的(因为从桌面运行时一切运行正常)。我认为问题必须是从GPO运行客户端应用程序。但我想不出有什么理由会导致这个错误。

更新

我在微软的网站上看到了这个:

  

命名管道是Windows操作系统内核中的对象,例如   作为进程可以使用的共享内存的一部分   通讯。命名管道具有名称,可用于单向或   单个机器上进程之间的双工通信。

     

当a上的不同WCF应用程序之间需要通信时   单台计算机,你想阻止任何通信   另一台机器,然后使用命名管道传输。 另外一个   限制是从Windows远程桌面运行的进程可能   限制为相同的Windows远程桌面会话,除非他们   拥有提升的特权。

Choosing a Transport,强调增加)

我需要客户端进程在(非特权)用户的上下文中运行,并且弹出UAC对话框不是一个选项。反正让我在保持进程在用户上下文中运行而不是让用户具有特权的情况下给这个客户端进程提升了权限吗?

更新#2:

似乎存在全局和本地(对于Windows会话)命名管道这样的事情。我相信我的Windows服务正在创建一个本地命名管道,如果我可以强制它创建一个全局命名管道,它将解决我的问题。 (这解释了为什么我在sysinternals“Process Explorer”中看不到我的管道,即使我的客户端应用程序可以找到它,如果我从特权会话启动它)。问题是,我不知道(并且似乎无法找到)如何强制全局创建命名管道(c#)。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

The mechanism by which WCF clients find WCF service NetNamedPipe endpoints涉及内核共享内存对象,服务使用该对象告诉客户端要使用的管道的实际名称。如果客户端将与服务器位于不同的登录会话中,则此共享内存对象必须位于Global而不是Local内核命名空间中。命名管道本身具有单个命名空间,对所有客户端都可见。您不能直接控制WCF用于共享内存对象的命名空间,但它将是全局内核命名空间,前提是您的服务器是使用SeCreateGlobalPrivilege运行的Windows服务。你的问题似乎暗示是这种情况,所以我怀疑你的问题是否与内核对象命名空间有关。

另外两个可能的原因是:

  1. 保护共享内存对象和命名管道的ACL。这些将始终拒绝访问具有NETWORK USERS组成员身份的任何安全上下文(SID S-1-5-2)。这将强制WCF保证不能远程访问命名管道端点。

  2. 如果您在Vista或更高版本上运行,客户端进程的强制完整性级别不得低于内核对象的强制完整性级别(这将是隐含级别 - 中级 - 除非您已采取使用强制完整性标签提升的特殊步骤

  3. 我对GPO启动的客户端流程运行的安全上下文不太了解,但我建议您检查这两种可能性并相应地更新您的问题。