前述した公式ブログの古い記事では、Visual Studioに付属する「Spy++」を利用して、ゴーストウィンドウである証拠を示していますが、筆者はもっと簡単な、別の方法で証拠を示したいと思います。
以下のように記述したWindows PowerShellスクリプト(.ps1)を実行すれば、応答なしウィンドウを持つプロセスとプロセスIDを識別することができます。もともとのアプリケーションのプロセスではなく、デスクトップウィンドウマネージャー(dwm.exe)のプロセスが示されるはずです。
$psArray = [System.Diagnostics.Process]::GetProcesses() foreach ($ps in $psArray){ if ($ps.MainWindowTitle -like "*応答なし*") { "Window Title: " + $ps.MainWindowTitle "ProcessName(PID): " + $ps.Name + "(" + [string] $ps.Id + ")" } }
このPowerShellスクリプトの「"*応答なし*"」の部分を「"<実際のウィンドウタイトル>*"」に変えると、さらに興味深い結果が得られます。応答がある状態では、もともとのアプリケーションのプロセスが表示されます。応答なしの状態になると、「ウィンドウタイトル」と「ウィンドウタイトル(応答なし)」の2つのウィンドウが表示され、それぞれアプリケーションのプロセスとデスクトップウィンドウマネージャー(dwm.exe)のプロセスが持つウィンドウであることを示します(画面3)。そして、「ウィンドウタイトル」のウィンドウの方は非表示になっており、ユーザーからは隠されています。
筆者が利用したアプリケーションは、『Windows Sysinternals Administrator’s Reference』という書籍(この書籍のアップデート版『Troubleshooting with the Windows Sysinternals Tools』が2016年末に出ました。日本語翻訳版も近日中に出版されるそうです)の執筆のために作られた「VirtMemTest.exe」というツールで、応答なしウィンドウを意図的に発生させることができます。このツールは、以下のサイトからダウンロードできます。
ちなみに、Windows Sysinternalsの「Process Explorer(Procexp)」を使ってデスクトップウィンドウマネージャー(dwm.exe)のプロセスの詳細を見てみると、「dwmghost.dll」というDLLがロードされていることを確認できます。おそらく、このDLLがゴーストウィンドウを処理しているものと想像します(画面4)。
ところで、Windows SysinternalsのProcess Explorer(Procexp)や「Process Monitor」には、アプリケーションのウィンドウを捕まえ、対応するプロセスを素早く識別できる機能があります。この機能は、ゴーストウィンドウへの配慮がきちんとされており、応答なしのウィンドウを捕まえても、デスクトップウィンドウマネージャー(dwm.exe)ではなく、本当に応答しなくなったアプリケーションのプロセスを識別してくれます。
岩手県花巻市在住。Microsoft MVP:Cloud and Datacenter Management(Oct 2008 - Sep 2016)。SIer、IT出版社、中堅企業のシステム管理者を経て、フリーのテクニカルライターに。マイクロソフト製品、テクノロジーを中心に、IT雑誌、Webサイトへの記事の寄稿、ドキュメント作成、事例取材などを手掛ける。個人ブログは『山市良のえぬなんとかわーるど』。近著は『Windows Server 2016テクノロジ入門−完全版』(日経BP社)。
Copyright © ITmedia, Inc. All Rights Reserved.