Private Const sModule_Name As String = "ModRunDOSExecutable"
'The following is Code from Kris, a Software Engineer from Phoenix, AZ USA
'Additional code from Heulsa, Quebec/Canada
'Both came from Website: CodeGuru.com
'I have added my own changes so that it can be executed as a stand-alone function
'You would run code by calling the function like follows:
'RunDOSExecutable "c:\temp\Executable.bat", "c:\temp\Log.txt"
Option Explicit
'//public Constants
Public Const NORMAL_PRIORITY_CLASS = &H20&
Public Const INFINITE = -1&
'//public Types
Public 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
Public Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type
'//API Declarations
Public Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
hHandle As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function CreateProcessA Lib "kernel32" (ByVal _
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, lpProcessInformation As _
PROCESS_INFORMATION) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal _
hObject As Long) As Long
Private Const STARTF_USESHOWWINDOW = 1
Private Const SW_HIDE = 0
Public Function RunDOSExecutable(AppToRun As String, Optional ByVal Logfile As String)
' AppToRun is used for DOS executable name, which must be a full path to Bat or Exe file
' Logfile is used to capture the outcome of running the executable
' The "/C" tells Windows to Run The Command then Terminate
PROC_DECLARATIONS:
Const sProc_Name As String = "RunDOSExecutable"
Dim cmdline As String
PROC_START:
On Error GoTo PROC_ERROR
PROC_MAIN:
'//Build Command string
If Logfile = "" Then
Else: Logfile = " > " & Logfile
End If
cmdline = AppToRun & " /C" & Logfile
DoCmd.Hourglass True
'//Shell App And Wait for It to Finish
ExecCmd cmdline, True
DoCmd.Hourglass False
PROC_EXIT:
' Perform cleanup code here, set recordsets to nothing, etc.
On Error Resume Next
Exit Function
PROC_ERROR:
Select Case iErrorHandler(Err.Description, Err.Number, sProc_Name, sModule_Name)
Case iERROR_DEBUG
Stop
Resume
Case iERROR_RETRY
Resume
Case iERROR_IGNORE
Resume Next
Case iERROR_ABORT
Call CloseApplication
Case Else
MsgBox "Error: " & Err.Description
End Select
Resume PROC_EXIT
End Function
Public Function ExecCmd(ByVal cmdline As String, Optional ByVal HideWindow As Boolean = False) As Long
PROC_DECLARATIONS:
Const sProc_Name As String = "ExecCmd"
Dim Proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim ReturnValue As Integer
PROC_START:
On Error GoTo PROC_ERROR
PROC_MAIN:
If (HideWindow) Then
start.dwFlags = STARTF_USESHOWWINDOW
start.wShowWindow = SW_HIDE
End If
'//Initialize The STARTUPINFO Structure
start.cb = Len(start)
'//Start The Shelled Application
ReturnValue = CreateProcessA(0&, cmdline, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, start, Proc)
'//Wait for The Shelled Application to Finish
Do
ReturnValue = WaitForSingleObject(Proc.hProcess, 0)
DoEvents
Loop Until ReturnValue <> 258
'//Close Handle to Shelled Application
ReturnValue = CloseHandle(Proc.hProcess)
PROC_EXIT:
' Perform cleanup code here, set recordsets to nothing, etc.
On Error Resume Next
Exit Function
PROC_ERROR:
Select Case iErrorHandler(Err.Description, Err.Number, sProc_Name, sModule_Name)
Case iERROR_DEBUG
Stop
Resume
Case iERROR_RETRY
Resume
Case iERROR_IGNORE
Resume Next
Case iERROR_ABORT
Call CloseApplication
Case Else
MsgBox "Error: " & Err.Description
End Select
Resume PROC_EXIT
End Function