Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How To Grab the Currently Active/Foreground window in PowerShell

Tags:

powershell

I understand that this can easily be accomplished by using alt-tab, but the main purpose of this script's creation is to teach myself some PowerShell basics.

I'm writing a script that, when run, toggles the foreground window between powershell and the current foreground window. I read this question and used one of the answers to get the code for retrieving the current foreground window but it doesn't seem to grab the correct window - it instead seems to grab explorer.exe

Below is my code for the script with hopefully helpful comments:

# Toggle-PowerShell.ps1
# Toggles focus between powershell and the current active window.
# If this script isn't run with -NoProfile, it will switch focus to itself.

. $PSScriptRoot\..\Functions\Toggle-Window.ps1

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Util {
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}
"@

$a = [util]::GetForegroundWindow()

# Get-Unique may be unnecessary here, but including it for the case when
# working with Chrome as the stored process
$storedProcess=get-process | ? { $_.mainwindowhandle -eq $a } | Get-Unique

If(Test-Path $PSScriptRoot\Toggle-PowerShell.temp)
{
    $tempArray=(Get-Content $PSScriptRoot\Toggle-Powershell.temp)

    # the id number is at index three of tempArray
    Show-Process -Process (Get-Process -id $tempArray[3])

    # delete the file so the next time we run the script it toggles to PS
    Remove-Item $PSScriptRoot\Toggle-PowerShell.temp
} Else
{
    $propertiesFile=$PSScriptRoot\..\currentSession.properties
    $propertiesMap = convertfrom-stringdata (get-content $propertiesfile -raw)

    Show-Process -Process (Get-Process -id $propertiesMap.'PowerShellPID')

    # write a new temp file that contains the stored process's id
    # so that the next time this script is run it toggles back
    $storedProcess | Select-Object Id > $PSScriptRoot\Toggle-PowerShell.temp
}

I was thinking perhaps that maybe I should try getting the active window instead of the foreground window but another question's answer said that foreground implies active.

I'm on Windows 10.

EDIT: I think that it may be using explorer.exe as the 'foreground window' because I call the script via a shortcut, which launches from explorer.

like image 1000
mystbinder Avatar asked Sep 21 '17 19:09

mystbinder


1 Answers

Try this one to get the ID of the process you like or just get it by any other way you prefer.

Add-Type @"
  using System;
  using System.Runtime.InteropServices;
  public class Tricks {
    [DllImport("user32.dll")]
    public static extern IntPtr GetForegroundWindow();
}
"@

$a = [tricks]::GetForegroundWindow()

$WH = get-process | ? { $_.mainwindowhandle -eq $a }

Now, imagine that you active window is another one and you would like to go back to the one related to $WH. Just use the following code to move back to it. You can do it with whatever trigger you like, as you mentioned with keyboard hotkey or automatically.

$sig = '
    [DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll")] public static extern int SetForegroundWindow(IntPtr hwnd);
'

$type = Add-Type -MemberDefinition $sig -Name WindowAPI -PassThru
# maximize the window related to $WH; feel free to play with the number
$null = $type::ShowWindowAsync($WH, 4)
# change the focus to $WH
$null = $type::SetForegroundWindow($WH) 
like image 81
Alin Avatar answered Nov 15 '22 07:11

Alin