| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 | using System.Collections;using System.Collections.Generic;using System.Configuration.Install;using System.Reflection;using System.ServiceProcess;namespace PRSServices;// Class to manage the installation of servicespublic class PRSServiceInstaller{    public static Assembly Assembly { get; set; }    public static bool IsInstalled(string serviceName)    {        return ServiceController.GetServices().Any(s => s.ServiceName == serviceName);    }    public static bool IsRunning(string serviceName)    {        using (var controller =               new ServiceController(serviceName))        {            if (!IsInstalled(serviceName)) return false;            return controller.Status == ServiceControllerStatus.Running;        }    }    private static AssemblyInstaller GetInstaller(string serviceName, string description, string displayName, string? username, string? password)    {        // The arguments passed here are received by PRSInstaller, which it uses to set service metadata.        // /name=servicename is *REQUIRED* because otherwise Windows can't find the service in the executable.        var installProperties = new List<string>        {            "/name=" + serviceName,            "/description=" + description,            "/displayName=" + displayName        };        if(!string.IsNullOrWhiteSpace(username))        {            installProperties.Add("/username=" + username);            installProperties.Add("/password=" + (password ?? ""));        }        var installer = new AssemblyInstaller(Assembly, installProperties.ToArray());        installer.UseNewContext = true;        return installer;    }    private static AssemblyInstaller GetUninstaller(string serviceName)    {        // The argument passed here is received by PRSInstaller. /name=serviceName is used to find the serviceName        // in the PRSServer.exe, which can then execute the uninstaller.        var installer = new AssemblyInstaller(Assembly, new[] { "/name=" + serviceName });        installer.UseNewContext = true;        return installer;    }    public static void InstallService(string serviceName, string description, string displayName, string? username, string? password)    {        if (IsInstalled(serviceName)) return;        using var installer = GetInstaller(serviceName, description, displayName, username, password);        IDictionary state = new Hashtable();        try        {            installer.Install(state);            installer.Commit(state);        }        catch        {            try            {                //installer.Rollback(state);            }            catch            {            }            throw;        }    }    public static void UninstallService(string serviceName)    {        if (!IsInstalled(serviceName)) return;        using var installer = GetUninstaller(serviceName);        IDictionary state = new Hashtable();        installer.Uninstall(state);    }    public static void ChangeService(string serviceName, string description, string displayName, string? username, string? password)    {        if (IsInstalled(serviceName)) UninstallService(serviceName);        InstallService(serviceName, description, displayName, username, password);        /*        // Delegate the configuration of the service to sc.exe, and execute.        // I haven't found a way to do it without using sc.exe. (Unless we decided to change the registry, which is surely a bad idea.)        // Convert quotes and backslashes to escaped quotes and backslashes        var newServiceName = serviceName.Replace("\"", "\\\"").Replace("\\", "\\\\");        var newDisplayName = displayName.Replace("\"", "\\\"").Replace("\\", "\\\\");        var newDescription = description.Replace("\"", "\\\"").Replace("\\", "\\\\");        RunCommand("sc.exe", "description \"" + newServiceName + "\" \"" + newDescription + "\"");        RunCommand("sc.exe", "config \"" + newServiceName + "\" displayname=\"" + newDisplayName + "\"");        */    }    public static void StartService(string serviceName)    {        if (!IsInstalled(serviceName)) return;        using var controller =               new ServiceController(serviceName);        if (controller.Status != ServiceControllerStatus.Running)        {            controller.Start();            controller.WaitForStatus(ServiceControllerStatus.Running,                TimeSpan.FromSeconds(10));        }    }    public static void StopService(string serviceName)    {        if (!IsInstalled(serviceName)) return;        using var controller =               new ServiceController(serviceName);        if (controller.Status != ServiceControllerStatus.Stopped)        {            controller.Stop();            controller.WaitForStatus(ServiceControllerStatus.Stopped,                TimeSpan.FromSeconds(10));        }    }}
 |