Win32_Processのメモ2008年06月17日 03時48分07秒

前のエントリで書いた「ps.js」は、基本的にWMIでWin32_Processを列挙してそこから得られる情報を出力しているのだが、CPU時間とオーナーはちとてこずったのでその辺のメモをば。

まず、Win32_Processオブジェクトのメンバーについては、以下を参照。

CPU時間

Win32_Processのプロパティの中で、名前に「Time」がついているのは「KernelModeTime」と「UserModeTime」の2つ。そんで、どちらのプロパティも解説をみると

  • 64ビット 符号なし整数
  • 100ナノ秒単位
とある。

例えば「vmware-authd.exe」というプロセスが、CPU時間「0:13:36」という表示になっているとして、このプロセスをWQLで検索して、KernelModeTime/UserModeTimeの各プロパティ値を1000万で割ってみると、

プロパティ 値 / 1000万
KernelModeTime 5390451088 539.0451088
UserModeTime 2814146544 281.4146544
のようになった。ふむ、どうやらタスクマネージャのCPU時間はカーネルモード+ユーザモードらしい。これで時間の値は取得できたのであとは表示。

最初は「ミリ秒単位にしてDateに食わせりゃあんまり計算しなくていいかも」とか不精なことを考えていたのだが、GMT時差補正や24時間を越えた場合の展開、getMinutes()やgetSeconds()などをちくちく呼び出すことを考えたら、素直に計算したほうが早いことに気づいたのでベタで計算することにした。

ちなみにuint64にそのまま合わせるデータ型がないためか、JSでKernelModeTimeなどを取得した場合、返ってきたデータの型はstringだったので、そこらへんも注意。

オーナー情報の取得

プロパティをざっと眺めたところ、それっぽいやつはなかったのだが、メソッドのほうには「GetOwner」「GetOwnerSid」とそれっぽいやつがあった。

「GetOwnerSid」はSIDを取得するのだろうから、今回は用なしとした。そんな値みてもすぐにはピンと来ないし、第一長すぎるし。

なので、「GetOwner」メソッドの詳細を見てみたところ、

uint32 GetOwner(
 [out] string User,
 [out] string Domain
);
なんて定義になっていた。outパラメータで値を取得し、メソッドの戻り値は成否を示すらしい。

って、JSでoutパラメータなんでどうやって取り回すんだ??

ためしに

// proc には Win32_Processのインスタンスが入ってるとして、
var user, domain;
var result = proc.GetOwner( user, domain );
if( result == 0 ) { // success
	WSH.Echo( "user = " + user + "\ndomain = " + domain );
}
とかやってみたが、result == 0 の場合でもuser/domainとも値が入っていない。まぁ予想はしてたけど。

この説明ページにあるVBSのサンプルコードは

Return = objProcess.GetOwner(strNameOfUser)
とか普通にやってるのだがJSのサンプルないし。さて、困った。

んで「Win32_Process getowner jscript」なんてベタキーワードでググってみたら見つかりましたよ、こんなのが。

var q = "SELECT * FROM Win32_Process";
var e = New Enumerator( GetObject( "winmgmts:{impersonationLevel=impersonate}!//./root/cimv2" ).ExecQuery( q ) );

WScript.Echo("User\tPID");

for ( ; e.atEnd(); e.moveNext() )
{
   var x = e.item();
   var ometh = x.Methods_.Item("GetOwner");
   var xout = x.ExecMethod_(ometh.Name, null);
   var user = xout.User;
   var domain = xout.Domain;

   WScript.Echo(user + "\t" + x.ProcessId );
} 

なるほど、ExecMethod_なんてリフレクションメソッドを使うと、outパラメータの値も戻り値に含まれるのね。ちなみにGetOwner()を普通に呼び出したときの戻り値は上記「xout」の「ReturnValue」プロパティに入るらしい。

で、これを参考に

var info = proc.ExecMethod_( proc.Methods_.Item("GetOwner").Name, null );

なんてコードを書いたんだけど、よくよく考えてみると「proc.Methods_.Item("GetOwner").Name」って普通に"GetOwner"を返すので、
var info = proc.ExecMethod_( "GetOwner", null );
でぜんぜん問題なかったんだけどね(あ、第二引数もいらないかも)。

オマケ・現在のログオンユーザ情報の取得

ps.jsでは、-aオプションなしの時はオーナーが現在のログオンユーザのプロセスに限定するようにしたんだけども、その「現在のログオンユーザ」の取得はWMIとはまったく別口で取得。

こっちはきわめて簡単で、WScript.NetworkオブジェクトのUserDomain/UserNameプロパティでOK。オマケにComputerNameでNetBIOS名も取れる。

var net = new ActiveXObject("WScript.Network");
WSH.Echo( [
	"user = " + net.UserName,
	"domain = " + net.UserDomain,
	"machine = " + net.ComputerName
].join("\r\n") );

コメント

_ nysh ― 2009年01月08日 15時52分00秒

助かりました。

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://dara-j.asablo.jp/blog/2008/06/17/3581566/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。