public override object Suspend(SuspendInformation toSuspend) { // Check whether the necessary data to know which file was open is passed. if (toSuspend.CommandLine == null) { return(null); } // TODO: Should we distribute taskkill to ensure it being there? ProcessHelper.SetUp(@"C:\Windows\System32\taskkill.exe", "/pid " + toSuspend.Process.Id, "", true).Run(); // Extract file name from commandLine which is in format: "... path/to/notepad.exe" C:\Path\To\File\Without Quotes\text file.txt Match split = Regex.Match(toSuspend.CommandLine, "\"(.*)\" (.*)"); return(split.Groups[2].Value); }
public override object Suspend(SuspendInformation toSuspend) { var cabinetWindows = new ShellWindows() .Cast <InternetExplorer>() // TODO: Is there a safer way to guarantee that it is actually the explorer we expect it to be? // For some reason, the process CAN be both "Explorer", and "explorer". .Where(e => Path.GetFileNameWithoutExtension(e.FullName).IfNotNull(p => p.ToLower()) == "explorer") .ToList(); var suspendedExplorerWindows = new List <ExplorerLocation>(); foreach (Window window in toSuspend.Windows) { // Check whether the window is an explorer cabinet window. (file browser) InternetExplorer cabinetWindow = cabinetWindows.FirstOrDefault(e => { try { return(window.Handle.Equals(new IntPtr(e.HWND))); } catch (COMException) { // This exception is thrown when accessing 'HWND' for some windows. // TODO: Why is this the case, and do we ever need to handle those windows? return(false); } }); if (cabinetWindow != null) { var persistedData = new ExplorerLocation { LocationName = cabinetWindow.LocationName, LocationUrl = cabinetWindow.LocationURL, Pidl = cabinetWindow.GetPidl() }; cabinetWindow.Quit(); suspendedExplorerWindows.Add(persistedData); } // TODO: Support other explorer windows, e.g. property windows ... } return(suspendedExplorerWindows); }
public override object Suspend(SuspendInformation toSuspend) { var chromeWindows = toSuspend.Windows .Select(w => new WindowInfo(w.Handle)) // For some reason, Chrome windows can use two separate classes. The same ones are also used for status bars, but status bars never have a title set. .Where(w => w.GetClassName().EqualsAny("Chrome_WidgetWin_0", "Chrome_WidgetWin_1") && !w.GetTitle().EqualsAny("", "Chrome App Launcher")); var persisted = new List <ChromePersistedWindow>(); foreach (var w in chromeWindows) { bool hasRetried = false; while (true) { try { // TODO: The window title is passed in order to be able to identify which window needs to be suspended. This title can change dynamically however, so is there a safer way? string title = w.GetTitle(); const string chromeSuffix = " - Google Chrome"; if (title.EndsWith(chromeSuffix)) { title = title.Substring(0, title.Length - chromeSuffix.Length); } persisted.Add(_chromeService.Suspend(title)); break; } catch (RemotingException) { // When a new server has started, and thus the previous pipe connection was closed, the first call results in a 'pipe is closing' exception. // A second call however can succeed, now that the connection is aware it was closed, and a reconnect is attempted. if (hasRetried) { break; } hasRetried = true; } } } return(persisted); }