Reputation: 739
I have two different processes (on the same session, both not elevated) that communicate using Named Pipes on a self-hosted service (hosted in the server process). On rare conditions (2-3% of the users), the client will not be able to connect o the server.
It happens only under UAC and with no elevation. To be perfectly clear, in most cases the app works perfectly fine for users with UAC and not-elevated sessions.
I found out that running everything as an Administrator resolves this issue, but I do not want to go this road. Also, changing the communication to netTcp resolves it too, but it prompts my users the Windows Firewall dialog, which is unacceptable for me.
I can't figure out why this happens or how to resolve it. I saw many posts about permissions required to create pipes, but as I see it, I don't need a global pipe, just a local one, which should not require UAC off/elevation/specific objects.
The server will show no error and act normally, but the client will show this:
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)
Server config:
<?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>
Client config:
<?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>
Upvotes: 2
Views: 1733
Reputation: 5049
I had a similar problem using named pipes for inter-process communication. The client app could only connect to the server app when the server app was run using "run as administrator", otherwise I would get an EndpointNotFoundException
from the client app.
This post described the core of the problem. If there is already a named pipe with an endpoint of net.pipe://localhost/
created with elevated rights, clients will fail to connect to a non-elevated endpoint like net.pipe://localhost/SomethingElse
.
This post helped me find the named pipes that were open on my system. Download the Sysinternals Suite, then use Handle.exe from an elevated command prompt to search for opened named pipes.
handle net.pipe
The names of the pipes use Base64 Encoding.
net.pipe:E<Base64EncodedValue>
net.pipe:EbmV0LnBpcGU6Ly8rL1RSQURFU0VSVklDRS9TRVJWSUNFMS8=
I used this link to decode the Base64 value.
bmV0LnBpcGU6Ly8rL1RSQURFU0VSVklDRS9TRVJWSUNFMS8=
net.pipe://+/TRADESERVICE/SERVICE1/
The named pipe that was causing the issue was
net.pipe:EbmV0LnBpcGU6Ly8rLw==
Which decoded to
net.pipe://+/
Note: + or * may be wildcards for localhost
Killing the offending process, or having it specify a more specific endpoint (like net.pipe://localhost/SomethingElse
) resolved the issue.
Upvotes: 1