Freigeben über


VBScript: Betcha never thought of this one

I mentioned in a previous post that I had to solve a little issue with the wonderful WMCMD.VBS script that Alex Zambelli maintains.  Because of some occasional nastyness, when the script is done--successful or not-- it tries to kill it's own process, in case any of the WM Encoder objects gets hung up.

The original script uses WMI to look on the machine for the cscript process for the currently running script:

function TerminateEncoderProcess() dim objWMIService dim objProcess On Error Resume Next ' Get Windows Manager object Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\.\root\cimv2") ' Enumerate all CScript.exe processes dim colProcessList Set colProcessList = objWMIService.ExecQuery _ ("Select * from Win32_Process Where Name =" _ & "'cscript.exe'") dim strArguments strArguments = "" ' Enumerate all command-line arguments for i = 0 to wscript.arguments.Length-1 strArguments = strArguments & " " & _ wscript.arguments(i) next strArguments = Replace(strArguments, Chr(34), "") ' Kill the processes that match this one in name and arguments For Each objProcess in colProcessList if InStr(1, Replace(objProcess.CommandLine, _ Chr(34), ""), _ Trim(WScript.ScriptName & strArguments), 1 ) > 0 _ then objProcess.Terminate() end if Next ' What? Still not terminated? OK, kill first occurrence. For Each objProcess in colProcessList if InStr(1, objProcess.CommandLine, _ WScript.ScriptName) > 0 then objProcess.Terminate() end if Next end function

Unfortunatly, this script, when all else fails, tries to kill itself by finding the first running cscript, and killing it. Hmmm. not too good, I had multiple encoder script processes going on, and it kept killing the wrong one.

A pity it seems so hard to find the current process in VBScript... until I thought about it a bit more:

 

function TerminateEncoderProcess() GetObject("winmgmts:root\cimv2:Win32_Process.Handle='" _ & GetObject("winmgmts:root\cimv2:Win32_Process.Handle='" _ & CreateObject( "WScript.Shell").Exec("cmd.exe").ProcessId _ & "'").ParentProcessId & "'").Terminate end function

Huh?

This version of the script spawns off a new cmd.exe process (which exits nearly instantly), but uses the process ID from that, looks up the process, and get it's parent process, and then terminate that.  Nice thing is, it don't get confused :D