private bool CheckStarcounterApps(RecoveryConfigItem rc) { var apps = rc.ScAppNames; if (apps != null && apps.Count > 0) { var appNames = string.Join(", ", apps); var db = rc.ScDatabase ?? "default"; var scFileName = "staradmin.exe"; PrintDebug($"Checking starcounter apps: {appNames}, db: {db}"); System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo(); startInfo.FileName = string.IsNullOrEmpty(rc.StarcounterBinDirectory) ? scFileName : Path.Combine(rc.StarcounterBinDirectory, scFileName); startInfo.Arguments = $"--database={db} list app"; startInfo.UseShellExecute = false; startInfo.RedirectStandardOutput = true; startInfo.CreateNoWindow = true; process.StartInfo = startInfo; process.Start(); string stdOutput = process.StandardOutput.ReadToEnd(); bool allAppsAreRunning = apps.All(appName => stdOutput.Contains($"{appName} (in {db})")); return(allAppsAreRunning); } PrintDebug($"Skipped starcounter apps, not defined"); return(true); }
private bool DoCheck(RecoveryConfigItem rc, out string failed) { // It's faster to get by name on each foreach (string procName in rc.Processes) { var procs = Process.GetProcessesByName(procName); var found = procs.Length > 0; if (!found) { if (m_log.Level == ServiceLogLevel.Trace) { #if DBG_LOG m_log.Write(ServiceLogLevel.Trace, $"Failed to find '{procName}'{Environment.NewLine}{GetRunning()}"); #else m_log.Write(ServiceLogLevel.Trace, $"Failed to find '{procName}'"); #endif } failed = procName; return(false); } else if (m_log.Level == ServiceLogLevel.Trace) { var procInfo = string.Join(Environment.NewLine, procs.Select(p => $"[{p.ProcessName}] {p.Id}")); m_log.Write(ServiceLogLevel.Trace, $"Found '{procName}' Processes:{Environment.NewLine}{procInfo}"); } } failed = null; return(CheckStarcounterApps(rc)); }
private bool Check(RecoveryConfigItem rc) { string procName; if (!DoCheck(rc, out procName)) { LogCheckFailed(procName); return(false); } return(true); }
/// <summary> /// /// </summary> /// <param name="rc"></param> /// <param name="retryTimespan">Retry to find the process for this interval</param> /// <returns></returns> private bool Check(RecoveryConfigItem rc, TimeSpan retryTimespan) { var watch = Stopwatch.StartNew(); string failed; do { if (DoCheck(rc, out failed)) { PrintDebug($"Find took {watch.Elapsed.TotalMilliseconds}ms"); return(true); } Thread.Sleep(1); } while (watch.Elapsed < retryTimespan); return(false); }
private TimeSpan Recover(RecoveryConfigItem rc) { ApplicationLoader.PROCESS_INFORMATION procInfo; var timeout = m_config.RecoveryExecutionTimeout; if (rc.OverrideRecoveryExecutionTimeout != 0) { timeout = rc.OverrideRecoveryExecutionTimeout; } var recoverTime = TimeSpan.FromMilliseconds((int)timeout); var watch = Stopwatch.StartNew(); // This is the way to go if running as a service. But when debugging we don't have this privelege. Just spawn a new process if (m_user.IsServiceAccount || m_user.IsSystemAccount) { ApplicationLoader.StartProcessAndBypassUAC(rc.RecoveryBatch, m_config.NoConsoleForRecoveryScript, timeout, PrintDebug, out procInfo); } else { ApplicationInlineLoader.Start(GetFile(rc.RecoveryBatch), m_config.NoConsoleForRecoveryScript, timeout, PrintDebug); } // Return the amount of time left to wait for recovery execution return(recoverTime - watch.Elapsed); }