How to bring GUI window to front after an event?

Viewed 73

As the title says, how can I bring a Powershell GUI window in front of another window after an event has happened, if it is at all possible? As in, I have, for example, Firefox opened and the Powershell GUI is running behind it, after certain event happens inside of the Powershell it pops in front of the Firefox?

1 Answers

On Windows, you can use [Microsoft.VisualBasic.Interaction]::AppActivate() to reactivate your own process' main window via the process ID, as reflected in the automatic $PID variable:

# Load the required assembly.
Add-Type -AssemblyName Microsoft.VisualBasic

# Launch a sample GUI application that will steal the focus
# (will become the foreground application).
Start-Process notepad.exe

# Wait a little.
Start-Sleep 3 

# Now reactivate the main window of the current process.
[Microsoft.VisualBasic.Interaction]::AppActivate($PID)

Caveat:

  • Programmatic activation of a window may be prevented, based on per-user configuration, and is by default. If so, instead of activating the window, its taskbar button flashes, so as to signal to the user the intent to make the window active.

  • You can allow unconditional activation via the SystemParametersInfo WinAPI function, by setting its SPI_SETFOREGROUNDLOCKTIMEOUT to 0, as shown below - use with caution.

Add-Type -ErrorAction Stop -Namespace Util -Name WinApi -MemberDefinition @'
  [DllImport("user32.dll", EntryPoint="SystemParametersInfo")]
  public static extern bool SystemParametersInfo_Set_UInt32(uint uiAction, uint uiParam, UInt32 pvParam, uint fWinIni);
'@

if ([Util.WinApi]:: SystemParametersInfo_Set_UInt32(0x2001 <# SPI_SETFOREGROUNDLOCKTIMEOUT #>, 0, 0 <# timeout in ms. #>, 0 <# non-persistent #>)) { 
  "Set timeout to 0, for this session."
} else {
  throw "Setting timeout failed."
}
Related