如何检查HTA是否是前景窗口?

时间:2017-06-09 15:52:28

标签: powershell user-interface hta

我试图确定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 进程。 (I.E.有一个MainWindowHandle,但是没有进程!?)

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

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

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

2 个答案:

答案 0 :(得分:0)

返回的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

答案 1 :(得分:0)

修改了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
}

希望能有所帮助。