2008年12月5日金曜日

GetProcess.cmd

状況によっては、内部で作成している WShell.exec("xx") の部分が非同期にならず、
PIDを取得しようとした時に当該プロセスが存在しないというエラーになる場合があった。
んで、改良版がこれ。呼び出すプロセスとしてcscript.exeの代わりにcmd.exeを
使用し、pauseにて入力を待つようにした。これだと非同期に実行でき、不要に
なったらさっと片づけられる。


@if(0)==(0) ECHO OFF
:: GetProcessId.cmd ver 1.2
:: PolymorphicScript(CMD/JSCRIPT)
:: http://scripting.cocolog-nifty.com/blog/2007/01/index.html
:: V1.1 20081127 ST(KRB)
:: V1.2 20081202 ST(KRB) replace vbs with self script cause file permission
:: V1.3 20081205 ST(KRB) use cmd.exe for inspect pid instead of cscript.exe
CScript.exe //NoLogo //E:JScript "%~f0" %*
GOTO :EOF
@end
//
var error_level = 0;
try
{
var pGene = 0;
if(WScript.Arguments.Named.Exists("P")) {
pGene = WScript.Arguments.Named.Item("P");
}
if(WScript.Arguments.UnNamed.Length==0) {
PrintPPid(GetPID(), pGene);
//WScript.Echo(GetPPID(GetPID()));
error_level = 0;
} else if(WScript.Arguments.UnNamed.Length==1) {
PrintPPid(WScript.Arguments.Item(0), pGene);
// WScript.Echo(GetPPID(WScript.Arguments.UnNamed.Item(0)));
error_level = 0;
} else {
WScript.StdErr.WriteLine("Usage: GetProcessID.CMD [/P:n | PID]");
error_level = 2;
}
}
catch(e)
{
WScript.StdErr.WriteLine("error:" + e.message);
error_level = 1;
}
finally
{
WScript.Quit(error_level);
}

function PrintPPid(ipid, igen){
var result = ipid;
for (var i=0;i <= igen;i++){
result = GetPPID(result);
}
WScript.Echo(result);
}

function GetPID(){
var Path=WScript.ScriptFullName;
var wShell=new ActiveXObject("WScript.Shell");
// if use cscript.exe ,cannot run as async mode
var oExec=wShell.Exec('cmd.exe /C pause');
var PID=GetPPID(oExec.ProcessID);
try{
// Terminate() may needs waite time for several seconds
// so input as enter to 'pause' cmd
oExec.StdIn.WriteLine("");
oExec.Terminate();
}
catch(e)
{
// none
}
return PID;
}

function GetPPID(PID){
var SWbemObjectSet=GetObject("winmgmts:root/CIMV2").ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID=" + PID);
if(SWbemObjectSet.Count!=1){
WScript.StdErr.WriteLine("ID " + PID + " Not Found.");
WScript.Quit(1);
}
var Processes=new Enumerator(SWbemObjectSet);
for(;!Processes.atEnd();Processes.moveNext()){
var Process=Processes.item();
return Process.ParentProcessID;
}
}

0 件のコメント: