Hi Park,
If you use command “ping 10.0.0.0 -n 90 -w 1000 > NUL”,
it creates two processes ‘cmd.exe’ and ‘ping.exe’.
I can get pid of ‘cmd.exe’, but not pid of ‘ping.exe’.
If you download pstools from:
http://www.sysinternals.com/ntw2k/freeware/pstools.shtml
and run “pslist -t” it shows you the process tree.
(There is also a Win2K ResourceKit utility “ptree” which I believe does
the
same thing).
Which tells me that there is Windows API which exposes the parent-child
relationship of processes.
May be that is what is needed to finish it off.
If you can find pid of ‘ping.exe’, there’s no problem.
It’s your chance to finish this program perfectly.
Assuming I get hold of the pid for “ping”, I guess, I will have to replace
the following line of your modification:
hProcess = OpenProcess.Call(0x100001, 1 , f.pid)
^^^^
with:
hProcess = OpenProcess.Call(0x100001, 1 , ping_pid)
Right ?
I will try … but I am not as comfortable with Windows API as you are
…so
I might call for help again
Thanks for your information.
Here is my final version.
···
#===========================================================================
require ‘Win32API’
OpenProcess = Win32API.new(“kernel32”,“OpenProcess”,[‘L’,‘L’,‘L’],‘L’)
TerminateProcess = Win32API.new(“kernel32”,“TerminateProcess”,[‘L’,‘L’],‘L’)
WaitForSingleObject =
Win32API.new(“kernel32”,“WaitForSingleObject”,[‘L’,‘L’],‘L’)
RegCloseKey = Win32API.new(“advapi32”,“RegCloseKey”,[‘L’],‘L’)
RegOpenKeyEx =
Win32API.new(“advapi32”,“RegOpenKeyEx”,[‘L’,‘P’,‘L’,‘L’,‘P’],‘L’)
RegQueryValueEx =
Win32API.new(“advapi32”,“RegQueryValueEx”,[‘L’,‘P’,‘L’,‘P’,‘P’,‘P’],‘L’)
INITIAL_SIZE = 51200
EXTEND_SIZE = 25600
REGKEY_PERF = “software\microsoft\windows
nt\currentversion\perflib\009”
REGSUBKEY_COUNTERS = “Counters”
KEY_READ = 0x20019;
ERROR_MORE_DATA = 234
HKEY_LOCAL_MACHINE = 0x80000002
HKEY_PERFORMANCE_DATA = 0x80000004
return hash key : parent pids, value : array of child pids
def getpids()
result = Hash.new
hKeyNames = “\0”*4
rc = RegOpenKeyEx.Call(
HKEY_LOCAL_MACHINE,REGKEY_PERF,0,KEY_READ,hKeyNames)
hKeyNames = hKeyNames.unpack(‘L’)[0]
dwSize = “\0”*4
rc = RegQueryValueEx.Call( hKeyNames,REGSUBKEY_COUNTERS,0,0,0,dwSize)
dwSize2 = dwSize.unpack(‘L’)[0]
buf = “\0” * dwSize2
rc = RegQueryValueEx.Call( hKeyNames,REGSUBKEY_COUNTERS,0,0,buf,dwSize)
buf2 = Hash[*buf.split(“\0”)]
proidx = buf2.index(“Process”).to_i
pididx = buf2.index(“ID Process”).to_i
ppididx = buf2.index(“Creating Process ID”).to_i
buf = “\0” * INITIAL_SIZE
szSubKey = proidx.to_s
dwSize = [INITIAL_SIZE]
while true
dwSize2 = dwSize.pack(‘L’)
rc = RegQueryValueEx.Call( HKEY_PERFORMANCE_DATA,szSubKey,0,0,buf,dwSize2)
break if rc==0
if rc == ERROR_MORE_DATA
dwSize[0] += EXTEND_SIZE;
buf = “\0” * dwSize[0]
else
exit
end
end
pObj = buf[buf[24,4].unpack(‘L’)[0] … -1]
pCounterDef = pObj[pObj[8,4].unpack(‘L’)[0] … -1]
numCounters = pObj[32,4].unpack(‘L’)[0]
for i in 0 … numCounters
counterNameTitleIndex = pCounterDef[4,4].unpack(‘L’)[0]
if counterNameTitleIndex == pididx
pidcounter = pCounterDef[36,4].unpack(‘L’)[0]
end
if counterNameTitleIndex == ppididx
ppidcounter = pCounterDef[36,4].unpack(‘L’)[0]
end
pCounterDef = pCounterDef[40…-1]
end
dwNumTasks = pObj[40,4].unpack(‘L’)[0]
pInst = pObj[pObj[4,4].unpack(‘L’)[0] … -1]
for i in 0 … dwNumTasks
pCounter = pInst[pInst[0,4].unpack(‘L’)[0] … -1]
pid = pCounter[pidcounter,4].unpack(‘L’)[0]
ppid = pCounter[ppidcounter,4].unpack(‘L’)[0]
if ppid>0
if result[ppid] == nil
result[ppid] = [pid]
else
result[ppid].push(pid)
end
end
pInst = pCounter[pCounter[0,4].unpack(‘L’)[0] … -1]
end
RegCloseKey.Call( hKeyNames )
RegCloseKey.Call( HKEY_PERFORMANCE_DATA )
result
end
puts 'Start: ’ + echo %TIME%
cmds = [
“ping 10.0.0.0 -n 30 -w 1000 >NUL”,
“ping 10.0.0.0 -n 60 -w 1000 >NUL”,
“ping 10.0.0.0 -n 90 -w 1000 >NUL”
]
out =
threads =
for c in cmds
threads << Thread.new(c) { |myCmd|
puts “#{myCmd}”
f = IO.popen(myCmd)
hProcess = OpenProcess.Call(0x00100001, 0 ,f.pid)
Thread.current[‘pid’] = f.pid
Thread.current[‘hProcess’] = hProcess
while true
a = WaitForSingleObject.Call( hProcess, 0 );
break if a==0
end
}
end
puts threads.length.to_s + ’ threads running’
begin
i = 0
threads.each { |t| i += 1 if t.stop? }
puts echo %TIME%
b = File.exists?(“C:junkj0.txt”)
puts i.to_s + ‘:’ + File.mtime(“C:junkj0.txt”).to_s if $DEBUG and b
$stdout.flush
end until (i == threads.length) || (not b)
pids = getpids
puts 'Mid: ’ + echo %TIME%
threads.each { |t|
if t.alive?
pids[t[‘pid’]].each {|pid|
TerminateProcess.Call(OpenProcess.Call(0x00100001, 0 ,pid),0) }
TerminateProcess.Call(t[‘hProcess’],0)
end
}
puts 'Stop: ’ + echo %TIME%
puts out if $DEBUG
#=================================================================
Park Heesob