4

We need to control the Windows Service remotely using the .net application. Example: we have 10 windows services on different services. Now I want to create the application(I guess it is also a windows service) to start and stop these service remotely, and also install or uninstall them via command line.

First thing is to collect these services name. Then using a loop or if/else I guess. Before that I want to make sure all services are installed. I don't want to access service manager to install services, I want to implement it in the code. I got a hint from somewhere but still not sure exactly.

ServiceInstaller.InstallService("\"" + _applicationPath + "\\" + _applicationName + ".exe\" -service", _applicationName, _applicationName, autoInstall, autoRun);
internal static bool InstallService(string svcPath, string svcName, string svcDispName, bool autoStart, bool startNow)
    {
        #region Constants declaration.
        int SC_MANAGER_CREATE_SERVICE = 0x0002;
        int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
        int SERVICE_DEMAND_START = 0x00000003;
        int SERVICE_ERROR_NORMAL = 0x00000001;
        int STANDARD_RIGHTS_REQUIRED = 0xF0000;
        int SERVICE_QUERY_CONFIG = 0x0001;
        int SERVICE_CHANGE_CONFIG = 0x0002;
        int SERVICE_QUERY_STATUS = 0x0004;
        int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
        int SERVICE_START = 0x0010;
        int SERVICE_STOP = 0x0020;
        int SERVICE_PAUSE_CONTINUE = 0x0040;
        int SERVICE_INTERROGATE = 0x0080;
        int SERVICE_USER_DEFINED_CONTROL = 0x0100;
        int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
        SERVICE_QUERY_CONFIG |
        SERVICE_CHANGE_CONFIG |
        SERVICE_QUERY_STATUS |
        SERVICE_ENUMERATE_DEPENDENTS |
        SERVICE_START |
        SERVICE_STOP |
        SERVICE_PAUSE_CONTINUE |
        SERVICE_INTERROGATE |
        SERVICE_USER_DEFINED_CONTROL);
        int SERVICE_AUTO_START = 0x00000002;
        #endregion Constants declaration.

        try
        {
            int dwStartType = SERVICE_AUTO_START;
            if (autoStart == false) dwStartType = SERVICE_DEMAND_START;

            IntPtr sc_handle = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
            if (sc_handle.ToInt32() != 0)
            {
                IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, dwStartType, SERVICE_ERROR_NORMAL, svcPath, null, 0, null, null, null);
                if (sv_handle.ToInt32() == 0)
                {
                    CloseServiceHandle(sc_handle);
                    return false;
                }
                else

My questions:

1) How to collect services?

2) How to start/stop the services?

3) Install service code, no clue.

3 Answers3

3

You can use the ServiceController class to remotely control services on another computer provided that your application is running with the necessary rights and nothing like a firewall is blocking the connection.

  1. Get all services on a remote computer:

    var services = ServiceController.GetServices(machineName);
    
  2. To start and stop a specific service on a remote computer you can use LINQ to get a specific service from the list retrieved above:

    var services = ServiceController.GetServices(machineName);
    var service = services.First(s => s.ServiceName == "MyServiceName");
    service.Start();
    ...
    service.Stop();
    

    Another option is to get a specific service on a specific machine:

    var service = new ServiceController("MyServiceName", machineName);
    
  3. To install a new service you have multiple options. If you are writing your own services in .NET you can create an MSI package using WiX. You can also use the ServiceInstaller class with or without InstallUtil.exe or you can install any service even remotely using SC.exe.

    However, to install a service remotely you still should place the executable file of the service locally on the remote computer. So installing a service remotely really involves getting the service onto the remote computer and then run some process to perform the actual installation which will create the correct entries in the registry database. You will have to decide if you want to use file shares, WMI, remote PowerShell or perhaps Active Directory to distribute the software.

Martin Liversage
  • 96,855
  • 20
  • 193
  • 238
0

Maybe using net command from the shell is a way to go? It is able to list, start, stop services etc. You'll feel a little 'dirty' if you use it, but heck, it will work.

How do I restart a service on a remote machine in Windows?

An yes, I would recommend wrapping that under simple WEB service app.

Also to read: Simplest way to restart service on a remote computer

Community
  • 1
  • 1
Daniel Mošmondor
  • 19,070
  • 12
  • 53
  • 95
  • I was told that I had to design a controller to execute commands from command line. Your links don't have to how install services. –  Sep 30 '13 at 12:58
0

What about ServiceController class?

http://msdn.microsoft.com/library/system.serviceprocess.servicecontroller.aspx

If service isn't installed ServiceController.Status will throw InvalidOperationException

ServiceController.GetServices() will get you a list of services. It can work on remote computers too, but the code must have correct permissions (impersonation, maybe?)

There is also this: http://www.codeproject.com/Articles/4242/Command-Line-Windows-Services-Manager

In Windows InstallUtil.exe can be used to install/uninstall services. But you must use the correct version: there can be more than one, depending on .NET version and system (x64, x32). On your own machine (I don't know about remote machines) the correct path is:

 string path = Path.Combine(System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory(), "InstallUtil.exe");

You can execute a process on another machine using PsExec or WMI

EDIT:

.bat script to install a service on your own machine (x64 version of installutil installs x64 version of service):

@ECHO OFF

REM The following directory is for .NET 2.0
set DOTNETFX2=%SystemRoot%\Microsoft.NET\Framework64\v2.0.50727
set PATH=%PATH%;%DOTNETFX2%

echo Installing WindowsService...
echo ---------------------------------------------------
InstallUtil /i "service path goes here"
echo ---------------------------------------------------
echo Done.
Arie
  • 4,869
  • 2
  • 28
  • 49
  • So the manager itself is a windows service or a generic class? –  Sep 30 '13 at 13:12
  • @Love if you are talking about the codeproject post, I think it's a console application. InstallUtil.exe is also a console app. You go: "installutil -i [servicepath]" to install a service and use "-u" parameter to uninstall – Arie Sep 30 '13 at 13:22