/// <summary> /// Create a new service. /// </summary> /// <param name="name">The name of the service.</param> /// <param name="display_name">The display name for the service.</param> /// <param name="service_type">The service type.</param> /// <param name="start_type">The service start type.</param> /// <param name="error_control">Error control.</param> /// <param name="binary_path_name">Path to the service executable.</param> /// <param name="load_order_group">Load group order.</param> /// <param name="dependencies">List of service dependencies.</param> /// <param name="service_start_name">The username for the service.</param> /// <param name="password">Password for the username if needed.</param> /// <param name="throw_on_error">True to throw on error.</param> /// <returns>The registered service information.</returns> public static NtResult <RunningService> CreateService( string name, string display_name, ServiceType service_type, ServiceStartType start_type, ServiceErrorControl error_control, string binary_path_name, string load_order_group, IEnumerable <string> dependencies, string service_start_name, SecureString password, bool throw_on_error) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException($"'{nameof(name)}' cannot be null or empty", nameof(name)); } if (string.IsNullOrEmpty(binary_path_name)) { throw new ArgumentException($"'{nameof(binary_path_name)}' cannot be null or empty", nameof(binary_path_name)); } using (var scm = Win32NativeMethods.OpenSCManager(null, null, ServiceControlManagerAccessRights.Connect | ServiceControlManagerAccessRights.CreateService)) { if (scm.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <RunningService>(throw_on_error)); } IntPtr pwd = password != null?Marshal.SecureStringToBSTR(password) : IntPtr.Zero; try { using (var service = Win32NativeMethods.CreateService(scm, name, display_name, ServiceAccessRights.MaximumAllowed, service_type, start_type, error_control, binary_path_name, load_order_group, null, dependencies.ToMultiString(), string.IsNullOrEmpty(service_start_name) ? null : service_start_name, pwd)) { if (service.IsInvalid) { return(Win32Utils.GetLastWin32Error().CreateResultFromDosError <RunningService>(throw_on_error)); } return(new RunningService(name, display_name ?? string.Empty, QueryStatus(service)).CreateResult()); } } finally { if (pwd != IntPtr.Zero) { Marshal.FreeBSTR(pwd); } } } }