I have a c# REST webservice that has a console host for debugging purposes. I need to add authentication mode to this service, my console host code looks like this:
WebServiceHost host = new WebServiceHost(typeof(WebService,new Uri[] { new(http://localhost:8000/")});
WebHttpBinding binding = new WebHttpBinding();
host.AddServiceEndPoint(typeof(WebService, binding, "");
host.Open();
Console.WriteLine("Testing Webservice through console. Press Enter to quit.");
Console.ReadLine();
host.Close(System.TimeSpan.Zero);
The authentication in web.config can be added by:
<system.web><authentication mode="Windows"/></system.web>
How can i add authentication mode to my console host?
When an application is running in IIS, it uses web.config to store settings. When you have a desktop application (ie a console app like yours), the same settings are stored in App.config.
Just go to 'Add New Item' and select 'Application Configuration File'. This will create an App.config file in your project, which is where you can put the WCF configuration.
Related
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.
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
I've got 2 applications:
Windows Service (with HTTP listener for config website & api)
Control Utility (WPF app)
The requirements of the control utility are pretty straightforward:
Start / stop service
Launch browser pointing to website (e.g. http://local:5555)
Looking for a Windows Service called "MyService", retrieve its status and start it when needed is pretty simple. However, how do I launch the browser with the correct link? The port which the HTTP listener is listening for is configurable inside the app.config of my Windows Service application and there is no possibility to discover the listener. Can a app.config be shared between 2 applications?
I know ConfigurationManager has OpenExeConfiguration(), but this causes other problems:
I have to know the path where the Windows Service is installed
Reading the configuration may cause a read lock
If the config file is encrypted, I have to know the key
Are there any other solutions to achieve this?
You could use the registry for exchanging data.
// Create a Subkey
RegistryKey newKey = Registry.CurrentUser.CreateSubKey("SOFTWARE\\SuperSoft\\App");
// Write Values to the Subkey
newKey.SetValue("Value1", "Content1");
newKey.SetValue("Value2", "Content2");
// read Values from the Subkey
if (SubKeyExist("SOFTWARE\\SuperSoft\\App"))
{
RegistryKey myKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\SuperSoft\\App");
string firstApp = (string)myKey.GetValue("Value1");
string secondApp = (string)myKey.GetValue("Value2");
}
[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.
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!