public override void ApplyTemplateInfo(ActionTemplateInfo ati, BackgroundAction action) { // default implementation: do nothing ServiceDataObject sdo = GetServiceDataObjectByID(ati.ID); if (sdo == null) { Log.ErrorFormat("Unable to find object for ID {0}", ati.ID); } else { string expectedStartType = ati["StartTypeString"]; string actualStartType = sdo.StartTypeString; if (expectedStartType != actualStartType) { Log.InfoFormat("=> StartType for {0} needs to change from {1} to {2}", ati, actualStartType, expectedStartType); using (NativeSCManager scm = new NativeSCManager(MachineName)) { SC_START_TYPE startType = ServicesLocalisation.ReverseLocalizedStartType(expectedStartType); if (startType != SC_START_TYPE.SERVICE_NO_CHANGE) { sdo.ApplyStartupChanges(scm, startType); } } } else { Log.InfoFormat("=> StartType for {0} identical, no need to change", ati); } } }
public ServiceDataObject(NativeService service, ENUM_SERVICE_STATUS_PROCESS essp) : base(essp.ServiceName) { DisplayName = essp.DisplayName; CurrentState = essp.CurrentState; ControlsAccepted = essp.ControlsAccepted; Win32ExitCode = essp.Win32ExitCode.ToString(); ServiceSpecificExitCode = essp.ServiceSpecificExitCode.ToString(); CheckPoint = essp.CheckPoint.ToString(); WaitHint = essp.WaitHint.ToString(); ServiceFlags = essp.ServiceFlags.ToString(); ServiceType = essp.ServiceType; if (essp.ProcessID != 0) { PID = essp.ProcessID.ToString(); } else { PID = ""; } QUERY_SERVICE_CONFIG config = service.ServiceConfig; if (essp.CurrentState == SC_RUNTIME_STATUS.SERVICE_RUNNING) { IsRunning = true; } if (config != null) { if (config.StartType == SC_START_TYPE.SERVICE_DISABLED) { IsDisabled = true; } StartType = config.StartType; BinaryPathName = config.BinaryPathName; LoadOrderGroup = config.LoadOrderGroup; ErrorControl = ServicesLocalisation.Localized(config.ErrorControl); TagId = config.TagId.ToString(); User = config.ServiceStartName; } ToolTip = Description = service.Description; ToolTipCaption = DisplayName; ConstructionIsFinished = true; }
public override void DoWork() { ACCESS_MASK ServiceAccessMask = SSR.GetServiceAccessMask() | ACCESS_MASK.STANDARD_RIGHTS_READ | ACCESS_MASK.SERVICE_QUERY_STATUS; ServicesDataController sdc = MainWindow.CurrentController as ServicesDataController; using (NativeSCManager scm = new NativeSCManager(sdc.MachineName)) { int serviceIndex = 0; foreach (ServiceDataObject so in Services) { ++serviceIndex; try { SetOutputText(string.Format("Service {0}/{1}: {2} is initially in state {3}", serviceIndex, Services.Count, so.DisplayName, ServicesLocalisation.Localized(so.CurrentState))); if (so.CurrentState == SC_RUNTIME_STATUS.SERVICE_STOPPED) { ServiceAccessMask &= ~(ACCESS_MASK.SERVICE_STOP); } using (NativeService ns = new NativeService(scm, so.InternalID, ServiceAccessMask)) { bool requestedStatusChange = false; Log.InfoFormat("BEGIN backgroundWorker1_Process for {0}", ns.Description); using (ServiceStatus ss = new ServiceStatus(ns)) { for (int i = 0; i < 100; ++i) { if (Worker.CancellationPending) { break; } if (!ss.Refresh()) { break; } SetOutputText(string.Format("Service {0}/{1}: {2} is now in state {3}", serviceIndex, Services.Count, so.DisplayName, ServicesLocalisation.Localized(ss.Status.CurrentState))); if (SSR.HasSuccess(ss.Status.CurrentState)) { Log.Info("Reached target status, done..."); break; // TODO: reached 100% of this service' status reqs. } // if we haven't asked the service to change its status yet, do so now. if (!requestedStatusChange) { requestedStatusChange = true; Log.InfoFormat("Ask {0} to issue its status request on {1}", SSR, ss); if (!SSR.Request(ss)) { break; } } else if (SSR.HasFailed(ss.Status.CurrentState)) { Log.Error("ERROR, target state is one of the failed ones :("); break; } Thread.Sleep(500); } so.UpdateFrom(ss.Status); Log.Info("END backgroundWorker1_Process"); } } } catch (Exception ex) { Log.Error("Exception caught in PerformServiceStateRequest", ex); } if (Worker.CancellationPending) { break; } } } }