C# register the same windows service with different parameters - c#

I need to create many windows services to host many WCF Service so I can stop a single one (for example to update it) and keep the other running.
Since I don't want to create a windows service for every WCF Service I have, I'm trying to create a C# application that can register itself as a windows service but with different parameters (and service name of course).
For example calling it this way:
MyService.exe /install WcfService1.dll
MyService.exe /install WcfService2.dll
This creates two different windows service like these:
WcfService1 -> MyService.exe /run WcfService1.dll
WcfService2 -> MyService.exe /run WcfService2.dll
I can't find a way to do this other than editing directly the registry.

I've found a nicer way to do it: sc.exe
sc.exe create WcfService1 binPath= "MyService.exe /run WcfService1.dll"
so I just need to create a bat/cmd to launch this command.

By its nature, a service is designed to be the go-to process for dealing with a particular thing, and having multiple instances is generally not a good idea. However, it is possible to do what you want; for instance, you can have multiple instances of SQL Server running at one time.
Have a read of this. Basically, your service installer can be given some command-line or other configurable argument that will tell it the name to which it should register itself in Windows as a service. This is normally automatic based on the service installer's and service executable's properties, but all of this can be set dynamically as well. Change the name, and you change the service registration. The name of the service should be (AFAIK) inspectable by the executable being run as the service, which can tell it the WCF service for which it is responsible.

Related

Starting a service programmatically

I'm struggling with starting a service from another application.
Ok, first, that's my starting point:
I got a usual service wrapped into my own class which inherits from ServiceBase.
Furthermore I got a ProjectInstaller instance, which inherits from System.Configuration.Install.Installer and takes care of installing my service on the system in the right way.
it's got these parameters:
serviceInstaller1.ServiceName = "NameOfService";
serviceInstaller1.StartType = System.ServiceProcess.ServiceStartMode.Manual;
serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService;
This ProjectInstaller output is installed through a usual C# .NET installation project.
The service is shown in the GUI list of services within system control -> administration -> services. But what I'm wondering about is that the service does not appear in the list of services, if I use the cmd.exe and type "net start".
That's waht I have so far.
Now I want to start my service from another application. This application inherits from
ServiceController
If I want to call now the
Start()
method, I get an error telling me that the service could not be opened of the local machine.
I use the same Service Name as stated above. T'm confused about that, because I thought the service is installed correctly through my installer.
Or does my application (and the cmd.exe too) does not have enough rights to access the service?
I found this article on stackoverflow.
I think this answer posted there can be applied here too.
see the link below
ServiceController permissions in Windows 7
I've run into this issue before, and it was permissions-based for me, too. I wish that error message was a little more clear.
I'd recommend taking a look at this SO article: C#.NET: Acquire administrator rights? - it looks like there's a good tutorial about upgrading to administrative rights provided in the answers.

Running a C# console application as a Windows service

I have a basic C# console application that I would like to run as a Windows Service.
I have created the Windows service using sc create. This worked fine, and I can see my service under services.msc. When I try and start this service I get the following error:
Could not start the PROJECT service on Local Computer. Error 1053: The service did not respond to the start or control request in a timely fashion.`
I read that this might be due to the service code taking longer than 30000 ms to execute. Therefore I removed the bulk of the code so that hardly anything is being executed.. yet the same error persists.
I am using .NET 3.5 for this project.
What would cause this?
You cannot just take any console application and run as Windows service. First you need to implement your service class that would inherit from ServiceBase, then in entry point (Main) you need to run the service with ServiceBase.Run(new YourService()). In your service class you need to define what happens when service starts and ends.
Ideally you should add ServiceInstaller to your assembly too. This way you will be able to preset your service properties, and use installutil.exe to install the service.
Walkthrough: Creating a Windows Service Application in the Component Designer is a walkthrough of how to create a service.
Not any old application can be run as a service, especially under more recent versions of Windows. They are expected to support certain functionality, respond to certain requests, and (again, under recent versions of Windows) not interact with the user directly.
If you want a service, write an application specifically designed to be a service.
I do not know what "sc create" is. But I know, using Visual Studio 2010, one can build a Windows service project. By the way, I have created a project of this kind and it does work well all the way.
why is this so? – wulfgar.pro Jun 3 '11 at 1:13
#WulfgarPro - because windows service application has a little
different architecture. You need to define what to do when service starts and ends. – Alex Aza Jun 3 '11 at 1:15
(Unfortunately I can't write a comment yet.)
It is because SCM (Service Control Manager) controls the service trough ServiceBase Class. If one would only need to define what it does when it starts and stops there would be no need for inheritance and overriding. One could simply create those two methods. Unfortunately there is a bit more work involved because ServiceBase contains a bit more functionality.
I have had great success with TopShelf. This is a nuget package that allows your .NET console app to also have the necessary Windows Service hooks such that it can happily run as either a console app (useful for debugging), or be installed as a Windows Service.

Testing Windows Service in .Net

I'm developing a windows service in C# .Net and i'm having some dificulty to execute and test my service.
I'm using a timer component to run it from time to time and execute my methods. I have to intialize the service all the time to run it.
Anyone know a more practical way to test a service?
This often boils down to the question what you want to test. Do you want to test the service, or the functionality that it performs? Personally I would...
Refactor all of the service functionality into a separate class library
Test the library
Invoke the library functionality from the service
...and then keep the amount of code in the service itself to the bare minimum needed to trigger the functionality in the class library.
Windows services are ordinary EXEs that happen to connect to the service control manager on startup.
I normally test services by giving them an optional command line argument that tells them to execute normally, inside the Main method, instead of acting as a service. That way I can debug them directly within Visual Studio, or on the command line, etc.
You probably want to add unit tests to your service.
It sounds like you could benefit more from adding your application to the Task Scheduler instead of running it as a service.
Other than that if you really need it as a service you need to design it so it can be tested. I usually write my services in a separate class and add a .EXE project to it so I can run it from the command line too.
One of the ways I have run services when developing is along these lines - Run a windows service as a console. I have found it useful because you can add code to write out to the console for debug information and writing out any relevant exception data.
I would not use this method instead of unit tests but I found this to be a useful way to work and debug where needed.
After create window service you can set it into window service.
Install service using InstallUtil.exe
To install or uninstall windows service (which was created using .NET Framework) use utility InstallUtil.exe. This tool can be found in the following path (use appropriate framework version number).
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe
To install .NET service run command similar to this (specify full path to your service).
InstallUtil.exe "path of service"
To uninstall .NET service use the same command with parameter /u.
InstallUtil.exe /u "path of service"

Passing a Windows Service Parameters for it to act on

I want to turn a program I have into a service so I can use it without logging it. Basically what it does is it backs up specified folders to a specified location using SSH. However the problem I'm running into is I don't know how to tell it these items. I only know how to start, stop, and run a custom command with only an integer with a parameter.
How can I do this?
Windows Service, not a Web Service
edit: The folders it backs up will not remain consistent and will be updated at every runtime
You can instantiate your service and pass command line arguments using the ServiceController class.
using (ServiceController serviceController = new ServiceController(serviceName))
{
string[] args = new string[1];
args[0] = "arg1";
serviceController.Start(args);
}
"arg1" will then be available as regular command line arguments in main() when Windows starts up the service.
I see that you (or someone) voted Sebastian Sedlak's answer down, because he mentioned hosting a WCF Service in the Windows Service. Your reply was
It's in nice bold lettering in the question. Not a Web Service, therefor WCF is out of the question
I think you misunderstood what he meant. He wasn't talking about a Web Service. He was talking about hosting a WCF Service within your Windows Service.
It's far from the same thing. You can host a WCF Service within any Windows (Forms/Console/Service) application. The point of doing so, is that the application is then reachable for communciation via its internal WCF Service, in the same fashion as you can communicate with a Web Service (you can also host WCF Services in IIS, btw, which would then make them "Web Services", in the sense you seem to be referring to).
In a Windows Service, this means you can send any command to it and also get any information you want from it - while it's running.
In fact, I am working on a project right now, which is a Windows Service that I need to be able to contact and pass commands to - and get information from - at runtime. For example, I want to be able to tell it where to store certain things, what to log, to have it reset/restart - and poll it for status messages. I do this by hosting a WCF Service inside the Windows Service. That WCF Service exposes a set of methods, that in my case includes receiving commands and returning status information. So when the Windows Service is running, I can contact it (even remotely), via its built-in WCF Service and tell it what to do.
This an extremely easy thing to implement, and in the case of Windows Services, can provide you with a much richer interface to the Service than through the basic standard commands.
However, you specified that you wanted your Windows Service to receive its folder settoings each time it starts up, which makes such a passive setup less than ideal (as it would be unable to do anything until you passed it the right folders).
One way to deal with this (using a hosted WCF Service), would be to have the Windows Service running all the time (i.e. automatic startup). Its default state would be idle. Then you could issue it a "start processing"-command, feeding it the correct folders to work on (through a call to the corresponding WCF Service method). Similarly, the WCF Service would expose methods giving you the status of the application (current folder, progress, busy/idle etc). Once the processing is done, it would go back into the idle state, waiting for the next set of folders to be supplied to it.
Doing it this way would make it very easy to control remotely - you could even make an online administration panel for it, accessible from anywhere.
The issue, is that, while passing in parameters is not difficult, when the machine restarts and windows tries to restart the service, those parameters are not there. they only exist when someone starts the service from the command line.
for example. I have a windows service which hosts a WCF service. I want the users to be able to specify a non-default port number for the WCF service to listen on. They do this by starting the windows service like so... MyService -port:xxxxx
Which works fine, until the server is rebooted, then windows restarts MyService (but without parameters) and the wcf service defaults to original port #
Any service is capable of receiving command line arguments at start-up.
Would it be possible to use a configuration file to specify these items?
Store the service's startup parameters in the registry: and then, when the registry starts, it should read its startup parameters from the registry.
Windows services have executables like any other. I believe you can write it to accept command-line parameters and specify those parameters in the Windows Service configuration. You can also have it read a config file. If you're using .NET, there are config file classes in the framework.
Why not just Host a WCF Service in the Windows Service to obatain such "admin" functions?
(Remoting is also possible)
RE: config file.
Of course a config file can be used.
And the file can be changed while the service is running.
This would be a nice solution if the config file changes in fact.
All my services use an XML config file, wrapped in a class for easy reuse.
The wrapper has an option to monitor the XML file using fileMonitor for changes, optionally refreshing the content of the config file automatically, and finally raises an event to the service class.
The service then has the option of "resetting" itself as needed to incorporate the new values in the XML configuration file.
Placing configuration into the registry has a few issues:
Security (ie: installer being granted access), depending on what tree is used
The service will not be aware of changes
Portability - although minor as the install should setup registry settings
Where an XML file is easy to copy, edit, share, view and understand.
Throw in some good COMMENT blocks and a detailed XSD file, and it becomes a source of good documentation too.
Look into XPath for easy navigation and extraction of values within the XML file.
$0.02
... david ...
Concerning the app.config file - I'm rather sure that your service will read and use those files as I write all my windows-services this way ;)
So just put everything you need in the app.config under "application" (not user) and put allway edit the "yourname.exe.config" in the folder where you "InstallUtil" the service from.

Send administrative commands to my C# Windows Service using own PowerShell CmdLets

I have a C# Windows application which runs a service. I would like to leverage PowerShell in order to offer a command line management interface for administering my running service.
From my point of view, I am trying to offer the same administrative interface a la Exchange 2007.
Do you have any suggestion or sample code on how to start/design the management cmdlets in order "connect" to the running service to query or send administrative commands?
How can I access service's internal runtime state from powershell command line? For example I would like to implement a cmdlet called Get-ConnectionsInfo to find out how many outbound connections my Windows service is using when the cmdlet is executed.
A practical example or web link to an example would be more than welcomed.
Thanks,
Robert
A solution would be for your Windows Service to expose an administrative interface through WCF. Your PowerShell commands would use this WCF service to pull out information and make the Windows Service perform actions.
The key here is to start by writting an API that you can access from .Net, then you can easily wrap the calls to this API into a DLL that exposes classes that are PowerShell cmdlets. If you want someone to be able to administer your service remotely then I think probably the best thing is to create either a webservice or WCF Service that does this and then you can wrap that in PowerShell. If you have a look on codeplex you will find some examples of administer remote web based services like GoGrid and SQL Data Services that will give you some sample code to get you started.
Another way of exposing the internal state of the Windows Service came to mind. You could expose information through WMI which can be consumed from PowerShell or your PowerShell commands.
I'm not sure if you are able to tell your service to perform actions through WMI but you would at least be able to pull out state.
A third alternative might be to make the Windows Service be a PowerShell content provider. However I have never made one myself so I'm not sure if they're suitable for hosting in a Windows Service, since the service might not be running all the time.

Categories