【问题标题】:How To Grab the Currently Active/Foreground window in PowerShell如何在 PowerShell 中获取当前活动/前台窗口
【发布时间】:2018-03-03 06:37:01
【问题描述】:

我知道这可以通过使用 alt-tab 轻松完成,但创建此脚本的主要目的是自学一些 PowerShell 基础知识。

我正在编写一个脚本,该脚本在运行时会在 powershell 和当前前台窗口之间切换前台窗口。我阅读了this question 并使用其中一个答案来获取检索当前前景窗口的代码,但它似乎没有抓取正确的窗口 - 它似乎抓取了 explorer.exe

下面是我的脚本代码,希望对 cme​​ts 有帮助:

# 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
}

我在想也许我应该尝试获取活动窗口而不是前景窗口,但another question's answer 说前景意味着活动。

我使用的是 Windows 10。

编辑:我认为它可能使用 explorer.exe 作为“前景窗口”,因为我通过从资源管理器启动的快捷方式调用脚本。

【问题讨论】:

  • 从命令提示符运行脚本,看看它是否仍然返回 Explorer.exe 作为前台窗口。
  • 它返回了运行它的提示的PID。
  • 那么这里的目标是什么?
  • 我非常希望有一个键盘快捷键,当按下它时,将当前进程(例如,假设我正在对 Chrome 进行一些研究,然后它将存储浏览器的 PID)存储在内存中,并且切换到powershell。然后,当再次按下时,切换回存储过程。我的方法是编写这个脚本,然后创建一个调用它的键盘快捷键。

标签: powershell


【解决方案1】:

试试这个来获取你喜欢的进程的ID,或者通过你喜欢的任何其他方式来获取它。

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 }

现在,假设您的活动窗口是另一个窗口,您想回到与$WH 相关的窗口。只需使用following code 即可移回它。您可以使用您喜欢的任何触发器来执行此操作,如您使用键盘热键或自动提到的。

$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) 

【讨论】:

  • 这可行,但 CPU 成本高,大约需要半秒
【解决方案2】:

我从Justin Richsocial.technet.microsoft.com 找到了这个快速且非 CPU 密集型的解决方案

Add-Type  @"
 using System;
 using System.Runtime.InteropServices;
 using System.Text;
public class APIFuncs
   {
    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
   public static extern int GetWindowText(IntPtr hwnd,StringBuilder
lpString, int cch);
    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
   public static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
       public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd,out
Int32 lpdwProcessId);
    [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
       public static extern Int32 GetWindowTextLength(IntPtr hWnd);
    }
"@
 
while(1)
{
$w = [apifuncs]::GetForegroundWindow()
$len = [apifuncs]::GetWindowTextLength($w)
$sb = New-Object text.stringbuilder -ArgumentList ($len + 1)
$rtnlen = [apifuncs]::GetWindowText($w,$sb,$sb.Capacity)
write-host "Window Title: $($sb.tostring())"
sleep 1
} 

【讨论】:

    猜你喜欢
    • 2011-12-02
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多