private static void InstallService(string ServiceName, string DisplayName, string Description, ServiceStartType StartType, bool Immediate, ServiceFailureActions FailureActions, Win32ServiceCredentials Credentials) { ServiceInstaller host = new ServiceInstaller(ServiceName); int i; switch (i = host.Install(DisplayName, Description, StartType, Immediate, FailureActions, Credentials)) { case 0: Console.Out.WriteLine("Service successfully installed. Service start is pending."); break; case 1: Console.Out.WriteLine("Service successfully installed and started."); break; case 2: Console.Out.WriteLine("Service registration successfully updated. Service start is pending."); break; case 3: Console.Out.WriteLine("Service registration successfully updated. Service started."); break; default: throw new Exception("Unexpected installation result: " + i.ToString()); } }
private static void Install(Settings Set) { Win32ServiceCredentials cred = Win32ServiceCredentials.NetworkService; switch (Set.Account) { case AccountType.LocalService: cred = Win32ServiceCredentials.LocalService; break; case AccountType.LocalSystem: cred = Win32ServiceCredentials.LocalSystem; break; } var binaryPath = Process.GetCurrentProcess().MainModule.FileName; binaryPath = binaryPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase) ? $"{binaryPath} \"{Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, PlatformServices.Default.Application.ApplicationName + ".dll")}\" srun" : $"{binaryPath} srun"; new Win32ServiceManager().CreateService( Set.ServiceName, Set.DisplayName, Set.Description, binaryPath, cred, autoStart: Set.StartType == StartType.Auto, startImmediately: Set.StartType == StartType.Auto, errorSeverity: ErrorSeverity.Normal); Console.WriteLine($@"Successfully registered and started service ""{Set.ServiceName}"" (""{Set.DisplayName}"")"); }
private void InstallInternal( ServiceController serviceController, string ravenServerDir, List <string> serviceArgs, int counter = 0) { var serviceName = _serviceName; var serviceCommand = GetServiceCommand(ravenServerDir, serviceArgs); var serviceDesc = WindowServiceDescription; try { var credentials = Win32ServiceCredentials.LocalService; if (string.IsNullOrWhiteSpace(_username) == false) { credentials = new Win32ServiceCredentials(_username, _password); } new Win32ServiceManager().CreateService(new ServiceDefinition(NormalizeServiceName(serviceName), serviceCommand) { DisplayName = serviceName, Description = serviceDesc, Credentials = credentials, AutoStart = true, DelayedAutoStart = false, ErrorSeverity = ErrorSeverity.Normal }); Console.WriteLine($"Service {ServiceFullName} has been registered."); } catch (Win32Exception e) when(e.NativeErrorCode == ErrorServiceExists) { Console.WriteLine($"Service {ServiceFullName} already exists. Reinstalling..."); Reinstall(serviceController, ravenServerDir, serviceArgs); } catch (Win32Exception e) when(e.NativeErrorCode == ErrorServiceMarkedForDeletion) { if (counter < 10) { Console.WriteLine($"Service {ServiceFullName} has been marked for deletion. Performing {counter + 1} installation attempt."); Thread.Sleep(1000); counter++; InstallInternal(serviceController, ravenServerDir, serviceArgs, counter); } } catch (Win32Exception e) when(e.NativeErrorCode == ErrorAccessIsDenied) { Console.WriteLine($"Cannot register service {ServiceFullName} due to insufficient privileges. Please use Administrator account to install the service."); } catch (Win32Exception e) { Console.WriteLine($"Cannot register service {ServiceFullName}: { FormatWin32ErrorMessage(e) }"); } }
/// <summary> /// Installs the service. /// </summary> /// <param name="DisplayName">Service display name.</param> /// <param name="Description">Service description.</param> /// <param name="StartType">How the service should be started.</param> /// <param name="StartImmediately">If the service should be started immediately.</param> /// <param name="FailureActions">Service failure actions.</param> /// <param name="Credentials">Credentials to use when running service.</param> /// <returns> /// Return code: /// /// 0: Installed, not started. /// 1: Installed, started. /// 2: Updated, not started. /// 3: Updated, started. /// </returns> /// <exception cref="Exception">If service could not be installed.</exception> public int Install(string DisplayName, string Description, ServiceStartType StartType, bool StartImmediately, ServiceFailureActions FailureActions, Win32ServiceCredentials Credentials) { string Path = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe"); try { using (ServiceControlManager mgr = ServiceControlManager.Connect(null, null, ServiceControlManagerAccessRights.All)) { if (mgr.TryOpenService(this.serviceName, ServiceControlAccessRights.All, out ServiceHandle existingService, out Win32Exception errorException)) { using (existingService) { existingService.ChangeConfig(DisplayName, Path, ServiceType.Win32OwnProcess, StartType, ErrorSeverity.Normal, Credentials); if (!string.IsNullOrEmpty(Description)) { existingService.SetDescription(Description); } if (!(FailureActions is null)) { existingService.SetFailureActions(FailureActions); existingService.SetFailureActionFlag(true); } else { existingService.SetFailureActionFlag(false); } if (StartImmediately) { existingService.Start(throwIfAlreadyRunning: false); return(3); } else { return(2); } }
private static void Install(HostConfiguration <SERVICE> config, ServiceController sc, int counter = 0) { Win32ServiceCredentials cred = Win32ServiceCredentials.LocalSystem; if (!string.IsNullOrEmpty(config.Username)) { cred = new Win32ServiceCredentials(config.Username, config.Password); } try { new Win32ServiceManager().CreateService( config.Name, config.DisplayName, config.Description, GetServiceCommand(config.ExtraArguments), cred, autoStart: true, startImmediately: true, errorSeverity: ErrorSeverity.Normal); Console.WriteLine($@"Successfully registered and started service ""{config.Name}"" (""{config.Description}"")"); } catch (Exception e) { if (e.Message.Contains("already exists")) { Console.WriteLine($@"Service ""{config.Name}"" (""{config.Description}"") was already installed. Reinstalling..."); Reinstall(config, sc); } else if (e.Message.Contains("The specified service has been marked for deletion")) { if (counter < 10) { System.Threading.Thread.Sleep(500); counter++; string suffix = "th"; if (counter == 1) { suffix = "st"; } else if (counter == 2) { suffix = "nd"; } else if (counter == 3) { suffix = "rd"; } Console.WriteLine("The specified service has been marked for deletion. Retrying {0}{1} time", counter, suffix); Install(config, sc, counter); } else { throw; } } else { throw; } } }
public static int Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (sender, e) => { if (e.IsTerminating) { string FileName = Path.Combine(Gateway.AppDataFolder, "UnhandledException.txt"); Networking.Sniffers.XmlFileSniffer.MakeUnique(ref FileName); using (StreamWriter w = File.CreateText(FileName)) { w.Write("Type: "); if (e.ExceptionObject != null) { w.WriteLine(e.ExceptionObject.GetType().FullName); } else { w.WriteLine("null"); } w.Write("Time: "); w.WriteLine(DateTime.Now.ToString()); w.WriteLine(); if (e.ExceptionObject is Exception ex) { while (ex != null) { w.WriteLine(ex.Message); w.WriteLine(); w.WriteLine(ex.StackTrace); w.WriteLine(); ex = ex.InnerException; } } else { if (e.ExceptionObject != null) { w.WriteLine(e.ExceptionObject.ToString()); } w.WriteLine(); w.WriteLine(Environment.StackTrace); } w.Flush(); } } if (e.ExceptionObject is Exception ex2) { Log.Critical(ex2); } else if (e.ExceptionObject != null) { Log.Critical(e.ExceptionObject.ToString()); } else { Log.Critical("Unexpected null exception thrown."); } }; AppDomain.CurrentDomain.DomainUnload += (sender, e) => { Log.Informational("Unloading domain."); }; AppDomain.CurrentDomain.ProcessExit += (sender, e) => { Log.Informational("Exiting process."); Log.Terminate(); }; try { string ServiceName = "IoT Gateway Service"; string DisplayName = ServiceName; string Description = "Windows Service hosting the Waher IoT Gateway."; string Arg; ServiceStartType StartType = ServiceStartType.Disabled; Win32ServiceCredentials Credentials = Win32ServiceCredentials.LocalService; bool Install = false; bool Uninstall = false; bool Immediate = false; bool AsConsole = false; bool Error = false; bool Help = false; int i, c = args.Length; Log.RegisterExceptionToUnnest(typeof(System.Runtime.InteropServices.ExternalException)); Log.RegisterExceptionToUnnest(typeof(System.Security.Authentication.AuthenticationException)); Log.Register(new Waher.Events.WindowsEventLog.WindowsEventLog("IoTGateway")); Log.Informational("Program started."); for (i = 0; i < c; i++) { Arg = args[i]; switch (Arg.ToLower()) { case "-?": Help = true; break; case "-install": Install = true; break; case "-uninstall": Uninstall = true; break; case "-immediate": Immediate = true; break; case "-console": AsConsole = true; break; case "-displayname": i++; if (i >= c) { Error = true; break; } DisplayName = args[i]; break; case "-description": i++; if (i >= c) { Error = true; break; } Description = args[i]; break; case "-start": i++; if (i >= c) { Error = true; break; } if (!Enum.TryParse <ServiceStartType>(args[i], out StartType)) { Error = true; break; } break; case "-localsystem": Credentials = Win32ServiceCredentials.LocalSystem; break; case "-localservice": Credentials = Win32ServiceCredentials.LocalService; break; case "-networkservice": Credentials = Win32ServiceCredentials.NetworkService; break; case "-instance": i++; if (i >= c) { Error = true; break; } instanceName = args[i]; break; default: Error = true; break; } } if (Error || Help) { Log.Informational("Displaying help."); Console.Out.WriteLine("IoT Gateway Windows Service Application."); Console.Out.WriteLine(); Console.Out.WriteLine("Command line switches:"); Console.Out.WriteLine(); Console.Out.WriteLine("-? Brings this help."); Console.Out.WriteLine("-install Installs service in operating system"); Console.Out.WriteLine("-uninstall Uninstalls service from operating system."); Console.Out.WriteLine("-displayname Name Sets the display name of the service. Default is \"IoT "); Console.Out.WriteLine(" Gateway Service\"."); Console.Out.WriteLine("-description Desc Sets the textual description of the service. Default is "); Console.Out.WriteLine(" \"Windows Service hosting the Waher IoT Gateway.\"."); Console.Out.WriteLine("-start Mode Sets the default starting mode of the service. Default is "); Console.Out.WriteLine(" Disabled. Available options are StartOnBoot, "); Console.Out.WriteLine(" StartOnSystemStart, AutoStart, StartOnDemand and Disabled."); Console.Out.WriteLine("-immediate If the service should be started immediately."); Console.Out.WriteLine("-console Run the service as a console application."); Console.Out.WriteLine("-localsystem Installed service will run using the Local System account."); Console.Out.WriteLine("-localservice Installed service will run using the Local Service account"); Console.Out.WriteLine(" (default)."); Console.Out.WriteLine("-networkservice Installed service will run using the Network Service"); Console.Out.WriteLine(" account."); Console.Out.WriteLine("-instance INSTANCE Name of instance. Default is the empty string. Parallel"); Console.Out.WriteLine(" instances of the IoT Gateway can execute, provided they"); Console.Out.WriteLine(" are given separate instance names."); return(-1); } if (Install && Uninstall) { Log.Error("Conflicting arguments."); Console.Out.Write("Conflicting arguments."); return(-1); } if (Install) { Log.Informational("Installing service."); InstallService(ServiceName, DisplayName, Description, StartType, Immediate, new ServiceFailureActions(TimeSpan.FromDays(1), null, null, new ScAction[] { new ScAction() { Type = ScActionType.ScActionRestart, Delay = TimeSpan.FromMinutes(1) }, new ScAction() { Type = ScActionType.ScActionRestart, Delay = TimeSpan.FromMinutes(1) }, new ScAction() { Type = ScActionType.ScActionRestart, Delay = TimeSpan.FromMinutes(1) } }), Credentials); return(0); } else if (Uninstall) { Log.Informational("Uninstalling service."); UninstallService(ServiceName); return(0); } else { if (AsConsole) { Log.Informational("Running as console application."); RunAsConsole(); } else { Log.Informational("Running as service application."); RunAsService(ServiceName); } return(1); // Allows the service to be restarted. } } catch (Exception ex) { Log.Critical(ex); Console.Out.WriteLine(ex.Message); return(1); } }
public virtual void ChangeConfig(string displayName, string binaryPath, ServiceType serviceType, ServiceStartType startupType, ErrorSeverity errorSeverity, Win32ServiceCredentials credentials) { bool success = Win32.ChangeServiceConfigW(this, serviceType, startupType, errorSeverity, binaryPath, null, IntPtr.Zero, null, credentials.UserName, credentials.Password, displayName); if (!success) { throw new Win32Exception(Marshal.GetLastWin32Error()); } }
private void InstallService(ParameterHandlerInfo parameterHandlerInfo) { try { // Environment.GetCommandLineArgs() includes the current DLL from a "dotnet my.dll --register-service" call, which is not passed to Main() var remainingArgs = Environment.GetCommandLineArgs() .Where(arg => arg != "/service-install") .Select(EscapeCommandLineArgument) .Append("/service-run"); var host = Process.GetCurrentProcess().MainModule.FileName; if (!host.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase)) { // For self-contained apps, skip the dll path remainingArgs = remainingArgs.Skip(1); } var fullServiceCommand = host + " " + string.Join(" ", remainingArgs); _settings.DisplayName = _settings.DisplayName ?? Core.ApplicationDisplayName; _settings.Description = _settings.Description ?? Core.ApplicationDisplayName; Win32ServiceCredentials credentials; switch (_settings.Credentials) { case ServiceCredentials.LocalSystem: credentials = Win32ServiceCredentials.LocalSystem; break; case ServiceCredentials.LocalService: credentials = Win32ServiceCredentials.LocalService; break; case ServiceCredentials.NetworkService: credentials = Win32ServiceCredentials.NetworkService; break; case ServiceCredentials.Custom: credentials = new Win32ServiceCredentials(_settings.Username, _settings.Password); break; default: throw new ArgumentException("The Credentials enum has a wrong value."); } var serviceManager = new Win32ServiceManager(); serviceManager.CreateOrUpdateService( ServiceName, _settings.DisplayName, _settings.Description, fullServiceCommand, credentials, _settings.AutoStart ); Core.Log.Warning($"The Service \"{ServiceName}\" was installed successfully."); } catch (Exception ex) { Core.Log.Error(ex.Message); } }
public ServiceHandle CreateService(string serviceName, string displayName, string binaryPath, ServiceType serviceType, ServiceStartType startupType, ErrorSeverity errorSeverity, Win32ServiceCredentials credentials) { ServiceHandle service = Win32.CreateServiceW(this, serviceName, displayName, ServiceControlAccessRights.All, serviceType, startupType, errorSeverity, binaryPath, null, IntPtr.Zero, null, credentials.UserName, credentials.Password); if (service.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return(service); }
/// <summary> /// Installs the service. /// </summary> /// <param name="DisplayName">Service display name.</param> /// <param name="Description">Service description.</param> /// <param name="StartType">How the service should be started.</param> /// <param name="StartImmediately">If the service should be started immediately.</param> /// <param name="Credentials">Credentials to use when running service.</param> /// <returns> /// Return code: /// /// 0: Installed, not started. /// 1: Installed, started. /// 2: Updated, not started. /// 3: Updated, started. /// </returns> /// <exception cref="Exception">If service could not be installed.</exception> public int Install(string DisplayName, string Description, ServiceStartType StartType, bool StartImmediately, Win32ServiceCredentials Credentials) { string Path = Assembly.GetExecutingAssembly().Location.Replace(".dll", ".exe"); try { using (ServiceControlManager mgr = ServiceControlManager.Connect(null, null, ServiceControlManagerAccessRights.All)) { if (mgr.TryOpenService(this.serviceName, ServiceControlAccessRights.All, out ServiceHandle existingService, out Win32Exception errorException)) { using (existingService) { existingService.ChangeConfig(DisplayName, Path, ServiceType.Win32OwnProcess, StartType, ErrorSeverity.Normal, Credentials); if (!string.IsNullOrEmpty(Description)) { existingService.SetDescription(Description); } /*if (serviceFailureActions != null) * { * existingService.SetFailureActions(serviceFailureActions); * existingService.SetFailureActionFlag(failureActionsOnNonCrashFailures); * }*/ if (StartImmediately) { existingService.Start(throwIfAlreadyRunning: false); return(3); } else { return(2); } } } else { if (errorException.NativeErrorCode == Win32.ERROR_SERVICE_DOES_NOT_EXIST) { using (ServiceHandle svc = mgr.CreateService(this.serviceName, DisplayName, Path, ServiceType.Win32OwnProcess, StartType, ErrorSeverity.Normal, Credentials)) { if (!string.IsNullOrEmpty(Description)) { svc.SetDescription(Description); } /*if (serviceFailureActions != null) * { * svc.SetFailureActions(serviceFailureActions); * svc.SetFailureActionFlag(failureActionsOnNonCrashFailures); * }*/ if (StartImmediately) { svc.Start(); return(1); } else { return(0); } } } else { throw errorException; } } }
public static int Main(string[] args) { AppDomain.CurrentDomain.UnhandledException += (sender, e) => { Log.Error("Unhandled exception caught.", new KeyValuePair <string, object>("IsTerminating", e.IsTerminating)); if (e.ExceptionObject is Exception ex) { Log.Critical(ex); } else if (e.ExceptionObject != null) { Log.Critical(e.ExceptionObject.ToString()); } else { Log.Critical("Unexpected null exception thrown."); } }; AppDomain.CurrentDomain.DomainUnload += (sender, e) => { Log.Informational("Unloading domain."); }; AppDomain.CurrentDomain.ProcessExit += (sender, e) => { Log.Informational("Exiting process."); Log.Terminate(); }; try { string ServiceName = "IoT Gateway Service"; string DisplayName = ServiceName; string Description = "Windows Service hosting the Waher IoT Gateway."; string Arg; ServiceStartType StartType = ServiceStartType.Disabled; Win32ServiceCredentials Credentials = Win32ServiceCredentials.LocalService; bool Install = false; bool Uninstall = false; bool Immediate = false; bool AsConsole = false; bool Error = false; bool Help = false; int i, c = args.Length; Log.RegisterExceptionToUnnest(typeof(System.Runtime.InteropServices.ExternalException)); Log.RegisterExceptionToUnnest(typeof(System.Security.Authentication.AuthenticationException)); Log.Register(new Waher.Events.WindowsEventLog.WindowsEventLog("IoTGateway")); Log.Informational("Program started."); for (i = 0; i < c; i++) { Arg = args[i]; switch (Arg.ToLower()) { case "-?": Help = true; break; case "-install": Install = true; break; case "-uninstall": Uninstall = true; break; case "-immediate": Immediate = true; break; case "-console": AsConsole = true; break; case "-displayname": i++; if (i >= c) { Error = true; break; } DisplayName = args[i]; break; case "-description": i++; if (i >= c) { Error = true; break; } Description = args[i]; break; case "-start": i++; if (i >= c) { Error = true; break; } if (!Enum.TryParse <ServiceStartType>(args[i], out StartType)) { Error = true; break; } break; case "-localsystem": Credentials = Win32ServiceCredentials.LocalSystem; break; case "-localservice": Credentials = Win32ServiceCredentials.LocalService; break; case "-networkservice": Credentials = Win32ServiceCredentials.NetworkService; break; default: Error = true; break; } } if (Error || Help) { Log.Informational("Displaying help."); Console.Out.WriteLine("IoT Gateway Windows Service Application."); Console.Out.WriteLine(); Console.Out.WriteLine("Command line switches:"); Console.Out.WriteLine(); Console.Out.WriteLine("-? Brings this help."); Console.Out.WriteLine("-install Installs service in operating system"); Console.Out.WriteLine("-uninstall Uninstalls service from operating system."); Console.Out.WriteLine("-displayname Name Sets the display name of the service. Default is \"IoT "); Console.Out.WriteLine(" Gateway Service\"."); Console.Out.WriteLine("-description Desc Sets the textual description of the service. Default is "); Console.Out.WriteLine(" \"Windows Service hosting the Waher IoT Gateway.\"."); Console.Out.WriteLine("-start Mode Sets the default starting mode of the service. Default is "); Console.Out.WriteLine(" Disabled. Available options are StartOnBoot, "); Console.Out.WriteLine(" StartOnSystemStart, AutoStart, StartOnDemand and Disabled."); Console.Out.WriteLine("-immediate If the service should be started immediately."); Console.Out.WriteLine("-console Run the service as a console application."); Console.Out.WriteLine("-localsystem Installed service will run using the Local System account."); Console.Out.WriteLine("-localservice Installed service will run using the Local Service account"); Console.Out.WriteLine(" (default)."); Console.Out.WriteLine("-networkservice Installed service will run using the Network Service"); Console.Out.WriteLine(" account."); return(-1); } if (Install && Uninstall) { Log.Error("Conflicting arguments."); Console.Out.Write("Conflicting arguments."); return(-1); } if (Install) { Log.Informational("Installing service."); InstallService(ServiceName, DisplayName, Description, StartType, Immediate, Credentials); } else if (Uninstall) { Log.Informational("Uninstalling service."); UninstallService(ServiceName); } else if (AsConsole) { Log.Informational("Running as console application."); RunAsConsole(); } else { Log.Informational("Running as service application."); RunAsService(ServiceName); } return(0); } catch (Exception ex) { Log.Critical(ex); Console.Out.WriteLine(ex.Message); return(-1); } }
public void CreateService(string serviceName, string displayName, string description, string binaryPath, Win32ServiceCredentials credentials, bool autoStart = false, bool startImmediately = false, ErrorSeverity errorSeverity = ErrorSeverity.Normal) { CreateService( new ServiceDefinitionBuilder(serviceName) .WithDisplayName(displayName) .WithDescription(description) .WithBinaryPath(binaryPath) .WithCredentials(credentials) .WithAutoStart(autoStart) .WithErrorSeverity(errorSeverity) .Build(), startImmediately ); }