C version Windows service installation and uninstallation gadget

  • 2021-10-27 08:36:26
  • OfStack

Preface
In our work, we often encounter the installation and uninstallation of Windows service. Before, the company also wrote an WinForm program to choose the installation path. This time, we will have a small and flexible console program, which can be installed or uninstalled only by putting it in the directory where the service needs to be installed.

Development ideas
1. Due to the permission restriction of the system, it is necessary to run the program as an administrator
2. Because you need to realize the functions of installation and uninstallation, you need to enter 1 or 2 when you prompt the program to install or uninstall this operation
3. Next, the program will find the executable files in the current directory and filter the program itself and sometimes the files with vhost that we copy in, and list them for the operator to choose (only one in general)
4. Install or uninstall according to the user's selection
5. Because the operation may be repeated, it is necessary to call 1 recursively
Concrete realization
To operate the service first, you need to encapsulate the implementation class with System. ServiceProcess


using System;
using System.Collections;
using System.Configuration.Install;
using System.Linq;
using System.ServiceProcess;

namespace AutoInstallUtil
{
  public class SystemServices
  {
    /// <summary>
    ///  Open System Services 
    /// </summary>
    /// <param name="serviceName"> System service name </param>
    /// <returns></returns>
    public static bool SystemServiceOpen(string serviceName)
    {
      try
      {
        using (var control = new ServiceController(serviceName))
        {
          if (control.Status != ServiceControllerStatus.Running)
          {
            control.Start();
          }
        }
        return true;
      }
      catch
      {
        return false;
      }
    }


    /// <summary>
    ///  Shut down system services 
    /// </summary>
    /// <param name="serviceName"> System service name </param>
    /// <returns></returns>
    public static bool SystemServiceClose(string serviceName)
    {
      try
      {
        using (var control = new ServiceController(serviceName))
        {

          if (control.Status == ServiceControllerStatus.Running)
          {
            control.Stop();
          }
        }
        return true;
      }
      catch
      {
        return false;
      }
    }

    /// <summary>
    ///  Restart system services 
    /// </summary>
    /// <param name="serviceName"> System service name </param>
    /// <returns></returns>
    public static bool SystemServiceReStart(string serviceName)
    {
      try
      {
        using (var control = new ServiceController(serviceName))
        {
          if (control.Status == System.ServiceProcess.ServiceControllerStatus.Running)
          {
            control.Continue();
          }
        }
        return true;
      }
      catch
      {
        return false;
      }
    }

    /// <summary>
    ///  Return to service status 
    /// </summary>
    /// <param name="serviceName"> System service name </param>
    /// <returns>1: Service is not running  2: Service is starting  3: Service is stopping  4: Service is running  5: Service is about to continue  6: Service is about to be suspended  7: Service has been suspended  0: Unknown state </returns>
    public static int GetSystemServiceStatus(string serviceName)
    {
      try
      {
        using (var control = new ServiceController(serviceName))
        {
          return (int)control.Status;
        }
      }
      catch
      {
        return 0;
      }
    }

    /// <summary>
    ///  Return to service status 
    /// </summary>
    /// <param name="serviceName"> System service name </param>
    /// <returns>1: Service is not running  2: Service is starting  3: Service is stopping  4: Service is running  5: Service is about to continue  6: Service is about to be suspended  7: Service has been suspended  0: Unknown state </returns>
    public static string GetSystemServiceStatusString(string serviceName)
    {
      try
      {
        using (var control = new ServiceController(serviceName))
        {
          var status = string.Empty;
          switch ((int)control.Status)
          {
            case 1:
              status = " Service is not running ";
              break;
            case 2:
              status = " Service is starting ";
              break;
            case 3:
              status = " Service is stopping ";
              break;
            case 4:
              status = " Service is running ";
              break;
            case 5:
              status = " Service is about to continue ";
              break;
            case 6:
              status = " Service is about to be suspended ";
              break;
            case 7:
              status = " Service has been suspended ";
              break;
            case 0:
              status = " Unknown state ";
              break;
          }
          return status;
        }
      }
      catch
      {
        return " Unknown state ";
      }
    }

    /// <summary>
    ///  Install services 
    /// </summary>
    /// <param name="stateSaver"></param>
    /// <param name="filepath"></param>
    public static void InstallService(IDictionary stateSaver, string filepath)
    {
      try
      {
        var myAssemblyInstaller = new AssemblyInstaller
        {
          UseNewContext = true,
          Path = filepath
        };
        myAssemblyInstaller.Install(stateSaver);
        myAssemblyInstaller.Commit(stateSaver);
        myAssemblyInstaller.Dispose();
      }
      catch (Exception ex)
      {
        throw new Exception("installServiceError/n" + ex.Message);
      }
    }

    public static bool ServiceIsExisted(string serviceName)
    {
      ServiceController[] services = ServiceController.GetServices();
      return services.Any(s => s.ServiceName == serviceName);
    }

    /// <summary>
    ///  Uninstall service 
    /// </summary>
    /// <param name="filepath"> Path and file name </param>
    public static void UnInstallService(string filepath)
    {
      try
      {
        //UnInstall Service 
        var myAssemblyInstaller = new AssemblyInstaller
        {
          UseNewContext = true,
          Path = filepath
        };
        myAssemblyInstaller.Uninstall(null);
        myAssemblyInstaller.Dispose();
      }
      catch (Exception ex)
      {
        throw new Exception("unInstallServiceError/n" + ex.Message);
      }
    }
  }
} 

Next, we encapsulate the operation method of the console. In order to realize circular monitoring, recursion is used here


using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace AutoInstallUtil
{
  class Program
  {
    static void Main(string[] args)
    {
      try
      {
        ServerAction();
      }
      catch (Exception ex)
      {
        Console.WriteLine(" An error occurred: {0}", ex.Message);
      }

      Console.ReadKey();
    }

    /// <summary>
    ///  Operation 
    /// </summary>
    private static void ServerAction()
    {
      Console.WriteLine(" Please enter: 1 Installation  2 Uninstall ");
      var condition = Console.ReadLine();
      var currentPath = Environment.CurrentDirectory;
      var currentFileNameVshost = Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName).ToLower();
      var currentFileName = currentFileNameVshost.Replace(".vshost.exe", ".exe");
      var files =
        Directory.GetFiles(currentPath)
          .Select(o => Path.GetFileName(o).ToLower())
          .ToList()
          .Where(
            o =>
              o != currentFileNameVshost
              && o != currentFileName
              && o.ToLower().EndsWith(".exe")
              && o != "installutil.exe"
              && !o.ToLower().EndsWith(".vshost.exe"))
          .ToList();
      if (files.Count == 0)
      {
        Console.WriteLine(" The executable file was not found. Please confirm that there are service programs to be installed in the current directory ");
      }
      else
      {
        Console.WriteLine(" The following executable files are found in the directory. Please select the file sequence number to install or uninstall: ");
      }
      int i = 0;
      foreach (var file in files)
      {
        Console.WriteLine(" Serial number: {0}  Filename: {1}", i, file);
        i++;
      }
      var serviceFileIndex = Console.ReadLine();
      var servicePathName = currentPath + "\\" + files[Convert.ToInt32(serviceFileIndex)];
      if (condition == "1")
      {
        SystemServices.InstallService(null, servicePathName);
      }
      else
      {
        SystemServices.UnInstallService(servicePathName);
      }
      Console.WriteLine("********** This operation is completed **********");
      ServerAction();
    }
  }
}

So far, the simple installation program is finished. In order to stand out, I chose a red tomato as an icon, which shows some

Source code and procedures: Install and uninstall Windows service


Related articles: