torutkのブログ

ソフトウェア・エンジニアのブログ

Windowsで稼動中のプロセス一覧、CPU・メモリサイズを取得するには

前々からの課題の一つに、JavaプログラムからWindows OS上の稼動プロセス一覧、それぞれのメモリ/CPU使用率を取り出す方法を見出すことがあります。OS固有の処理になるのでJNIを使うつもりです。
ところが、Win32 APIを調べまわっているのですが、なかなか簡単な方法が見つかりません。

CreateToolhelp32SnapshotとProcess32First/Process32Nextを使う

プロセス一覧は取れますが、CPU使用率、メモリサイズは取れないようです。

#include <windows.h>
#include <tlhelp32.h>
...
  HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  PROCESSENTRY32 entry;
  entry.dwSize = sizeof(PROCESSENTRY32);
  if (Process32First(hSnapshot, &entry)) {
    do {
      // entry.szExeFile           :プロセス名(実行ファイル名)
      // entry.th32ProcessID       :プロセスID
      // entry.th32ParentProcessID :親プロセスID
    } while(Process32Next(hSnapshot, &entry));  

PdhOpenQuery

使用方法が面倒そうです。

レジストリから情報を取り出す

レジストリ(といってもregedit等では見えない)に、パフォーマンス情報が保持されているようです。
レジストリを読み出すコードは結構面倒なので、ちょっと意欲なし。

NtQuerySystemInformation

Windowsの悪名高い非公開APIのようです。ntdll.dllにコードが含まれますが、開発に必要なヘッダーやインポートライブラリは見当たらなかったので、どうビルドするのか不明です。どうやら自前でヘッダーファイルを作り、インポートライブラリはdumpbinコマンドあたりで生成する?

  • Microsoft SDKのwinternl.hに以下の定義がありました
    • NtQuerySystemInformation関数のプロトタイプ宣言
    • SYSTEM_PROCESS_INFORMATION(*PSYSTEM_PROCESS_INFORMATION)構造体定義
  • 関数の呼び出しは、LoadLibraryでntdll.dllをロードし、GetProcAddressでNtQuerySystemInformation関数のポインタを取得し呼び出す