Tutorial :VBA Shell and Wait with Exit Code



Question:

I am wrapping up an office application (VBA) that makes a call to a C# console application to perform some of the heavy lifting for the application (large simulation program). I would like to be able to have the VBA application wait for the console application to complete as well as retreive the exit code from the console application. I have been able to do the former, but have yet to be able to retrieve the exit code from the application. Is there any way that I can use something like

Diagnostics.Process.Start(filePath)  

I have seen this in VB but not sure about VBA. Otherwise, any other suggestions?


Solution:1

Have a look at WaitForSingleObject and GetExitCodeProcess functions.

Example Usage:

Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long  Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long  Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long  Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long  Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long    Public Const INFINITE = &HFFFF  Public Const PROCESS_ALL_ACCESS = &H1F0FFF    Sub RunApplication(ByVal Cmd as String)        lTaskID = Shell(Cmd, vbNormalFocus)      //Get process handle      lPID = OpenProcess(PROCESS_ALL_ACCESS, True, lTaskID)      If lPID Then          //Wait for process to finish          Call WaitForSingleObject(lPID, INFINITE)          //Get Exit Process          If GetExitCodeProcess(lPID, lExitCode) Then              //Received value              MsgBox "Successfully returned " & lExitCode, vbInformation          Else              MsgBox "Failed: " & DLLErrorText(Err.LastDllError), vbCritical          End If      Else          MsgBox "Failed: " & DLLErrorText(Err.LastDllError), vbCritical      End If      lTaskID = CloseHandle(lPID)  End Sub    Public Function DLLErrorText(ByVal lLastDLLError As Long) As String      Dim sBuff As String * 256      Dim lCount As Long      Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100, FORMAT_MESSAGE_ARGUMENT_ARRAY = &H2000      Const FORMAT_MESSAGE_FROM_HMODULE = &H800, FORMAT_MESSAGE_FROM_STRING = &H400      Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000, FORMAT_MESSAGE_IGNORE_INSERTS = &H200      Const FORMAT_MESSAGE_MAX_WIDTH_MASK = &HFF        lCount = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0, lLastDLLError, 0&, sBuff, Len(sBuff), ByVal 0)      If lCount Then          DLLErrorText = Left$(sBuff, lCount - 2) \\Remove line feeds      End If    End Function  


Solution:2

This functionality has been wrapped up in the ShellAndWait function.

Excellent write up on it here.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »