第三方应用程序打破了我们的WCF应用程

Obj*_*art 23 .net wcf net.pipe

我们的应用程序使用WCF而不是命名管道来在两个进程之间进行通信(注意:这两个进程都不是Windows服务.)我们的应用程序已经在现场运行了几年而没有发生任何事故.

我们现在收到报告称第三方应用程序(特别是Garmin Express)的存在正在打破我们的行为.我已经在内部安装了Garmin Express并确认了这一行为.特别是"Garmin核心更新服务"在运行时会导致我们的应用程序失败.

当Garmin服务运行时,我们的应用程序的"服务"端启动,并且创建WCF端点没有问题.但是当客户端启动并尝试连接到服务时,它会因EndpointNotFoundException而失败,就好像服务甚至没有运行一样.

此时,我可以从服务控制面板停止Garmin服务,然后成功重新运行客户端,甚至无需重新启动我们自己的服务.如果我再次启动Garmin服务,则进一步尝试启动客户端会失败.所以这至少证明了我们的WCF服务一直在运行,并且Garmin软件以某种方式阻止了我们客户端连接它的能力.

我们使用自己的名称作为端点地址(例如"net.pipe:// localhost/MyPrivateApplication").我已经尝试将此地址更改为其他各种名称,但这对此问题没有影响.

另一个应用程序如何通过运行来破坏我们自己的应用程序使用WCF的能力?

更新:根据请求,这是服务端的代码段.我已经从原始代码中简化了它,试图找出问题所在.到目前为止,我所做的改变并没有对这个问题产生任何影响.

MyService service = new MyService();
ServiceHost host = new ServiceHost(service);
string hostAddress = new Uri("net.pipe://localhost/MyWCFConnection");
host.AddServiceEndpoint(typeof(IMyService), new NetNamedPipeBinding(), hostAddress);
host.Open();
Run Code Online (Sandbox Code Playgroud)

Chr*_*son 15

一个可能的答案你的问题"另一个应用程序,只需通过运行,打破我们自己的应用程序......":

  1. 另一个应用程序也使用WCF NetNamedPipeBinding.
  2. 两个应用程序都使用基本+相对URL创建服务端点.
  3. 应用程序选择基址和HostNameComparisonMode使得客户端WCF堆栈用于定位服务元数据的URL变体之一上的应用程序之间存在名称冲突.

我不知道Garmin服务是否确实使用了WCF NetNamedPipeBinding,但这是你应该调查的一种可能性.始终使用NetNamedPipe端点的绝对URL可以避免此问题.


好的,所以在问题更新之后,我们现在知道Garmin服务正在使用WCF NetNamedPipeBinding,并且我们知道您的应用程序使用绝对地址注册其服务,因此上述解释并非完整的故事.

这是另一个假设:

  1. 假设Garmin服务在具有安全权限SeCreateGlobalPrivilege的进程中运行(除非经过特殊编码以禁用该权限,否则Windows服务将拥有该权限).
  2. 假设它还使用基地址net.pipe:// localhost和相对端点地址注册其WCF命名管道端点.
  3. 现在,它的服务元数据将使用全局命名空间中具有名称的共享内存映射对象发布.
  4. 您的服务应用程序不是Windows服务.我的假设是它的进程没有安全权限SeCreateGlobalPrivilege.如果是这种情况,则仅使用其本地会话命名空间中的共享内存映射对象发布其服务元数据.
  5. 现在,您的客户端进程尝试在Garmin服务运行时启动连接... WCF客户端通道堆栈NetNamedPipeBinding元素尝试根据您的服务URL net.pipe:// localhost/MyWCFConnection找到服务的服务元数据.如上面的链接所述,它将依次使用服务URL的各种变体执行搜索,以获得包含元数据的共享内存对象的名称.在查看Local命名空间之前,它首先在Global命名空间中查找完整的变体列表.
  6. 在这种情况下,第一次尝试将是从"net.pipe:// +/MyWCFConnection"派生的名称,并且可能无法在全局命名空间中找到具有此名称的对象.
  7. 但是,第二次尝试将基于变体"net.pipe:// + /",这将匹配在Global命名空间中发布的Garmin服务的共享内存映射的名称.由于搜索顺序,它永远不会获取在本地会话命名空间中发布的服务元数据.
  8. 您的客户端尝试连接到Garmin服务的管道.让我们假设Garmin服务已经实现了一些安全性,导致客户端被拒绝访问拒绝(例如,它可能在其管道上设置ACL).结果可能表现为EndpointNotFoundException.[ 后期编辑:实际上,最有可能发生的事情是您的客户端实际连接到Garmin服务,启动成帧协议的前导码握手,并收回成帧协议故障(http://schemas.microsoft.com/ws/) 2006/05/framing/faults/EndpointNotFound)因为Via记录中请求的URL与Garmin服务所期望的不匹配.绑定然后丢弃连接并将此错误作为EndpointNotFoundException呈现给您的客户端代码.

你能为这个做什么?我会建议:

  • 如果可以确认上述假设或类似的东西,并且Garmin正在使用base + relative相对寻址只使用net.pipe:// localhost,那么最好是让他们拥有问题:他们可以解决这个问题通过将他们的基地址更改为更可能是唯一的东西来轻松实现.
  • 您可以通过找到服务应用程序使用安全权限SeCreateGlobalPrivilege运行的某种方式来解决这个问题:如果不将其作为Windows服务或以管理员身份运行,这并不容易,但也许并非不可能.然后您的元数据也将在全局命名空间中发布,客户端的搜索将在Garmin之前找到它.
  • [稍后编辑]也许有一种解决方法,涉及将绑定的HostNameComparisonMode属性设置为Exact,并使用localhost的同义词作为服务URL的主机部分(例如net.pipe://127.0.0.1/MyWCFConnection).这可能会引导搜索Garmin变体,以便您的客户端有机会考虑本地会话命名空间中的名称.我不知道它会起作用,但值得一试,我想.
  • 还有一个很长的镜头:贵公司是否与微软有产品支持关系?可以说这是WCF中一个严重的设计缺陷:如果你对此大惊小怪,你可能会让微软为它发出一个QFE补丁,例如提供一个绑定属性来告诉客户端堆栈只尝试Local命名空间.

  • 感谢您的解决方案建议,我实际上已经尝试过(将比较模式设置为Exact并尝试除本地主机之外的主机名.)不幸的是,它似乎没有帮助.令人惊讶的是,显然没有办法从客户端引导全局表中的搜索模式. (2认同)

小智 7

我们微软已经将问题归结为Garmin核心更新服务创建命名管道的方式.可以在不同的范围 - 全局和本地创建命名管道.全局范围本质上是机器范围的,而Local是特定于用户的.Garmin的应用是

一个.作为系统服务运行,因此侦听命名管道服务的范围是全局的.

湾 监听"net.pipe:// localhost /"的根地址(例如,没有任何子路径/段).

C.使用StrongWildcard主机名比较模式.

d.项目a到c意味着Garmin的应用程序基本上是任何与更具体的内容不匹配的网络管道连接的全能.

即 这也意味着Garmin完全阻止所有使用本地范围的侦听器

对此的理想修复是Garmin应用程序的更改,以便它使用更具体的URL注册其net.pipe侦听器.

  • 我认为微软应该计划修复它或热修复它.我们刚刚发现服务"HP支持解决方案框架服务"也导致了这个问题. (2认同)

Cam*_*tta 6

我找到了一种方法来显示哪些应用程序使用net.pipe(虽然不一定正确使用它).

首先从sysinternals下载Handle应用程序:

https://technet.microsoft.com/en-us/sysinternals/handle.aspx?f=255&MSPPError=-2147217396

然后以管理员身份打开命令提示符,并运行"Handle.exe net.pipe"(减去引号).这将列出当前正在运行的net.pipe的所有应用程序.从那里,你可以一次杀死或禁用一个,直到你的罪魁祸首被发现.我几乎没有超过4-5个进程使用它.如果您无法以管理员身份运行命令提示符,则可能会给出0结果.

以下是我发现的干扰net.pipe的所有应用程序:

  • "HP支持解决方案框架服务" - 仅受影响的某些版本
  • "Garmin核心更新服务" - 修复了较新版本但开箱即用
  • "WBE服务" - 由几台戴尔笔记本电脑与无线扩展坞配合使用
  • "英特尔(R)安全协助"服务 - 我在2016年初在几台Win10笔记本电脑上看到过.
  • "Baraccuda WSA服务" - 网络安全代理.如果您禁用此功能,可能会让客户感到不安.
  • "DropboxOEM.exe" - Dropbox的一个变种,包含在商店购买的PC中.到目前为止只在Win10上注意到了.这个是独一无二的,因为它是我发现的第一个不是Windows服务,我能说的最好.
  • "MTC服务" - 安装在一些Getac品牌PC上.不确定它的作用.
  • "pcdrcui.exe" - 不是服务,而是以管理员身份运行.戴尔SupportAssist的组件.
  • "Mitchell1/Shopkey SE Con​​nection"或"ShopHubService"或"Mitchel1/Shopkey数据备份服务" - 数据同步服务.不确定它做了什么.

我支持需要net.pipe的应用程序,因此我会更新此列表,因为我找到了更多服务来执行此操作.

  • 非常感谢您的回复,非常有帮助,让我们省去了很多麻烦!我们的情况与OP完全相同,并且能够按照您的指示找到罪魁祸首;在我们的例子中,它是 Wonderware InTouch HMI 系统附带的 **“Wonderware InTouch IData Service”** (`SE.Scada.Asb.InTouchDataService.exe`)(我不知道它到底有什么作用)。终止此进程突然使我们基于 WCF 的应用程序再次正常运行。 (2认同)
  • 在我们的例子中,它是 **WKSSTrayNotification.exe**(不是服务,而是 Addison Software 的托盘应用程序部分)。这是德国软件编辑器 Datev 的知识库文章,其中包含另一个罪魁祸首列表:https://www.datev.de/dnlexom/client/app/index.html#/document/1080431 (2认同)