Try this out: I have tested it on Win2K and Win XP (Pro)
using ruby 1.6.8 (2002-12-24) [i586-mswin32]
Does more than what you asked for …
require ‘Win32API’
STDOUT.sync = true
NORMAL_PRIORITY_CLASS = 0x00000020
STARTUP_INFO_SIZE = 68
PROCESS_INFO_SIZE = 16
ERROR_SUCCESS = 0x00
FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000
PROCESSENTRY32_SIZE = 296
def process_running?(pid,ppid = -1)
params = [ ‘L’, # IN DWORD dwFlags
’L’ # IN DWORD th32ProcessID
]
retVal = ‘L’ # HANDLE
getProcessSnapShot = Win32API.new(“kernel32”, “CreateToolhelp32Snapshot”, params, retVal)
hProcess = getProcessSnapShot.call(8,0)
params = [ ‘L’, # hSnapshot [in] Handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.
‘P’ # lppe [in, out] Pointer to a PROCESSENTRY32 structure
]
retVal = ‘I’ # BOOL
Dim hSnapshot As Long, uProcess As PROCESSENTRY32
uProcess.dwSize = Len(uProcess)
uProcess = [PROCESSENTRY32_SIZE].pack(‘I’) + ([0].pack(‘I’) * (PROCESSENTRY32_SIZE - 4))
getProcessFirst = Win32API.new(“kernel32”, “Process32First”, params, retVal)
getProcessNext = Win32API.new(“kernel32”, “Process32Next”, params, retVal)
r = getProcessFirst.call(hProcess,uProcess)
found = false
while (r != 0)
puts r
gotPid = uProcess.th32ProcessID
gotPpid = uProcess.th32ParentProcessID
(found = true; break) if (gotPid == pid) and ((ppid >= 0) ? (ppid == gotPpid) : true)
r = getProcessNext.call(hProcess,uProcess)
end
return found
end
def raise_last_win_32_error
errorCode = Win32API.new(“kernel32”, “GetLastError”, [], ‘L’).call
if errorCode != ERROR_SUCCESS
params = [
‘L’, # IN DWORD dwFlags,
‘P’, # IN LPCVOID lpSource,
‘L’, # IN DWORD dwMessageId,
‘L’, # IN DWORD dwLanguageId,
‘P’, # OUT LPSTR lpBuffer,
‘L’, # IN DWORD nSize,
‘P’, # IN va_list *Arguments
]
formatMessage = Win32API.new("kernel32", "FormatMessage", params, 'L')
msg = ' ' * 255
msgLength = formatMessage.call(FORMAT_MESSAGE_FROM_SYSTEM +
FORMAT_MESSAGE_ARGUMENT_ARRAY, '', errorCode, 0, msg, 255, '')
msg.gsub!(/\000/, '')
msg.strip!
raise msg
else
raise 'GetLastError returned ERROR_SUCCESS’
end
end
def create_process(command,redirStdout="", redirStderr="")
if redirStdout.length > 0
tmpfile = File.new(redirStdout,“w”)
save_stdout = $stdout.clone
$stdout.reopen(tmpfile)
end
if redirStderr.length > 0
tmpfile = File.new(redirStderr,“w”)
save_stderr = $stderr.clone
$stderr.reopen(tmpfile)
end
params = [
‘L’, # IN LPCSTR lpApplicationName
’P’, # IN LPSTR lpCommandLine
’L’, # IN LPSECURITY_ATTRIBUTES lpProcessAttributes
’L’, # IN LPSECURITY_ATTRIBUTES lpThreadAttributes
’L’, # IN BOOL bInheritHandles
’L’, # IN DWORD dwCreationFlags
’L’, # IN LPVOID lpEnvironment
’L’, # IN LPCSTR lpCurrentDirectory
’P’, # IN LPSTARTUPINFOA lpStartupInfo
’P’ # OUT LPPROCESS_INFORMATION lpProcessInformation
]
returnValue = ‘I’ # BOOL
startupInfo = [STARTUP_INFO_SIZE].pack(‘I’) + ([0].pack(‘I’) * (STARTUP_INFO_SIZE - 4))
processInfo = [0].pack(‘I’) * PROCESS_INFO_SIZE
createProcess = Win32API.new(“kernel32”, “CreateProcess”, params, returnValue)
if createProcess.call(0, command, 0, 0, 0, NORMAL_PRIORITY_CLASS, 0, 0, startupInfo, processInfo) == 0
raise_last_win_32_error
end
if redirStdout.length > 0
$stdout.reopen(save_stdout)
end
save_stdout.close if save_stdout
if redirStderr.length > 0
$stderr.reopen(save_stderr)
end
save_stderr.close if save_stderr
($0 == FILE ) ? processInfo : processInfo.unpack(“LLLL”)[2]
end
if $0 == FILE
begin
cmd = 'ping -n 15 localhost’
pi = create_process(cmd,"",“C:\stderr.txt”)
p pi.unpack(“LLLL”) #if $DEBUG
hProcess = pi.unpack("LLLL")[0]
hThread = pi.unpack("LLLL")[1]
dwProcessId = pi.unpack("LLLL")[2]
puts dwProcessId
dwThreadId = pi.unpack("LLLL")[3]
puts process_running?(4)
# Now kill the process
kill = false
if kill
sleep(10)
OpenProcess = Win32API.new("kernel32","OpenProcess",['L','L','L'],'L')
TerminateProcess = Win32API.new("kernel32","TerminateProcess",['L','L'],'L')
TerminateProcess.Call(OpenProcess.Call(0x00100001, 0 ,dwProcessId),0)
else
sleep(20)
end
rescue RuntimeError => err
puts 'Aborting: ’ + err
end
end
“LeRoy, Brian D.” brian.leroy@cendant.com wrote in message news:B307D1E87003D511A89700B0D0B0326A0116A201@CIS-DUBLIN-EX1…
I’ve been struggling to get the CreateProcess Win32API call to run. I get this error:
998 Invalid access to memory location. ERROR_NOACCESS
I’ve since attempted CreateProcessWithLogon, but this call expects a clear text password which is not so nice. Any help is greatly appreciated!
Brian LeRoy