macOSで浮いているダイアログ、反応しないログイン画面、正体不明のポップアップを見て、「このウィンドウはどのプロセスが作っているのか」と疑問に思ったことがあれば、それは珍しいことではありません。FinderやDockからは答えが見えず、Activity Monitorも一部しか助けてくれません。
結論から言うと
macOSで特定のウィンドウを所有しているプロセスを調べる最も信頼できる組み込みの方法は、Quartz Window ServicesのCGWindowListCopyWindowInfoを使ってkCGWindowOwnerPIDを取得し、そのPIDをpsで確認することです。Activity Monitorでも候補は絞れますが、ウィンドウとプロセスを正確に対応付けるならQuartzの方が確実です。
なぜmacOSではこの確認が分かりにくいのか
macOSには「このウィンドウを右クリックしてPIDを表示する」といった分かりやすい機能がありません。1つのアプリが複数のウィンドウ、補助プロセス、バックグラウンドエージェントを持つこともあり、タイトルやDockアイコンだけで判断すると誤解しやすくなります。
Appleのドキュメントを見ると理由が分かります。ウィンドウ情報の辞書ではkCGWindowOwnerPIDは必須キーですが、kCGWindowOwnerNameとkCGWindowNameは任意キーです。つまり、所有PIDは安定して取得できますが、アプリ名やウィンドウタイトルは欠けている場合があります。
方法1:アプリがだいたい分かっているならActivity Monitorを使う
どのアプリがそのウィンドウを作っているかおおよそ見当が付いている場合、Activity Monitorは確認用の最も手軽なGUIツールです。
候補を絞る手順
/Applications/Utilities/からActivity Monitorを開きます。- View > Windowed Processesを選び、ウィンドウを作成できるプロセスだけを表示します。
- 親子関係も見たい場合は、View > All Processes, Hierarchicallyを選びます。
- アプリ名で検索し、情報パネルを開くかPIDを控えます。
「このポップアップはSafariなのか、Slackなのか、それともヘルパーアプリなのか」といった場面では十分役立ちます。
Activity Monitorの弱点
Activity Monitorが見せてくれるのはウィンドウを作成できるプロセスであり、「この特定のウィンドウがこのPIDに属している」という直接対応ではありません。次のようなケースでは精度が下がります。
- 1つのアプリが複数のhelperプロセスを起動している
- ウィンドウタイトルとアプリ名が一致しない
- ウィンドウがバックグラウンドエージェントに属している
- 調査をスクリプト化したい
正確に調べたいならQuartzを使うべきです。
方法2:Quartz Window ServicesでウィンドウをPIDにマッピングする
AppleのCore Graphics APIであるCGWindowListCopyWindowInfoは、画面上のウィンドウに関するメタデータを返し、その中に所有PIDが含まれます。短いSwiftコマンドから直接呼び出せるので、フルアプリを作る必要はありません。
表示中のウィンドウと所有プロセスを一覧表示する
swift -e '
import Foundation
import CoreGraphics
let query = CommandLine.arguments.dropFirst().joined(separator: " ").lowercased()
let windows = CGWindowListCopyWindowInfo(
[.optionOnScreenOnly, .excludeDesktopElements],
kCGNullWindowID
) as? [[String: Any]] ?? []
for window in windows {
let owner = (window[kCGWindowOwnerName as String] as? String) ?? ""
let pid = (window[kCGWindowOwnerPID as String] as? Int) ?? 0
let title = (window[kCGWindowName as String] as? String) ?? ""
guard !owner.isEmpty else { continue }
guard query.isEmpty ||
owner.lowercased().contains(query) ||
title.lowercased().contains(query) else { continue }
print("PID: \(pid)\tApp: \(owner)\tWindow: \(title)")
}
' "Safari"
"Safari"の部分を、調べたいアプリ名やウィンドウタイトルの一部に置き換えてください。検索語を省略すれば、列挙できるすべての可視ウィンドウが出力されます。
出力の見方
- PID:
kCGWindowOwnerPIDから取得した所有プロセスID - App:
kCGWindowOwnerNameから取得したプロセス名 - Window:
kCGWindowNameが存在する場合のウィンドウタイトル
本当に知りたいことが「このウィンドウはどのプロセスのものか」なら、これが最も有効な組み込み手段です。
PIDが分かった後にやること
PIDを取得したら、psで実行ファイルやコマンドラインを確認します。
ps -p <PID> -o pid,ppid,comm,args
例:
ps -p 1234 -o pid,ppid,comm,args
これで、怪しいウィンドウから具体的なバイナリ、親プロセス、起動引数までたどれます。
注意点
kCGWindowNameは任意キーなので、タイトルが空のウィンドウもあります。- システムオーバーレイやユーティリティパネルは、同じアプリに属していても別ウィンドウとして見えることがあります。
- 実際には、保護されたアプリは適切なmacOSのプライバシー権限がないと公開するメタデータが少なくなることがあります。
方法3:日常的に調査するならProcXrayを使う
この作業を頻繁に行うなら、生のコマンドだけでは面倒になってきます。**ProcXray**を使うと、正体不明のウィンドウから周辺のプロセス文脈まで素早く追跡できます。
ProcXrayが継続的な調査に向いている理由
- ライブのプロセスツリーで、どの親がそのプロセスを起動したか分かる
- コマンドライン表示で、メインアプリとhelperの違いを見分けやすい
- 環境変数の確認で、Activity Monitorでは見えない起動コンテキストが分かる
- 短命プロセスのキャプチャで、一瞬だけ表示されるウィンドウにも対応しやすい
- コード署名の可視化で、そのプロセスが信頼できるか判断しやすい
アップデータ、helper、短命なバックグラウンドツールが関わる場合、PIDそのものよりもその周辺情報の方が重要になることが多いです。
関連ガイドもあわせてどうぞ。
Activity Monitor vs Quartz vs ProcXray
| 方法 | 向いている用途 | 強み | 制限 |
|---|---|---|---|
| Activity Monitor | ざっと目視で確認したいとき | 標準搭載、使いやすい、PIDが見える | 任意のウィンドウを所有プロセスに直接対応付けられない |
| Quartzによるウィンドウ照会 | ウィンドウからPIDを正確に知りたいとき | 公式API、スクリプト化できる、正確 | 出力後の追跡は手作業が必要 |
| ProcXray | 本格的な調査や継続的なデバッグ | 親子関係、環境変数、署名、短命プロセスまで見える | 別途インストールが必要 |
要点: 一度だけ正確に調べるならQuartzで十分です。ウィンドウ、helper、短命プロセスを繰り返し調べるならProcXrayの方が効率的です。
FAQ
Activity Monitorで特定のウィンドウの所有プロセスを直接確認できますか?
直接はできません。Windowed Processesで候補を絞り込んだり、関連しそうなアプリのPIDを調べたりはできますが、1つのウィンドウをそのまま正確なPIDに対応付ける機能はありません。より正確なのはQuartz Window Servicesです。
ウィンドウの所有プロセスを調べるためのApple公式APIは何ですか?
Appleは、ウィンドウのメタデータを取得するCore Graphicsの関数としてCGWindowListCopyWindowInfoを文書化しています。返される辞書には必須キーとしてkCGWindowOwnerPIDが含まれるため、ウィンドウを所有プロセスへマッピングする際の正式な基準になります。
macOSのウィンドウタイトルが空になることがあるのはなぜですか?
kCGWindowNameは任意キーであり、常に存在するわけではないからです。ユーティリティウィンドウ、システムオーバーレイ、保護されたアプリの画面では、所有PIDだけが見えてタイトルは空になることがあります。
PIDを見つけた後は何をすればいいですか?
ps -p <PID> -o pid,ppid,comm,argsを実行して、実行ファイル、親プロセス、コマンドライン引数を確認してください。まだ怪しい場合は、その後にオープンファイル、ネットワーク接続、コード署名を調べるとよいです。
出典・参考資料
- Apple Developer:
CGWindowListCopyWindowInfo - Apple Developer: Required Window List Keys
- Apple Developer: Optional Window List Keys
- Apple Support: View information about Mac processes in Activity Monitor
- Apple Support: Activity Monitor User Guide
- macOS組み込みリファレンス:
man ps
ProcXrayを無料でダウンロード → — 不審なウィンドウの背後にあるプロセスを、より速く把握できます。