How to make a .NET Windows Service start right after the installation?

前端 未结 8 1319
再見小時候
再見小時候 2020-11-22 10:49

Besides the service.StartType = ServiceStartMode.Automatic my service does not start after installation

Solution

Inserted this code on my Pr

相关标签:
8条回答
  • 2020-11-22 11:27

    You can do this all from within your service executable in response to events fired from the InstallUtil process. Override the OnAfterInstall event to use a ServiceController class to start the service.

    http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx

    0 讨论(0)
  • 2020-11-22 11:28

    You need to add a Custom Action to the end of the 'ExecuteImmediate' sequence in the MSI, using the component name of the EXE or a batch (sc start) as the source. I don't think this can be done with Visual Studio, you may have to use a real MSI authoring tool for that.

    0 讨论(0)
  • 2020-11-22 11:29

    I've posted a step-by-step procedure for creating a Windows service in C# here. It sounds like you're at least to this point, and now you're wondering how to start the service once it is installed. Setting the StartType property to Automatic will cause the service to start automatically after rebooting your system, but it will not (as you've discovered) automatically start your service after installation.

    I don't remember where I found it originally (perhaps Marc Gravell?), but I did find a solution online that allows you to install and start your service by actually running your service itself. Here's the step-by-step:

    1. Structure the Main() function of your service like this:

      static void Main(string[] args)
      {
          if (args.Length == 0) {
              // Run your service normally.
              ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
              ServiceBase.Run(ServicesToRun);
          } else if (args.Length == 1) {
              switch (args[0]) {
                  case "-install":
                      InstallService();
                      StartService();
                      break;
                  case "-uninstall":
                      StopService();
                      UninstallService();
                      break;
                  default:
                      throw new NotImplementedException();
              }
          }
      }
      
    2. Here is the supporting code:

      using System.Collections;
      using System.Configuration.Install;
      using System.ServiceProcess;
      
      private static bool IsInstalled()
      {
          using (ServiceController controller = 
              new ServiceController("YourServiceName")) {
              try {
                  ServiceControllerStatus status = controller.Status;
              } catch {
                  return false;
              }
              return true;
          }
      }
      
      private static bool IsRunning()
      {
          using (ServiceController controller = 
              new ServiceController("YourServiceName")) {
              if (!IsInstalled()) return false;
              return (controller.Status == ServiceControllerStatus.Running);
          }
      }
      
      private static AssemblyInstaller GetInstaller()
      {
          AssemblyInstaller installer = new AssemblyInstaller(
              typeof(YourServiceType).Assembly, null);
          installer.UseNewContext = true;
          return installer;
      }
      
    3. Continuing with the supporting code...

      private static void InstallService()
      {
          if (IsInstalled()) return;
      
          try {
              using (AssemblyInstaller installer = GetInstaller()) {
                  IDictionary state = new Hashtable();
                  try {
                      installer.Install(state);
                      installer.Commit(state);
                  } catch {
                      try {
                          installer.Rollback(state);
                      } catch { }
                      throw;
                  }
              }
          } catch {
              throw;
          }
      }
      
      private static void UninstallService()
      {
          if ( !IsInstalled() ) return;
          try {
              using ( AssemblyInstaller installer = GetInstaller() ) {
                  IDictionary state = new Hashtable();
                  try {
                      installer.Uninstall( state );
                  } catch {
                      throw;
                  }
              }
          } catch {
              throw;
          }
      }
      
      private static void StartService()
      {
          if ( !IsInstalled() ) return;
      
          using (ServiceController controller = 
              new ServiceController("YourServiceName")) {
              try {
                  if ( controller.Status != ServiceControllerStatus.Running ) {
                      controller.Start();
                      controller.WaitForStatus( ServiceControllerStatus.Running, 
                          TimeSpan.FromSeconds( 10 ) );
                  }
              } catch {
                  throw;
              }
          }
      }
      
      private static void StopService()
      {
          if ( !IsInstalled() ) return;
          using ( ServiceController controller = 
              new ServiceController("YourServiceName")) {
              try {
                  if ( controller.Status != ServiceControllerStatus.Stopped ) {
                      controller.Stop();
                      controller.WaitForStatus( ServiceControllerStatus.Stopped, 
                           TimeSpan.FromSeconds( 10 ) );
                  }
              } catch {
                  throw;
              }
          }
      }
      
    4. At this point, after you install your service on the target machine, just run your service from the command line (like any ordinary application) with the -install command line argument to install and start your service.

    I think I've covered everything, but if you find this doesn't work, please let me know so I can update the answer.

    0 讨论(0)
  • 2020-11-22 11:38

    To start it right after installation, I generate a batch file with installutil followed by sc start

    It's not ideal, but it works....

    0 讨论(0)
  • 2020-11-22 11:38

    The easiest solution is found here install-windows-service-without-installutil-exe by @Hoàng Long

    @echo OFF
    echo Stopping old service version...
    net stop "[YOUR SERVICE NAME]"
    echo Uninstalling old service version...
    sc delete "[YOUR SERVICE NAME]"
    
    echo Installing service...
    rem DO NOT remove the space after "binpath="!
    sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
    echo Starting server complete
    pause
    
    0 讨论(0)
  • 2020-11-22 11:39

    To add to ScottTx's answer, here's the actual code to start the service if you're doing it the Microsoft way (ie. using a Setup project etc...)

    (excuse the VB.net code, but this is what I'm stuck with)

    Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall
        Dim sc As New ServiceController()
        sc.ServiceName = ServiceInstaller1.ServiceName
    
        If sc.Status = ServiceControllerStatus.Stopped Then
            Try
                ' Start the service, and wait until its status is "Running".
                sc.Start()
                sc.WaitForStatus(ServiceControllerStatus.Running)
    
                ' TODO: log status of service here: sc.Status
            Catch ex As Exception
                ' TODO: log an error here: "Could not start service: ex.Message"
                Throw
            End Try
        End If
    End Sub
    

    To create the above event handler, go to the ProjectInstaller designer where the 2 controlls are. Click on the ServiceInstaller1 control. Go to the properties window under events and there you'll find the AfterInstall event.

    Note: Don't put the above code under the AfterInstall event for ServiceProcessInstaller1. It won't work, coming from experience. :)

    0 讨论(0)
提交回复
热议问题