public override void Restart(uint restartFlags = 0) { base.Restart(restartFlags); Logger.Trace(string.Format("Restarting RMSession {0} with {1} manual processes found to restart", SessionKey, ProcessesToManuallyRestart.Count)); foreach (Tuple <IntPtr, string> processInfo in ProcessesToManuallyRestart) { try { if (!WindowsAccountServices.StartProcessFromUserToken(processInfo.Item1, processInfo.Item2)) { throw new InvalidOperationException("Could not restart process " + processInfo.Item2 + " using previously defined user token!"); } } finally { WindowsAccountServices.CloseHandle(processInfo.Item1); } } ProcessesToManuallyRestart.Clear(); }
/// <summary> /// Shutdown all registered processes, including processes marked for manual shutdown (if necessary). /// <remarks>To ensure process restart success, the system MUST be able to query the user token from the process (you must be Administrator/LocalSystem). /// Otherwise, processes could restart as the wrong user, breaking the functionality of the process.</remarks> /// </summary> /// <param name="actionFlags"></param> public override void Shutdown(uint actionFlags = 0) { Logger.Trace(string.Format("Shutting down RMSession {0} with {1} manual processes found to shutdown", SessionKey, ProcessesToManuallyShutdown.Count)); if (ProcessesToManuallyRestart.Count > 0) { Logger.Warn("There are pending processes in the manual restart queue! Are you shutting down again?"); } foreach (Process manualShutdownProcess in ProcessesToManuallyShutdown) { IntPtr userToken = IntPtr.Zero; if (!WindowsAccountServices.GetUserTokenFromProcess(manualShutdownProcess.Id, ref userToken)) { throw new InvalidOperationException("Could not retrieve the user token for manual shutdown process " + manualShutdownProcess.ProcessName); } ProcessesToManuallyRestart.Add(Tuple.Create(userToken, manualShutdownProcess.MainModule.FileName)); } ProcessesToManuallyShutdown.ForEach(x => x.Kill()); ProcessesToManuallyShutdown.Clear(); base.Shutdown(actionFlags); }