I am attempting to host a WCF net.pipe service within a Windows Service. I define the service in code, in the Windows Service's OnStart()
function. I also create the client in a similar way - in code.
I have seen this question asked but it always seems to be devoted only to situations where the NetNamedPipe is defined within the app/web.config file.
When attempting to call the service, I get the error:
System.ServiceModel.ProtocolException: The requested upgrade is not supported by 'net.pipe://localhost/manager'. This could be due to mismatched bindings (for example security enabled on the client and not on the server).
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.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.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 MyClientApp.IManager.HelloWorld()
Here is my code:
//Service Contract:
[ServiceContract]
public interface IManager
{
[OperationContract]
string HelloWorld();
}
//Service
public class Manager : IManager
{
public string HelloWorld()
{
return "Hello to you too!";
}
}
//Defining and starting the Net.Pipe Service from the Windows Service
public partial class MyWindowsService : ServiceBase
{
public MyWindowsService()
{
InitializeComponent();
}
private ServiceHost m_serviceHost;
protected override void OnStart(string[] args)
{
try
{
m_serviceHost = new ServiceHost(typeof(Manager), new Uri("net.pipe://localhost"));
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
m_serviceHost.AddServiceEndpoint(typeof(IManager), binding, "manager");
m_serviceHost.Open();
}
catch (Exception ex)
{
EventLog("MyWindowsService", ex.ToString(), EventLogEntryType.Error);
}
}
}
//The client proxy
public class ManagerProxy : ClientBase<IManager>
{
public ManagerProxy()
: base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IManager)),
new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/manager"))) { }
public string InvokeHellowWorld()
{
return Channel.HelloWorld();
}
}
The Interface is in a ClassLibrary project and is shared between the host application (the Windows Service) and the client application which is attempting to call the service.
The Service class and the OnStart function are in the Windows Service project.
The Service proxy is in the client project (which is, of course, being run from the same machine as the Windows Service).
Also, whenever I attempt to use the proxy, I find that its State == CommunicationState.Faulted
. I then close/abort it, and create a new ManagerProxy()
. The state of the ManagerProxy
is then Created
. I try to invoke HelloWorld
and get the above Exception
.
The next time I try to use it - its state is once again Faulted
and the process repeats.
The only difference I can see is that on the server side you create the binding with explicitly no security mode binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
and on the client side without a security mode new NetNamedPipeBinding()
. The exception message does mention security being a potential mismatch.
System.ServiceModel.ProtocolException: The requested upgrade is not supported by 'net.pipe://localhost/manager'. This could be due to mismatched bindings (for example security enabled on the client and not on the server).
Just checked here and the default security mode is not NetNamedPipeSecurityMode.None
it is NetNamedPipeSecurityMode.Transport
. So there is a mismatch there.