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 services
- public 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));
- }
- }
- }
|