'Controlling Program Flow Between VB and C++

I have a program that runs from VB/Excel and executes a C++ program in the middle of it. I have two (I think related) questions:

  1. I capture the return value from the C++ program when it executes, but the number I get isn't zero (it's a 4-digit integer value instead, sample values I've received are 8156, 5844, 6100, 5528). I am certain the program exits normally with code 0, but I think VB is getting its value before the C++ program has completed its execution - would that explain why I am not getting a value of zero, and how I can get the final, correct return value from my C++ program?

  2. [Probably as a solution to #1] How can I make the VB program "pause" until the C++ model has completed its execution? I need to do some additional VB work (output configuration based on the C++ model run) once the model is complete

Here is my VB code for how the model call. I am running a full-compiled C++ program through the windows shell.

'---------------------------------------------------------
' SECTION III - RUN THE MODEL AS C++ EXECUTABLE
'---------------------------------------------------------
Dim ModelDirectoryPath As String
Dim ModelExecutableName As String
Dim ModelFullString As String
Dim ret As Long

ModelDirectoryPath = Range("ModelFilePath").value
ModelExecutableName = Range("ModelFileName").value
ModelFullString = ModelDirectoryPath & ModelExecutableName

' Call the model to run
Application.StatusBar = "Running C Model..."
ModelFullString = ModelFullString & " " & ScenarioCounter & " " & NumDeals _
              & " " & ModelRunTimeStamp
ret = Shell(ModelFullString)

' Add error checking based on return value
' This is where I want to do some checks on the return value and then start more VB code


Solution 1:[1]

1) You are capturing the Task ID of the program (this is what Shell() returns) not any return from the opened programme - that is why it is a 4 digit number

2) Shell() runs all programs asychronously.

To run a program synchronously or to run it and wait for the return, either:

Essentially, do something like:

Set o = CreateObject("WScript.Shell")
valueReturnedFromYourProgram = o.Run( _
                               strCommand:="notepad", _
                               intWindowStyle:=1, 
                               bWaitOnReturn:=true)
Debug.Print valueReturnedFromYourProgram

Solution 2:[2]

I'm not sure what the VBA code would be but have you checked out ShellExecuteEx? Below is the C/C++ code:

SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = "c:\\MyProgram.exe";        
ShExecInfo.lpParameters = "";   
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL; 
ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 markiemooster