126

I have a Windows Service which I install using the InstallUtil.exe. Even though I have set the Startup Method to Automatic, the service does not start when installed, I have to manually open the services and click start. Is there a way to start it either via the command line, or through the code of the Service?

GEOCHET
  • 21,119
  • 15
  • 74
  • 98
mickyjtwin
  • 4,960
  • 13
  • 58
  • 77

13 Answers13

232

In your Installer class, add a handler for the AfterInstall event. You can then call the ServiceController in the event handler to start the service.

using System.ServiceProcess;
public ServiceInstaller()
{
    //... Installer code here
    this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall);
}

void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
    ServiceInstaller serviceInstaller = (ServiceInstaller)sender;

    using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
    {
             sc.Start();
    }
}

Now when you run InstallUtil on your installer, it will install and then start up the service automatically.

comecme
  • 6,086
  • 10
  • 39
  • 67
codemonkey
  • 5,257
  • 2
  • 18
  • 16
  • 40
    (comment from a proposed edit): Better to use serviceInstaller.ServiceName, if the servicename gets changed it will use the correct name without needing to change it in the code. – Marc Gravell Feb 01 '11 at 09:46
  • 1
    It also wouldn't hurt to wrap the `ServiceController` in a using statement. – ChrisO Oct 21 '13 at 10:00
  • I needed to specify the id of the service installer in the OnBeforeInstall. Something like serviceInstaller = serviceInstaller1; where the serviceInstaller1 is the id from the designer. Doing this in the OnBeforeInstall made the above work flawlessly for me. I didn't try but you may be able to do it in the ServiceInstaller() call as well. – Micah Montoya Sep 05 '16 at 17:03
  • You also can use "Display name" of the service instead of serviceInstaller.ServiceName. – SurenSaluka Oct 21 '16 at 07:53
  • 3
    How are you getting serviceInstaller? – Philip Rego Dec 01 '16 at 16:47
  • 1
    serviceInstaller is supposed to be the `ServiceInstaller` variable in your class. Such class shall implement `System.Configuration.Install.Installer`. See this [msdn guide](https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx) for more information. – Sergio Basurco Jan 17 '17 at 12:44
  • 4
    @PhilipRego Presumably `serviceInstaller` is the `ServiceInstaller` object referred to by `sender` in the event handler, which is normally instantiated in the `ServiceInstaller()` constructor. Therefore you might add `ServiceInstaller serviceInstaller = (ServiceInstaller)sender;` before the `using` statement. – khargoosh Feb 10 '17 at 01:20
  • This is another one of those little-known things that Microsoft hardly explains, doesn't make a property in their IDE, and doesn't have an option in their Visual Studio Installer Projects free extension to do. I hope one also realizes that if they use Visual Studio Installer Projects to make an install, that they add a custom action with these extra steps: [Use a Compiled Setup Project to Install the Windows Service](https://support.microsoft.com/en-us/help/816169/how-to-create-a-setup-project-for-a-windows-service-application-in-vis). – Volomike Oct 08 '17 at 02:29
  • 1
    This saved my day...only one changed.. I used.. this.serviceInstaller.ServiceName – Ziggler Dec 20 '18 at 01:38
32

After refactoring a little bit, this is an example of a complete windows service installer with automatic start:

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace Example.of.name.space
{
[RunInstaller(true)]
public partial class ServiceInstaller : Installer
{
    private readonly ServiceProcessInstaller processInstaller;
    private readonly System.ServiceProcess.ServiceInstaller serviceInstaller;

    public ServiceInstaller()
    {
        InitializeComponent();
        processInstaller = new ServiceProcessInstaller();
        serviceInstaller = new System.ServiceProcess.ServiceInstaller();

        // Service will run under system account
        processInstaller.Account = ServiceAccount.LocalSystem;

        // Service will have Automatic Start Type
        serviceInstaller.StartType = ServiceStartMode.Automatic;

        serviceInstaller.ServiceName = "Windows Automatic Start Service";

        Installers.Add(serviceInstaller);
        Installers.Add(processInstaller);
        serviceInstaller.AfterInstall += ServiceInstaller_AfterInstall;            
    }
    private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
    {
        ServiceController sc = new ServiceController("Windows Automatic Start Service");
        sc.Start();
    }
}
}
Fenix
  • 2,271
  • 1
  • 16
  • 24
Pedro Pereira
  • 480
  • 5
  • 12
  • 2
    This code gave me the following error/s: An exception occurred during the Install phase. System.InvalidOperationException: An exception occurred in the OnAfterInstall event handler of System.ServiceProcess.ServiceInstaller. The inner exception System.InvalidOperationException was thrown with the following error message: Cannot start service serviceName on computer '.'.. The inner exception System.ComponentModel.Win32Exception was thrown with the following error message: The executable program that this service is configured to run in does not implement the service. – goamn May 01 '14 at 01:27
  • 2
    The errors seized once I commented out the line "InitializeComponent()". I believe this line is duplicating all the other lines as the logs seem to show two identical things happening at together before the error: Installing service serviceName... Service serviceName has been successfully installed. Creating EventLog source serviceName in log Application... Installing service serviceName... Creating EventLog source serviceName in log Application... An exception occurred in the OnAfterInstall event handler of System.ServiceProcess.ServiceInstaller. – goamn May 01 '14 at 01:28
  • You really saved my day :) Thank you for this useful comment. After I had commented out InitializeComponent() call, my service also started perfectly – Konstantin Feb 28 '18 at 14:21
9

How about following commands?

net start "<service name>"
net stop "<service name>"
Hemant
  • 19,486
  • 24
  • 91
  • 127
5

Programmatic options for controlling services:

  • Native code can used, "Starting a Service". Maximum control with minimum dependencies but the most work.
  • WMI: Win32_Service has a StartService method. This is good for cases where you need to be able to perform other processing (e.g. to select which service).
  • PowerShell: execute Start-Service via RunspaceInvoke or by creating your own Runspace and using its CreatePipeline method to execute. This is good for cases where you need to be able to perform other processing (e.g. to select which service) with a much easier coding model than WMI, but depends on PSH being installed.
  • A .NET application can use ServiceController
Richard
  • 106,783
  • 21
  • 203
  • 265
4

You can use the following command line to start the service:

net start *servicename*
AlexDrenea
  • 7,981
  • 1
  • 32
  • 49
4

Here is a procedure and code using generated ProjectInstaller in Visual Studio:

  1. Create Windows Service project in Visual Studio
  2. Generate installers to the service
  3. Open ProjectInstaller in design editor (it should open automatically when installer is created) and set properties of generated serviceProcessInstaller1 (e.g. Account: LocalSystem) and serviceInstaller1 (e.g. StartType: Automatic)
  4. Open ProjectInstaller in code editor (press F7 in design editor) and add event handler to ServiceInstaller.AfterInstall - see the following code. It will start the service after its installation.

ProjectInstaller class:

using System.ServiceProcess;


[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent(); //generated code including property settings from previous steps
        this.serviceInstaller1.AfterInstall += Autorun_AfterServiceInstall; //use your ServiceInstaller name if changed from serviceInstaller1
    }

    void Autorun_AfterServiceInstall(object sender, InstallEventArgs e)
    {
        ServiceInstaller serviceInstaller = (ServiceInstaller)sender;
        using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
        {
            sc.Start();
        }
    }
}
Fenix
  • 2,271
  • 1
  • 16
  • 24
2

Use ServiceController to start your service from code.

Update: And more correct way to start service from the command line is to use "sc" (Service Controller) command instead of "net".

arbiter
  • 9,447
  • 1
  • 32
  • 43
1

Despite following the accepted answer exactly, I was still unable to get the service to start-- I was instead given a failure message during installation stating that the service that was just installed could not be started, as it did not exist, despite using this.serviceInstaller.ServiceName rather than a literal...

I eventually found an alternative solution that makes use of the command line:

private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e) {
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.FileName = "cmd.exe";
        startInfo.Arguments = "/C sc start " + this.serviceInstaller.ServiceName;

        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();
    }
Matsu Q.
  • 468
  • 1
  • 9
  • 17
0

Automatic startup means that the service is automatically started when Windows starts. As others have mentioned, to start it from the console you should use the ServiceController.

Michael Klement
  • 3,376
  • 3
  • 30
  • 34
  • I do not wish to do this. I am looking to do this in one go from the command line, or from within the Windows Service classes. – mickyjtwin Jun 24 '09 at 06:41
  • Sorry, my bad, I missed the point where you explicitly excluded the possibility of starting it over the control panel. – Michael Klement Jun 24 '09 at 06:54
0

You can use the GetServices method of ServiceController class to get an array of all the services. Then, find your service by checking the ServiceName property of each service. When you've found your service, call the Start method to start it.

You should also check the Status property to see what state it is already in before calling start (it may be running, paused, stopped, etc..).

adrianbanks
  • 81,306
  • 22
  • 176
  • 206
0

Just a note: You might have set up your service differently using the forms interface to add a service installer and project installer. In that case replace where it says serviceInstaller.ServiceName with "name from designer".ServiceName.

You also don't need the private members in this case.

Thanks for the help.

0

This is OK for me. In Service project add to Installer.cs

[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent();
    }
 
    protected override void OnAfterInstall(IDictionary savedState)
    {
        base.OnAfterInstall(savedState);
 
        //The following code starts the services after it is installed.
        using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            serviceController.Start();
        }
    }
}
ismail uzunok
  • 163
  • 1
  • 1
  • 14
0

You corrupted your designer. ReAdd your Installer Component. It should have a serviceInstaller and a serviceProcessInstaller. The serviceInstaller with property Startup Method set to Automatic will startup when installed and after each reboot.

Guillaume Massé
  • 8,004
  • 8
  • 44
  • 57