Как проверить, является ли 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 находится на переднем плане, процесс ни один не возвращается. (Т.е. есть MainWindowHandle, но нет процесса!?)

Процесс MSHTA имеет совершенно другой MainWindowHandle, но не имеет окна.

Process Hacker идентифицирует окно HTA (фрейм или содержимое) как процесс mshta.

Как с помощью скрипта сопоставить окно HTA и mshta.exe? В качестве альтернативы, как я могу получить MainWindowHandle окна HTA, не зная, находится ли оно впереди?


person Teknowledgist    schedule 09.06.2017    source источник


Ответы (2)


Возвращаемое окно 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
person Community    schedule 09.06.2017
comment
Спасибо за предложение, но я стараюсь избегать сторонних инструментов (и я действительно не хочу, чтобы меня помечали как вредоносное ПО, что, скорее всего, связано с CMDOW.EXE). - person Teknowledgist; 12.06.2017
comment
У меня не было времени искать другое решение, я просто показываю принцип получения ВСЕХ оконных дескрипторов и через них получения исходного процесса. - person ; 12.06.2017

Изменен ответ с здесь, чтобы получить то, что мне нужно:

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
}

Надеюсь, это поможет кому-то.

person Teknowledgist    schedule 12.06.2017