Querying a Windows Service over a Network - c#

I have written a windows service in C# that gathers performance, disk and memory information and writes it to the EventLog. It is enabled as a network service. What I would like to do is be able to gather this information from a remote location. This service will run at various client machines and I would like to retrieve this information periodically (once a day) and store them in a database table. I am confused as to how one can query a windows service over a network. In other words, what exactly makes the service a "Network Service"?
I do not want the service to directly connect to my database and write this information. But I would like to initiate it from a remote machine, retreive the information and then write that information to my database table.
I was unable to find any tutorial that illustrates a networked windows service. Most of them covered writing to event logs and I am pretty much stuck there.
Is this doable, are there any suggestions about how this sort of stuff is done?

If the other suggestions to move over to WCF Web services are not an option, you can do allot with Custom commands in a windows service without having to resort to remoting.
Effectively you can send an integer between 128 & 256 and then have your service execute whatever code you need it to when it receives that command, like sending all the information to your database or web service.
You will be able to initiate it from your side as and when you need to while the service happily trundles along on the client machines.
Take a look at this code project article for an example: Creating a Basic Windows Service in C#
Take a look at the OnCustomCammand method.
Here's another example article from Microsoft: Communicate With Windows Services

Use WCF to enable some form of a RESTful Web Service.
See wcf-getting-started on MSDN, and specially A Guide to Designing and Building RESTful Web Services with WCF.

AFAIK 'Network Service' just means that it is running under the "Network Service" account which has a different set of permission than the 'Local Service' or 'System' accounts.
To expose a service to another machine on the network however (apart from the standard STOP, START, RESTART functionality that you get through the services snap-in - services.msc) you will need to create your service using something like Remoting, Webservices or most ideally as gimel mentioned WCF.

Related

I have two console apps one is client other server and they communicate using WCF. How to run those apps like different users in VS

Secyrity service represents server.I want to run Client for example like Mark and Secyrity service as John(https://i.stack.imgur.com/V8yRA.png)
I was following pdf file from my profesor and it is reffering me to Computer Managment into local users and groups section but i dont know what is there to do.
If you want to run code on the service in context of the user of the client you need to use impersonation: https://learn.microsoft.com/en-us/dotnet/framework/wcf/how-to-impersonate-a-client-on-a-service
If you want to know a more complete wcf service setup process, you can refer to the steps in this docs, from creating wcf services, configuration files, wcf clients, testing, step by step.

Is it possible to print through .NET code from an Azure Worker Role

To start off with, I am aware of this question that seems to ask the same thing. However I'm going to ask it again with a slight modification.
I'm working on a project to print PDF's. We have a library for PDF manipulation. We can use it to render a PDF to a file that the System.Drawing.Printing.PrintDocument object can use and print in c#. We are going to have an Azure Worker role that takes many 1-page pdf's and turns them into one large pdf, and I would like to have another Azure Worker Role that then spools that large PDF to a Windows Print Server here locally.
Since the printing part is so much slower (compared to the pdf creation/aggregation piece) I would like to be able to host it in azure to easily scale.
My initial thought was "I don't think this is even possible. How would Azure be able to know anything about my local print server." Which is the basic answer from the above similar question. But after some searching, I found some results that seem to indicate setting up a VPN Site-To-Site Tunnel or ExpressRoute Connection would let me do what I want. However I'm relatively new to Azure and the results I found are short on actual, useful, helpful details.
If it can't be done, fine, I can set up an application server locally to do the printing. But if someone has ideas or more insight on how to accomplish this I would love to hear it.
Basically, you could store PDFs into Azure Blob Storage like:
http://azureaccount.blob.core.windows.net/PDF/pdf1.pdf
Then you define an Azure Queue entity like:
MyQueue(Pdf_Id, Pdf_Blob_Url)
MyQueue(1, http://azureaccount.blob.core.windows.net/PDF/pdf1.pdf)
MyQueue(2, http://azureaccount.blob.core.windows.net/PDF/pdf2.pdf)
and submit to the Azure Queue.
Then on your Printing server, just setup an application to check the AzureQueue to process the PDFs. At this point, just get the PDFs directly from Azure blob storage url to do anything you want like merging, printing,....
Without getting into the VPN / Site-To-Site setups, here is an Idea:
You could have a small application hosted on your network that uses Service Bus Relay to expose a WCF service (this will allow incoming connections to the service from the role)
The worker role can consume this Service and then send the PDF for printing to it.
Your App would send the PDF to the printer via PrintDocument object you mentioned.
See:
https://azure.microsoft.com/en-gb/documentation/articles/service-bus-dotnet-how-to-use-relay/
What is the Service Bus relay? The Service Bus relay service enables
you to build hybrid applications that run in both an Azure datacenter
and your own on-premises enterprise environment. The Service Bus relay
facilitates this by enabling you to securely expose Windows
Communication Foundation (WCF) services that reside within a corporate
enterprise network to the public cloud, without having to open a
firewall connection, or require intrusive changes to a corporate
network infrastructure.

Transfer data between websites

I need some architectural advice on how to build a background service application.
Background:
I have 2 websites, and I need to transfer some data from website A to website B. Service
would have to run in a background (as windows service) and should connect (every 5 minutes)
to websites's A database directly (MSSQL) grab some data and insert this data through
websites's B API (API is build on MVC Web Api). Both websites are hosted on a same virtual
machine (Windows Server 2008 R2 Datacenter), but this might change (website B can be switched to another virtual server or cloud hosting as Windows Azure or Amazon AWS).
Question:
What do you suggest (best practices) and what guidelines you can give me? I want this to
be scalable and fast as possible and that service will receive multiple requests.
Thank you,
Jani
If it is important to know what data was transferred, then:
Add logs - log4net for instance
Issue tickets if the process stops, and close the ticket when it restarts, this way you will know if a process fails. Depending on the amount of data use you could use Redis/Riak.
Put monitoring on each service A and B, and you might also consider restarting the service via IIS on fail down.

IIS vs Windows Service?

I have a C# application that needs to always be running. I originally planned on making this a windows service but I now have a requirement to make the application host a web admin console.
I haven't played with IIS in quite a few years so my question is this:
What would you recommend I use?
I've thought about making a windows service and embedding a web server such as Cassini but so far I'm not very happy with the open source web servers I've looked at.
Can IIS handle this? Do people use it for this type of scenario, and if so how?
This sounds like a job for two separate projects.
One is the original Windows Service. Windows Services are well suited for what you're doing.
The second is the Web Project that will be used to administer the Windows Service. This is the part that runs in IIS.
It depends on what you mean by always running. An ASP.NET web application deployed in IIS could very well be unloaded by the web server if there aren't any requests for certain amount of time killing all background threads. So if you want an ever running background thread it would be better suited to use a Windows Service. As far as the web admin is concerned, well, here you don't have much choice: ASP.NET in IIS. In order to do something useful those two applications should be able to find a common language to talk. So you could use a database to store the results into which could be used by both applications.
IIS will run your app on first request, not on server boot. So you will still need to run a service to ensure your app is always running.
You can use IIS as a webserver for your web admin part, and link your ASP.net app with your service by means of a configuration database (easy) or webservices (a little more tricky).
Windows and Web services are two very different creatures. A web service will expose external methods that you can implement against an application, while a windows service is an entity within itself. If you're planning on using this service on a timed interval to perform an operation, a Windows service would be the right way to go. If you use a web service, you will need to invoke the method you wish to run from a secondary application.
If you need to queue commands against your windows service, you could always create a database that was accessible by both your website and your windows service. This way you could send commands and query data between the two. Placing a web service in to serve as an intermidary between the two may be overkill.

Call A Windows Service from a remote computer

I am going to be coding up a windows service to add users to a computer (users with no rights, ie just for authentication). (As a side note, I plan to use this method.)
I want to be able to call this windows service from another computer.
How is this done? Is this a tall order? Would I be better off just creating a Web Service and hosting it in IIS?
I have some WCF services hosted in IIS on the calling computer (they will do the calling to the proposed windows service). I have found that Hosting in IIS is somewhat problematic, so I would rather not have a second IIS instance to manage unless I need to.
(I will be using Visual Studio 2008 SP1, C# and Windows Server 2003 (for both caller and service host).
Thanks for the help
If you are thinking of hosting a web service in IIS just to communicate with an NT-service on that same machine, that is definitely more trouble than it is worth in this case.
As other answers have indicated you can make a WCF service with the operations you need and host that within the same NT-service that you want to interact with. You can easily secure this with certificates, or user accounts to make sure it is only controlled by the right people/machines.
If you need to control the NT-service itself, there are existing programs such as sc.exe to start, stop, configure, or query the status of your NT-service remotely.
However, you may want to consider seeking a solution without the overhead of creating an custom NT-service and a custom WCF service to interact with it. If you do, the Net User commands (sorry no link - new user limitation) or the AddUsers (see kb 199878/en-us) utility may be sufficient. If your remote "controller" can invoke these commands directly against the target machine you may not have to create any custom software address this need. Additionally you would have less software to maintain and administer on the target machine. You would just be using the built-in OS capabilities and admin utilities.
Finally, you will need to think about the security aspect, NT-services and IIS are usually run under very restricted accounts, many auditors would flip-out over any service running with sufficient permission to create or modify users locally, and especially on other machines. You'll want to make sure that the service could never be used to create users that do have more than the "authenticate" permission you indicated.
Edit: The net user command may not work against another machine's local users, but check out. pspasswd that along with PsExec to create users, should do what you need remotely.
Simply host a WCF service in the Windows Service. You'll then be able to call it remotely.
You can host a WCF service inside a Windows service. Take a look at the TCP binding (NetTcpBinding class). Both client and server will have to use WCF, but that doesn't sound like it will be an issue with your implementation.
Also, the section entitled "Hosting in Windows Services" in this MSDN article provides a walk-through of the process
If the windows service publishes a remoting interface then it can be accessed via that remoting interface.
Otherwise it's the same as accessing any other process running on a remote machine except that there may be some tools (e.g., sc) with built in support for executing against a remote machine (barring firewall complications).
Any IPC mechanisms applies; sockets, web services, remoting, etc...
You could expose a WCF service directly from your windows service. When you start up your windows service, in addition to spinning up any other background processes, you could create an instance of ServiceHost<T> for your service implementation. This would allow you to not only provide WCF access, but also avoid the extra instance of IIS like you requested, and provide TCP, Named Pipes, and WsHttp endpoints. This should give you some nice flexibility in the performance tuning arena, since it sounds like this service will be consumed internally on your network, rather than externally.
You could create a WCF service which will talk to your Windows service on the remote box. Host the WCF component in IIS (or however you'd like so that you can communicate with it) and then call the WCF component from your remote machine.

Categories