Connect to a self hosted WCF service - c#

So we have a 3rd party software that has it's own API we use to retrieve calculated data inside application only, when ever we try to run a WCF service through the API it runs, and the state is showing as OPEN but we try to add this Service as a Service Reference we can't connect to it for some reason .
The service port is not showing in opened ports list, could the be due to WCF is started on a different thread(3rd party application thread).
I am following this tutorial :
https://blogs.msdn.microsoft.com/brunoterkaly/2013/11/01/wcf-service-hosting-how-to-host-a-wcf-service-from-inside-a-windows-presentation-foundation-application/
which works fine when we create our own software to host the WCF.
The idea behind using WCF in a 3rd party software is we are trying to access calculated data from this software and get it in another client application.
Please your help is needed.

WCF service was no being detected because i have it inside using statement
using(ServiceHost myServ = new ServiceHost(typeof(HelloWorldService), baseAdress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
myServ.Description.Behaviors.Add(smb);
myServ.Open();
MessageBox.Show("Services is :" + myServ.State + "\n" + baseAdress);
}
once the using(){} is removed the WCF is working as a charm

Related

Consume WCF Service over named pipe hosted in WPF app from Windows Service

I host a WCF Service in a WPF appilication which updates the GUI using a named pipe. In a Windows Service I consume this WCF-Service to update the GUI.
I host it in my WPF app with the following code:
private ServiceHost serviceHost;
public MainWindow()
{
InitializeComponent();
try
{
string address = "net.pipe://localhost/Path/ServiceName";
serviceHost = new ServiceHost(typeof(ComGUIService));
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
serviceHost.AddServiceEndpoint(typeof(IComService), binding, address);
serviceHost.Open();
}
catch (Exception ex)
{
// TODO: Logging & Handling
}
}
And consume it in my Windows service:
string address = "net.pipe://localhost/Path/ServiceName";
NetNamedPipeBinding binding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None);
EndpointAddress ep = new EndpointAddress(address);
IComService channel =
ChannelFactory<IComService>.CreateChannel(
binding, ep
);
try
{
channel.SendUpdatedStatus("test");
}
catch (Exception e)
{
// Throws: The pipe endpoint net.pipe://localhost/... could not be found on your local machine
}
System.IO.PipeException: There was no endpoint listening at net.pipe://localhost/... that could accept the message
The strange thing is, the exact same code works when it is excecuted in a Console app and the communication to the WPF app is successfull. Is there something special about the communication between a Windows Service and a desktop app through named pipes? Is this even possible?
I had the same issue going on. The problem is your service runs in session 0 when running as a service and your app in session 2. You see it working when running the service as a console, because both apps are running under the same session 2 (no additional perms needed). The named pipe has to be created in a shared memory space for the service to actually see the named pipe, and when they are running different sessions you will see this problem crop up. The solution is to simply allow "create Local Object" permission to the necessary users/groups. Go into group policy editor. Windows Settings -> Security Settings -> local Policies -> User Rights Assignments -> Create global objects (add user group to this permission and you should be good to go!). Good luck!
I managed to get it working. The only thing I had to do was to run the WPF application with administrative privileges. Why the communication between those application only works when the WPF application is running as Administrator is still a mystery.

Circular Dependency Issue

I am currently trying to learn how to create a WCF service and I am facing an issue.
I have a project lets call it MainProject which is a console application and a second project called SoapServer which is created as a class library.
The MainProject doesn't need to reference the SoapServer but the SoapServer does need to reference stuff from within the MainProject.
However, even though MainProject doesn't need to access SoapServer at the moment it does so that the console application can start the host on the WCF service.
However, this obviously causes a circular dependency as I can't have MainProject refernece SoapServer and visa versa. Is there a way to get a round this.
Below is how I am opening the connection for the WCF Service.
public class SoapServer : ISoapServerInterface
{
public void startSoapServer()
{
Uri baseAddress = new Uri("http://localhost:6525/hello");
using (ServiceHost host = new ServiceHost(typeof(SoapServer), baseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.Open();
Console.WriteLine("The service is ready at: {0}", baseAddress);
Console.WriteLine("Press <Enter> to stop the service");
Console.ReadLine();
host.Close();
}
}
Thanks for any help you can provide.
There shouldn't be much code in hosting application (MainProject). It is responsible only for hosting the service and this is its sole purpose. Don't place commonly-used code there.
Instead create another class library with commonly-used code and create references to it from SoapServer and from MainProject.

WCF Service application without gui that will stay alive

[WCF newbie]
I have a basic client-server WCF project.
My Service is "gui"less application, meaning that I created winform application, removed the Form1.cs and the lines that starts the gui.
The service is running ok, I am using servicehost.open..
My problem is that it is "serial" (sync), so after a second the application exists.
How can i keep the application alive and listening to the host ?
I need to halt the process and then to host.close when I want to end it.
Thanks
This is code of service:
class Program
{
public static Uri BaseAddress;
[STAThread]
static void Main(string[] args)
{
string baseAddressStr = "http://localhost:7000/someservice";
BaseAddress = new Uri(baseAddressStr);
using (ServiceHost host = new ServiceHost(typeof(MyClass)BaseAddress))
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
host.Description.Behaviors.Add(smb);
host.Open();
host.Close();
}
}
}
I don't think you want to host your WCF service in a windowless WinForms app.
If you want it to stay open indefinitely, the way to go is to host the WCF service in a Windows Service. Here you have a basic sample.
The benefits should be obvious:
Can run even if no user is logged in.
Does not require a workaround for keeping the application open.
Additionally, you should consider externalizing your WCF configuration (like the base address, service behavior) to the application configuration file. You don't want to rebuild and redeploy your service each time something (anything) changes in the configuration, which may vary from development, test, acceptance and production environments.

How to consume Windows Communication Foundation (WCF) by a Windows Service

When i create a Windows Service for getting information from a Web Application(ASP.NET c#) for scheduling some task in the client machine.
To consume WCF from the web application. I added WCF reference
to Window Service project as a service reference, everything seems fine. It
updated app.config file, added service reference etc.
it was not working. Any idea will be very helpful.
My Code is shown below
string result = string.Empty;
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://test.com/Service.svc/DevicesService");
using (ChannelFactory<IDevicesService> myChannelFactory = new ChannelFactory<IDevicesService>(myBinding, myEndpoint))
{
IDevicesService wcfClient1 = myChannelFactory.CreateChannel();
result = wcfClient1.CheckNetworkConnection(IPLocalHost);
if (!string.IsNullOrEmpty(result) && result.Equals(IPLocalHost))
{
EventLog.WriteEntry("Test connection succeeded");
}
else
{
EventLog.WriteEntry("No live connection currently available");
}
((IClientChannel)wcfClient1).Close();
}
I find it easier, when building a windows service, to build a console application that performs the same work as the service will. I abstract out the actual working code (e.g. your code snippet above) into a separate assembly and then just invoke it from either my service's start method or the console's main method.
If you move your code above into a console application, does it work? If it doesn't, can you step through it and let us know where it fails. And when it fails, what exception information are you seeing?
Let us know and we'll help!

Can a WebServiceHost be changed to avoid the use of HttpListener?

I am looking for a way to use a WCF WebServiceHost without having to rely on the HttpListener class and it's associated permission problems (see this question for details).
I'm working on a application which communicates locally with another (third-party) application via their REST API.
At the moment we are using WCF as an embedded HTTP server. We create a WebServiceHost as follows:
String hostPath = "http://localhost:" + portNo;
WebServiceHost host = new WebServiceHost(typeof(IntegrationService), new Uri(hostPath));
// create a webhttpbinding for rest/pox and enable cookie support for session management
WebHttpBinding webHttpBinding = new WebHttpBinding();
webHttpBinding.AllowCookies = true;
ServiceEndpoint ep = host.AddServiceEndpoint(typeof(IIntegrationService), webHttpBinding, "");
host.Open()
ChannelFactory<IIntegrationService> cf = new ChannelFactory<IIntegrationService>(webHttpBinding, hostPath);
IIntegrationService channel = cf.CreateChannel();
Everything works nicely as long as our application is run as administrator. If we run our application on a machine without administrative privileges the host.Open() will throw an HttpListenerException with ErrorCode == 5 (ERROR_ACCESS_DENIED).
We can get around the problem by running httpcfg.exe from the command line but this is a one-click desktop application and that's not really as long term solution for us.
We could ditch WCF and write our own HTTP server but I'd like to avoid that if possible.
What's the easiest way to replace HttpListener with a standard TCP socket while still using all of the remaining HTTP scaffolding that WCF provides?
Your problem is not related to HttpListener.
Your problem is:
* You have a oneClick application with limited permissions that
* Tries to open a Server port.
This is a contradiction. An untrusted limited permission application should NOT OPEN A SERVER PORT. This is why this is not allowed per definition.
Have you tried opening a normal socket port? It should not work either.
In general, limited trust end user applications should not host a web service ;)
That said, I ahve been in a similar situation trying to use WCF in a driver communication scenario - thank heaven my application runs with full permission.
You can easily compose your own stack via CustomBinding, using the higher level protocol stuff "as is", and rolling your own version of HttpTransport that isn't backed by HttpListener or IIS. Do-able, sure, but it's a lot of work. Take the existing HttpTransport bits apart with Reflector- there are a LOT of moving parts in there. You could probably hack up a simple PoC over Socket in a day or two if you don't need anything fancy like HTTPS or chunking, but making it robust will be tricky. Here's a good wrapup of a bunch of resources (may be a bit dated now).
You could also look at ripping apart enough of Cassini to make it hostable in your app, and loading the WCF pipeline in there (via .svc files and the service activation handler)- it'd require writing very little new code that way, but still give you a fairly robust and tested webserver.

Categories