/// <summary> /// Allows you to change the service config /// </summary> /// <param name="serviceDefinition">Service definition instance with all paramaters</param> public void ChangeConfig(IWin32ServiceDefinition serviceDefinition) { //Change the config ChangeConfig ( serviceDefinition.DisplayName, serviceDefinition.StartType, serviceDefinition.CanInteractWithDesktop, serviceDefinition.LoadOrderGroup, serviceDefinition.ErrorControl, serviceDefinition.Credentials, serviceDefinition.DependOnService, serviceDefinition.DependOnGroup ); //Set the description ChangeDescription(serviceDefinition.Description); //Set delayed start ChangeDelayedStart(serviceDefinition.DelayedStart); //Change failure actions ChangeFailureActions(serviceDefinition.FailureActions); //Set the failure actions on non crash failures ChangeFailureActionsOnNonCrashFailures(serviceDefinition.FailureActionsOnNonCrashFailures); }
/// <summary> /// Creates a new service and return his handle /// </summary> /// <param name="serviceDefinition">The services definitions</param> /// <returns>A ServiceHandle instance</returns> public ServiceHandle CreateService(IWin32ServiceDefinition serviceDefinition) { IntPtr passwordHandle = IntPtr.Zero; if (!ValidServiceName(serviceDefinition.ServiceName)) { throw new ArgumentException("The given service name is not a valid name."); } //Create the service type var serviceType = Advapi32.ServiceType.Win32OwnProcess; //DM only supports Win32OwnProcess if (Equals(serviceDefinition.Credentials, ServiceCredentials.LocalSystem) && serviceDefinition.CanInteractWithDesktop) { serviceType |= Advapi32.ServiceType.InteractivProcess; } //The credentials can't be null if (serviceDefinition.Credentials == null) { throw new ArgumentNullException(nameof(serviceDefinition.Credentials)); } ServiceHandle serviceHandle; try { //Only call marshal if a password is set (SecureString != null), otherwise leave IntPtr.Zero if (serviceDefinition.Credentials.Password != null) { passwordHandle = Marshal.SecureStringToGlobalAllocUnicode(serviceDefinition.Credentials.Password); } serviceHandle = Advapi32.CreateService ( this, serviceDefinition.ServiceName, serviceDefinition.DisplayName, Advapi32.ServiceAccessRights.AllAccess, serviceType, serviceDefinition.StartType, serviceDefinition.ErrorControl, DmServiceExe, serviceDefinition.LoadOrderGroup, tagId: 0, //Tags are only evaluated for driver services that have SERVICE_BOOT_START or SERVICE_SYSTEM_START start types. Advapi32.ConvertDependenciesArraysToWin32String(serviceDefinition.DependOnService, serviceDefinition.DependOnGroup), serviceDefinition.Credentials.Username, passwordHandle ); if (serviceHandle.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (passwordHandle != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(passwordHandle); } } //Set the description if (!string.IsNullOrWhiteSpace(serviceDefinition.Description)) { serviceHandle.ChangeDescription(serviceDefinition.Description); } //Set delayed start if (serviceDefinition.DelayedStart) { serviceHandle.ChangeDelayedStart(serviceDefinition.DelayedStart); } //Change failure actions if (!serviceDefinition.FailureActions.Equals(Advapi32.ServiceFailureActions.Default)) { serviceHandle.ChangeFailureActions(serviceDefinition.FailureActions); } //Set the failure actions on non crash failures if (serviceDefinition.FailureActionsOnNonCrashFailures) { serviceHandle.ChangeFailureActionsOnNonCrashFailures(serviceDefinition.FailureActionsOnNonCrashFailures); } return(serviceHandle); }