LoginSignup
15
9

More than 3 years have passed since last update.

PowerShellでアクティブウィンドウのプロセスを拾う

Last updated at Posted at 2019-06-23

プレイ中にゲームが非アクティブになる!
My Window Loggerでも原因となっているアクティブになったウィンドウがわからない!
…というフレンドの要請があったので、原因調査のためにPowerShellでアクティブウィンドウになっているプロセスを拾うスクリプトを作りました。

コードの実装

check_activeprocess.ps1
$code = @'
    [DllImport("user32.dll")]
     public static extern IntPtr GetForegroundWindow();
    [DllImport("user32.dll")]
    public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
'@

Add-Type $code -Name Utils -Namespace Win32
$myPid = [IntPtr]::Zero;

while(1){
    $hwnd = [Win32.Utils]::GetForegroundWindow()
    $null = [Win32.Utils]::GetWindowThreadProcessId($hwnd, [ref] $myPid)
    Write-Host (Get-Process | Where-Object ID -eq $myPid | Select-Object Name,processName,Id,Path,MainWindowTitle)
    Start-Sleep -Milliseconds 500
}

コードの説明

Add-Type $code -Name Utils -Namespace Win32
$myPid = [IntPtr]::Zero;
無限ループに入る前にAddt-Typeで読み込みと変数($myPid)の初期化をしておきます。

[Win32.Utils]::GetForegroundWindow()
でアクティブになっているウィンドウハンドルを拾い、

[Win32.Utils]::GetWindowThreadProcessId($hwnd, [ref] $myPid)
で上記で拾ったウィンドウハンドルを元にプロセスIDを拾い、

Get-Process | Where-Object ID -eq $myPid
Get-Processで該当のプロセスIDと同じものを検索しています。

なお、上記のスクリプトではログには出力せず、ただただ結果を吐き続けるだけです。
「アクティブウィンドウになっているプロセスを拾う」という目的は達しているので、
ログとして出力が必要となれば、それなりに編集しておく必要があります。

技術参考

How to Get Active Process Name in C#?
上記はC#ですが、PowerShellで実行出来るように編集しています。

余談

非アクティブの原因はマカフィーのmcUIcnt.exeでした。
どうもこの非アクティブになる(フォーカスが外れる)のは昔からあるようで、マカフィーのコミュニティにおけるベストアンサーも「I gave up on this, and I switched to another virus scanner (paid).」となっていました。
参考:McUICnt.exe steals the current windows focus every 3 hours. How can I stop this?

My Window Loggerで検知できなかった理由はわかりませんが、WindowTitleが設定されていなかったからとかでしょうか。
他のプレイヤーの調査では上記ソフトで発見出来ていたようなので、今回が稀な例なのだと思われます。

15
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9