WCF命名管道未知错误

时间:2015-02-08 16:49:25

标签: wcf named-pipes

我有两个不同的进程(在同一个会话中,都没有提升),它们使用自托管服务上的命名管道进行通信(托管在服务器进程中)。 在极少数情况下(2-3%的用户),客户端将无法连接服务器。

它仅在UAC下发生且没有高程。要非常清楚,在大多数情况下,应用程序对于具有UAC和未提升的会话的用户来说非常好。

我发现以管理员身份运行一切可以解决这个问题,但我不想走这条路。此外,将通信更改为netTcp也会解决它,但它会提示我的用户使用Windows防火墙对话框,这对我来说是不可接受的。

我无法弄清楚为什么会发生这种情况或如何解决它。我看到很多关于创建管道所需权限的帖子,但正如我所看到的,我不需要全局管道,只需要本地管道,不需要UAC关闭/提升/特定对象。

服务器将显示无错误并正常运行,但客户端将显示:

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

Server stack trace: 
   at System.ServiceModel.Channels.ConnectionUpgradeHelper.DecodeFramingFault(ClientFramingDecoder decoder, IConnection connection, Uri via, String contentType, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at MyApp.BL.Interfaces.Service.IWCFClientServiceAPI.Initialize()
   at MyApp.Main.attemptConnection(WCFStoreAPIClient& i_WCFClientServiceAPI, IWCFClientCallbackAPI& i_WCFClientCallbackAPI)

服务器配置:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="MyApp.Client.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="Locales"/>
    </assemblyBinding>
  </runtime>
  <system.serviceModel>
    <bindings>
      <netNamedPipeBinding>
        <binding name="NPBinding_IWCFClientServiceAPI" transactionProtocol="OleTransactions" receiveTimeout="infinite" maxConnections="200" maxBufferSize="3145728" maxBufferPoolSize="3145728" maxReceivedMessageSize="3145728"/>
      </netNamedPipeBinding>
    </bindings>
    <services>
      <service
          name="MyApp.Client.Core.Managers.WCFClientService"
          behaviorConfiguration="WCFClientServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="net.pipe://localhost/MyAppServices/" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="netNamedPipeBinding" contract="MyApp.BL.Interfaces.Service.IWCFClientServiceAPI" bindingConfiguration="NPBinding_IWCFClientServiceAPI">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WCFClientServiceBehavior">
          <serviceMetadata httpGetEnabled="False"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

客户端配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <netNamedPipeBinding>
        <binding name="NPBinding_IWCFClientServiceAPI" transactionProtocol="OleTransactions" receiveTimeout="infinite" maxConnections="200" maxBufferSize="3145728" maxBufferPoolSize="3145728" maxReceivedMessageSize="3145728"/>
      </netNamedPipeBinding>
    </bindings>
    <client>
      <endpoint address="net.pipe://localhost/MyAppServices"
                binding="netNamedPipeBinding"
                bindingConfiguration="NPBinding_IWCFClientServiceAPI"
                contract="MyApp.BL.Interfaces.Service.IWCFClientServiceAPI"
                name="NPBinding_IWCFClientServiceAPI">
        <headers>
          <ClientIdentification>MyAppStore</ClientIdentification>
        </headers>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>

1 个答案:

答案 0 :(得分:0)

我在使用命名管道进行进程间通信时遇到了类似的问题。客户端应用程序只能在使用“以管理员身份运行”运行服务器应用程序时连接到服务器应用程序,否则我将从客户端应用程序获得EndpointNotFoundException。

post described the core of the problem。如果已经使用提升权限创建了端点为“net.pipe:// localhost /”的命名管道,则客户端将无法连接到非提升端点,如“net.pipe:// localhost / SomethingElse”。

我的系统上打开的post helped me find the named pipes。下载Sysinternals Suite,然后从提升的命令提示符处使用Handle.exe来搜索已打开的命名管道。

handle net.pipe

管道的名称使用Base64编码。

net.pipe:E<Base64EncodedValue>
net.pipe:EbmV0LnBpcGU6Ly8rL1RSQURFU0VSVklDRS9TRVJWSUNFMS8=

我使用了link to decode the Base64 value

bmV0LnBpcGU6Ly8rL1RSQURFU0VSVklDRS9TRVJWSUNFMS8=
net.pipe://+/TRADESERVICE/SERVICE1/

导致此问题的命名管道是

net.pipe:EbmV0LnBpcGU6Ly8rLw==

解码为

net.pipe://+/

注意:+或*可能是localhost的通配符

解决违规流程,或让它指定更具体的端点(如net.pipe:// localhost / SomethingElse)解决了这个问题。