wnv.asp
this is working – but frequently Segfaults ruby 1.6.6 mswin32
spawn = Win32API.new(“crtdll”, “_spawnvp”, [‘I’, ‘P’, ‘P’] ,‘L’)
need to try the third param as an ‘L’ and pass it 0, maybe segfault
will go away?
res = spawn.Call(P_NOWAIT, command, ‘’)
if res == -1
Win32API.new(“crtdll”, “perror”, [‘P’], ‘V’).call(‘async_system’)
end
res
end
from WinBase.h in SDK
dwCreationFlag values
NORMAL_PRIORITY_CLASS = 0x00000020
STARTUP_INFO_SIZE = 68
PROCESS_INFO_SIZE = 16
def create_process(command)
from WinBase.h in SDK
Passing nil for a pointer – I’ve seen it work with a P type param and
an empty string … here L with a 0 is the only way that works with
CreateProcess. (see FormatMessage in raise_last_win32_error for an
example of ‘P’ and ‘’ that works)
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
processInfo
end
ERROR_SUCCESS = 0x00
FORMAT_MESSAGE_FROM_SYSTEM = 0x1000
FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x2000
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
All this code is BSD license - full code is part of a misc windows utility
unit you can find here: