1. トップ
  2. 新着ニュース
  3. IT
  4. IT総合

Windowsではプロセスからプログラムに関するさまざまな情報が得られる

ASCII.jp / 2023年10月1日 10時0分

プロセス
Microsoftが提供するSysinternalsの「Process Explorer」を使うと、ジョブオブジェクトを調べることができる。Optionメニューの「Configure Color」でJobsのチェックボックスをオンにする。ジョブでグループ化されているプロセスに指定した色がつく

 コンピューターでは、プログラムを実行するとメモリに読み込まれて「プロセス」になる。プロセスからはさまざまな情報が得られる。今回は、プロセスから情報を取得する方法について解説する。その前に、プロセスや関連の用語が混乱しているので、1回整理しておこう。

そもそもWindowsにおける「プロセス」とは

 「プログラム」とは命令の連なりであり、これを記録したものが実行ファイルだ。ほとんどのプログラムは、実行ファイルという形を持つが、プログラムがプログラムを作って、実行ファイルという形を経ずに実行させることもできる。しかし、セキュリティの観点上、こうした手法には制限がかかる。悪意のある多くのプログラムが実際そうするからだ。そのため、通常はプログラムとは実行ファイルに記録されているものと考えていい。

 プロセスは、プログラムのインスタンス(実体)とも呼ばれることがある。実行ファイルに記録されているものはプログラムの定義であり、実行することで実体となるという考え方だ。あえてたとえるなら、プログラムとプロセスの関係は楽譜と演奏の関係である。

 Windowsは、実行ファイルから読み込まれたコードやデータなどを、一定の方法でメモリ上に配置する。このメモリ領域を実行イメージと呼ぶ。プロセスには、実行時間やファイルへのアクセス、接続しているネットワークポートといった「資源」(リソース)がプロセスに割り当てられる。Windowsでプロセスは、このようなリソースの割り当て、管理単位である。

 プロセスは、1つ以上のスレッドから構成される。スレッドとは、実行スケジューリングの管理単位だ。最初に起動されるのがメインスレッドで、この中でさらにスレッドを作り出すことができる。

 そのほかの用語として「ジョブ」と「タスク」がある。一般的な定義もあるが、Windowsではプロセスをグループとして管理するものがジョブ(正確にはジョブオブジェクト)である。たとえば、Google Chromeは多数のChrome.exeプロセスを作るが、これらはジョブオブジェクトでグループ化されている。ジョブに対しては、起動や停止といった操作をし、ジョブに属するプロセスをまとめて制御できる。

 Windowsでは、「タスク」は、ほぼプロセスの同義語として使われる。たとえば、タスクマネージャーやタスクリスト(tasklist.exe)といったプログラムは、プロセスに関する情報を扱うものだ。ただし、タスクスケジューラーは、プロセスではなく、プログラムの起動を管理している。

プログラムよりもプロセスからの情報を得るほうが簡単

 Windowsを含む多くのOSは、プロセスから情報を得るためのAPIが用意されている。このため、プロセスからプログラムに関する情報を得ることが可能になる。

 もちろん、プログラム自体からも情報を得られるが、そのためにはプログラム(の実行ファイルなど)を解析して、挙動を推測しなければならない。これは、かなり面倒で高度な作業だ。しかし、プログラムを実行してプロセスから情報を得ることは簡単にできる。

 たとえば、アプリケーションのウィンドウに表示されるタイトルはプロセスから簡単な方法で確認できる。しかし、プログラムから得るためには、プログラムコードを追いかけて、タイトルに表示される文字列を作る処理を突き止める必要がある。

 プロセスには、ユーザーが直接起動したプログラムだけでなく、Windowsが起動したプログラムのプロセスや、アプリケーションが起動したプロセスもある。適切な権限さえあれば、こうしたプロセスからさまざまな情報を得られる。

 たとえば、新旧の複数バージョンがインストールされているプログラムでも、プロセスから情報を得ることで、どちらが起動しているのかを判定可能だ。

 タスクマネージャーやリソースマネージャーは、プロセスの情報を表示することができる。またWindowsには、tasklistのようなプロセスを列挙し情報を表示するプログラムもある。ただし、これらは、プロセスが持つ情報の一部しか出力することができない。

 PowerShellのGet-ProcessコマンドやMicrosoftが提供するSysinternalsの「Process Explorer」(https://learn.microsoft.com/ja-jp/sysinternals/downloads/process-explorer、要インストール)は、プロセスからより詳細な情報を得ることができる(記事冒頭画面)。また、Windowsの管理機構であるWMI/CIMを使っても、同様に可能だ。

プロセスが持つ情報は何?

 タスクマネージャーもプロセスから情報を得て動作しているが、プロセスが持つ情報は多く、またGUIプログラムであるため、表示できる情報が限定されている。

 これに対してWindows PowerShell(およびPowerShell 7.x)のGet-Processコマンドは、実行中のプロセスから多くの情報を得ることができる。

 その情報は、.NET Framework/.NETのProcessクラス(System.Diagnostics.Process)に準じているが、Get-Processコマンドは、さらに「便利」なプロパティが追加されている。以下の表に追加されている主なプロパティを示す。これらは、プロセス情報をProcessクラスから得たあと、そのプロパティを使って、さらにAPIで得られる情報のうち、比較的利用頻度が高そうなものだ。

プロセス

 たとえば、プロセスの親プロセスは、PowerShell 7ではParentプロパティに入る。この中身もプロセス情報なので、同じように親をたどっていくことができる。CommandLineプロパティは、プロセスを起動したときのコマンドラインが記録されている。これを見ることでプロセスがどのように起動されたのかを知ることが可能だ(ただし、CommandLineプロパティを持たないプロセスも存在する)。そのほかには、プログラムのバージョンを表すProductVersionなどがある。

 なお、ParentとCommandLineは、PowerShell 7では利用できるが、Windows PowerShellでは利用できない。ただし、Get-CIMInstanceコマンド経由でWMI/CIMから同等の情報を得ることは可能だ。

Get-CimInstance Win32_Process | select ProcessName,ParentProcessId, CommandLine

 基本となるProcessクラスで得られる情報に関しては、マイクロソフトのLearnページに記載がある。

●Process クラス  https://learn.microsoft.com/ja-jp/dotnet/api/system.diagnostics.process?view=netframework-4.8.1

 このクラスには、たとえば、ウィンドウのタイトル文字列を示すMainWindowTitleや、関連付けられているDLLなどのプログラムを列挙できるModules、各種メモリ指標(ページメモリサイズやワーキングセットなど)、プロセスから起動されたスレッド(Threads)などがある。

 どんな情報があるのかを概観したければ、Get-Processの出力をOut-GridViewですべて表示可能。全体を眺めて見ることでどのような情報が出力されているのかを把握できる。

Get-Process | select * | Out-GridView

 Microsoftストアからインストールしたアプリの場合、プロセスのPathプロパティ(実行ファイルのパス)を使って、パッケージ情報を得ることも可能だ。Microsoftストアからインストールしたアプリは、「C:\Program Files\WindowsApps」のサブフォルダにインストールされ、このときのサブフォルダ名がパッケージのPackageFullNameに相当する。このことを使うと、Get-AppxPackageコマンドからパッケージ情報を得ることができる。

 たとえば、PowerShellの親プロセスのPathプロパティを見ることで、標準コンソール(conhost.exe)かWindowsターミナルなのか、ターミナルなら通常版かプレビュー版かを判断できる。

 インストール先サブフォルダは「Microsoft.WindowsTerminalPreview_1.18.1462.0_x64__8wekyb3d8bbwe」のようになり、Windowsターミナルなら"WindowsTerminal"の文字があり、さらにプレビュー版なら、は、“Preview”の文字が入る。情報を取り出すには、

(Get-Process -id $pid).Parent.Path

とする。“$pid”は、PowerShellのプロセスIDが自動的に入る変数である。

 PathプロパティからSplit-Pathコマンドで末尾の実行ファイル名を抜いたものと、Get-AppxPackageコマンドのInstallLocationプロパティが一致するものを探すことで、Get-AppxPackageコマンドで得られるパッケージ情報を見つけることができる。

Get-AppxPackage | ? InstallLocation -eq ((Get-Process -id $pid).Parent.path|Split-Path)

 このようにして、プロセスから得られる情報を起点に、プログラムに関するさまざまな情報にアクセスできる。プログラムの情報は、プログラムの実行ファイルや関連ファイルにあると考えがちだが、実際には、プログラムを起動させてプロセスから取得するほうが簡単である。

この記事に関連するニュース

トピックスRSS

ランキング

記事ミッション中・・・

10秒滞在

記事にリアクションする

記事ミッション中・・・

10秒滞在

記事にリアクションする

デイリー: 参加する
ウィークリー: 参加する
マンスリー: 参加する
10秒滞在

記事にリアクションする

次の記事を探す

エラーが発生しました

ページを再読み込みして
ください