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; }
/// <summary> /// Persists the current state of the application, and then suspends it. /// </summary> /// <param name = "toSuspend">Holds information about the process to suspend.</param> /// <returns>The object which holds the persisted data.</returns> public abstract object Suspend( SuspendInformation toSuspend );
/// <summary> /// Persists the current state of the application, and then suspends it. /// </summary> /// <param name = "toSuspend">Holds information about the process to suspend.</param> /// <returns>The object which holds the persisted data.</returns> public abstract object Suspend(SuspendInformation toSuspend);