【问题标题】:How to check if HTA is foreground window?如何检查HTA是否是前景窗口?
【发布时间】:2017-06-09 15:52:27
【问题描述】:

我正在尝试确定 HTA 是否是前景窗口。以下 PowerShell 通常会识别前台窗口:

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

$a = [UserWindows]::GetForegroundWindow()
get-process | ? { $_.mainwindowhandle -eq $a }

但是,如果 HTA 在前台,则返回 no 进程。 (即有一个MainWindowHandle,但是没有进程!?)

MSHTA 进程有一个完全不同的 MainWindowHandle,但没有窗口。

Process Hacker 将 HTA 窗口(框架或内容)识别为 mshta 进程。

如何通过脚本匹配 HTA 窗口和 mshta.exe?或者,如何在不知道它是否在前面的情况下获取HTA窗口的MainWindowHandle?

【问题讨论】:

    标签: powershell user-interface hta


    【解决方案1】:

    返回的 Foregroundwindow 不是任何进程的主窗口句柄,而只是 mshta 的窗口句柄,您必须检查所有窗口句柄。
    我使用工具 cmdow.exe 手动完成(必须将句柄转换为十六进制)并在我的示例中得到了这个 The HTA helpomatic

    > cmdow 0x14E0F46
    Handle   Lev  Pid -Window status- Image    Caption
    0x14E0F46 1 153048 Res Ina Ena Vis mshta    The HTA Helpomatic -- Presented by t
    

    应该有更好/更多的 PowerShellish 方法来枚举窗口句柄,但这个更改后的脚本将使用提到的 cmdow.exe

    ## Get-ForegrounWindow.ps1
    Add-Type @"
       using System;
       using System.Runtime.InteropServices;
       public class UserWindows {
          [DllImport("user32.dll")]
          public static extern IntPtr GetForegroundWindow();
       }
    "@
    
    while ($true -eq 'true') {
        $ForeGroundWin = [UserWindows]::GetForegroundWindow()
        $handle = "0x{0:x}" -f $($ForeGroundWin.ToInt64())
        cmdow.exe $Handle /B /F
        Sleep -sec 5  
    }
    

    样本输出:

    > .\Get-ForegrounWindow.ps1
    0x15C04A2 1 127148 Res Act Ena Vis powershell Windows PowerShell
    0x7F0DE4 1 135416 Res Act Ena Vis TextPad  TextPad - Q:\Test\2017-06\09\Get-ForegrounWindow.ps1
    0x16205D0 1 121732 Res Act Ena Vis bash     usernamet@computer: ~
    0x14E0F46 1 153048 Res Act Ena Vis mshta    The HTA Helpomatic -- Presented by the Microsoft Scripting Guys
    

    【讨论】:

    • 感谢您的建议,但我会尽量避免使用第三方工具(而​​且我真的不想被标记为恶意软件——这可能与CMDOW.EXE)。
    • 我没有时间找到另一个解决方案,只是展示获取ALL窗口句柄并通过它获取原始进程的原理。
    【解决方案2】:

    修改了here 的答案以获得我需要的答案:

    Add-Type  @"
    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    public class UserWindows {
       [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 GetWindowTextLength(IntPtr hWnd);
    }
    "@
    
    while(1) {
       $ForgroundWindow = [UserWindows]::GetForegroundWindow()
       $FGWTitleLength = [UserWindows]::GetWindowTextLength($ForgroundWindow)
       $StringBuilder = New-Object text.stringbuilder -ArgumentList ($FGWTitleLength + 1)
       $null = [UserWindows]::GetWindowText($ForgroundWindow,$StringBuilder,$StringBuilder.Capacity)
       if ($StringBuilder.ToString() -match $HTAWindowTitleRegEx) {
          # Put further scripting here for when the HTA window is in front
       }
       Start-Sleep -Seconds 1
    }
    

    希望对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2010-10-25
      • 2011-10-30
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 2017-12-29
      • 1970-01-01
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多