'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:
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?
[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:
Use a Windows API function (I refer you to https://stackoverflow.com/a/5686052/1101846 for a list of options / API calls you could use)
Much more easily, use the WshShell object provided by Windows Scripting Host (see https://stackoverflow.com/a/8906912/1101846 for more examples than what I give below). See Microsoft documentation of the Run method at http://msdn.microsoft.com/en-us/library/d5fk67ky
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 |