Option Explicit
Option Base 0
'Code written by JoshT. Use at your own risk
Private Declare Function CreateProcess _
Lib "kernel32" _
Alias "CreateProcessA" (ByVal lpApplicationName As String, _
ByVal lpCommandLine As String, _
lpProcessAttributes
As SECURITY_ATTRIBUTES, _
lpThreadAttributes
As SECURITY_ATTRIBUTES, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
lpEnvironment
As Any, _
ByVal lpCurrentDirectory As String, _
lpStartupInfo
As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function
CloseHandle _
Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function
ReadFile _
Lib "kernel32" (ByVal hFile As Long, _
lpBuffer
As Any, _
ByVal nNumberOfBytesToRead As Long, _
lpNumberOfBytesRead
As Long, _
lpOverlapped
As Long) As Long
Private Declare Function
WaitForSingleObject _
Lib "kernel32" (ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
Private Declare Function
CreatePipe _
Lib "kernel32" (phReadPipe As Long, _
phWritePipe
As Long, _
lpPipeAttributes
As SECURITY_ATTRIBUTES, _
ByVal nSize As Long) As Long
Private
Type STARTUPINFO
cb
As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End
Type
Private Type PROCESS_INFORMATION
hProcess
As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End
Type
Private Type SECURITY_ATTRIBUTES
nLength
As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End
Type
Private Const NORMAL_PRIORITY_CLASS As Long = &H20&
Private Const STARTF_USESTDHANDLES As Long = &H100&
Private Const STARTF_USESHOWWINDOW As Long = &H1&
Private Const SW_HIDE As Long = 0&
>Private Const INFINITE As Long = &HFFFF&
Public Function RunCommand(CommandLine As String) As String
Dim
si As STARTUPINFO 'used to send info the CreateProcess
Dim pi As PROCESS_INFORMATION 'used to receive info about the created process
Dim retval As Long 'return value
Dim hRead As Long 'the handle to the read end of the pipe
Dim hWrite As Long 'the handle to the write end of the pipe
Dim sBuffer(0 To 63) As Byte 'the buffer to store data as we read it from the pipe
Dim lgSize As Long 'returned number of bytes read by readfile
Dim sa As SECURITY_ATTRIBUTES
Dim strResult As String 'returned results of the command line

'set up security attributes structure
100 With sa
102 .nLength = Len(sa)
104 .bInheritHandle = 1& 'inherit, needed for this to work
106 .lpSecurityDescriptor = 0&
End With

'create our anonymous pipe an check for success
' note we use the default buffer size
' this could cause problems if the process tries to write more than this buffer size
108 retval = CreatePipe(hRead, hWrite, sa, 0&)

110 If retval = 0 Then
112 Debug.Print "CreatePipe Failed"
114 RunCommand = ""
Exit Function
End If

'set up startup info
116 With si
118 .cb = Len(si)
120 .dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW 'tell it to use (not ignore) the values below
122 .wShowWindow = SW_HIDE
' .hStdInput = GetStdHandle(STD_INPUT_HANDLE)
124 .hStdOutput = hWrite 'pass the write end of the pipe as the processes standard output
' .hStdError = GetStdHandle(STD_ERROR_HANDLE)
End With

'run the command line and check for success
126 retval = CreateProcess(vbNullString, CommandLine & vbNullChar, sa, sa, 1&, _
NORMAL_PRIORITY_CLASS,
ByVal 0&, vbNullString, si, pi)

128 If retval Then
'wait until the command line finishes
' trouble if the app doesn't end, or waits for user input, etc
130 WaitForSingleObject pi.hProcess, INFINITE

'read from the pipe until there's no more (bytes actually read is less than what we told it to)
132 Do While ReadFile(hRead, sBuffer(0), 64, lgSize, ByVal 0&)
'convert byte array to string and append to our result
134 strResult = strResult & StrConv(sBuffer(), vbUnicode)
'TODO = what's in the tail end of the byte array when lgSize is less than 64???
136 Erase sBuffer()

138 If lgSize <> 64 Then Exit Do
Loop

'close the handles of the process
140 CloseHandle pi.hProcess
142 CloseHandle pi.hThread
Else
144 Debug.Print "CreateProcess Failed" & vbCrLf
End If

'close pipe handles
146 CloseHandle hRead
148 CloseHandle hWrite
'return the command line output
150 RunCommand = Replace(strResult, vbNullChar, "")
End Function


 
目前有0条回应
Comment
Trackback
你目前的身份是游客,请输入昵称和电邮!