I have this piece of code.
ShellExecute Me.hwnd, vbNullString, "c:\mybat.bat", _
vbNullString, "C:\", SW_SHOWNORMAL
I want this to loop until it has ended.
Any ideas ?
Printable View
I have this piece of code.
ShellExecute Me.hwnd, vbNullString, "c:\mybat.bat", _
vbNullString, "C:\", SW_SHOWNORMAL
I want this to loop until it has ended.
Any ideas ?
hmmm...I think you need to shell the application and wait till it has finished. I've used some code before to do that and it works pretty fine without any noticeably memory leaks.
Try this:
VB Code:
Option Explicit 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 Declare Function WaitForSingleObject Lib "kernel32" (ByVal _ hHandle As Long, ByVal dwMilliseconds As Long) As Long 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 TerminateProcess Lib "kernel32" (ByVal hProcess As Long, _ ByVal uExitCode 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 Declare Function CloseHandle Lib "kernel32" _ (ByVal hObject As Long) As Long Private Declare Function GetExitCodeProcess Lib "kernel32" _ (ByVal hProcess As Long, lpExitCode As Long) As Long Private Const STARTF_USESTDHANDLES As Long = &H100& Private Const STARTF_USESHOWWINDOW As Long = &H1& Private Const SW_HIDE As Long = 0& Private Const SW_SHOWNORMAL = 1 Private Const SW_SHOWMINIMIZED = 2 Private Const SW_SHOWMAXIMIZED = 3 Private Const SW_SHOWNOACTIVATE = 4 Private Const SW_SHOW = 5 Private Const SW_MINIMIZE = 6 Private Const SW_SHOWMINNOACTIVE = 7 Private Const SW_SHOWNA = 8 Private Const SW_RESTORE = 9 Private Const WAIT_ABANDONED = &H80 Private Const WAIT_FAILED = &HFFFFFFFF Private Const WAIT_OBJECT_O = &H0 Private Const WAIT_TIMEOUT = &H102 Private Const NORMAL_PRIORITY_CLASS = &H20 Private Const INFINITE = -1& Private Sub RunCommand(ByVal lcStrCommandLine As String) Dim ProcInfo As PROCESS_INFORMATION Dim startinfo As STARTUPINFO Dim lcLngRetVal As Long Dim retval As Long Dim SA As SECURITY_ATTRIBUTES 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 lcStrErrPrefix As String Dim lcStrErrMsg As String On Error GoTo ErrHandler 'set up security attributes structure With SA .nLength = Len(SA) .bInheritHandle = 1& 'inherit, needed for this to work .lpSecurityDescriptor = 0& End With 'create our anonymous pipe an check for success retval = CreatePipe(hRead, hWrite, SA, 0&) If retval = 0 Then Debug.Print "CreatePipe Failed" Exit Sub End If ' Initialize the STARTUPINFO structure: With startinfo .cb = Len(startinfo) .dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW .wShowWindow = SW_HIDE .hStdOutput = hWrite .wShowWindow = SW_HIDE End With ' Start the shelled application: lcLngRetVal = CreateProcess(vbNullString, Chr(34) & lcStrCommandLine & Chr(34), SA, SA, 1&, _ NORMAL_PRIORITY_CLASS, 0&, vbNullString, startinfo, ProcInfo) If lcLngRetVal = 0 Then lcStrErrMsg = "Could not execute the DOS command: " & lcStrCommandLine Debug.Print lcStrErrMsg Exit Sub End If ' Wait for the shelled application to finish: If WaitForSingleObject(ProcInfo.hProcess, INFINITE) <> WAIT_OBJECT_O Then TerminateProcess ProcInfo.hProcess, 0 TerminateProcess ProcInfo.hThread, 0 End If Call CloseHandle(ProcInfo.hProcess) Call CloseHandle(ProcInfo.hThread) Debug.Print "Process Terminated" Exit Sub ErrHandler: Debug.Print Err.Description End Sub
usage:
VB Code:
call RunCommand "c:\mybat.bat"