How to determine when a shelled process has terminated
This article reprinted from the Microsoft Technical Support
Knowledge Base. To view
the article, maximize your help window. This information applies to
for Windows, versions 2.0 and 3.0.
Executing the shell function in a Visual Basic for Windows program,
asynchronously starts another executable program and returns control
back to the Visual Basic application. The shelled program continues
to run indefinitely until the user closes it, not when your Visual
Basic program terminates. However, your program can wait until the
shelled program has finished by polling the return value of the
Windows API function GetModuleUsage. This article describes the
method and provides a code example.
Using the Windows API function GetModuleUsage, your program can
monitor the status of a shelled process. The return value from Shell,
can be used to call GetModuleUsage continuously within a loop to poll
whether or not the shelled program has finished executing. If the
Shell function is successful, the return value is the instance
handle for the shelled program. This instance handle can be
passed to GetModuleUsage, to determine the reference count for the
module. When GetModuleUsage returns a value of 0 or less, the application
has finished its execution.
Regardless of the WindowStyle used to shell the program, this
algorithm works correctly. Additionally, this method does work under
the following situations:
- Shelling to Windows programs.
- Shelling to MS-DOS programs.
- Shelling to applications that do not display a window.
Below are the steps necessary to build a Visual Basic for Windows
program that uses the Shell function to execute the Windows Notepad
accessory. The program is an example of how to use the Windows API
function GetModuleUsage to wait until a shelled process has terminated
before resuming execution.
1. Run Visual Basic for Windows, or from the File menu, choose New
Project (ALT, F, N) if Visual Basic for Windows is already running.
Form1 is created by default.
2. Add the following code to the general Declarations section of
Declare Function GetModuleUsage% Lib "Kernel" (ByVal hModule%)
3. Add the following code to the Form_Click event procedure of Form1:
Sub Form_Click ()
x% = Shell("notepad.exe") ' Modify path as needed.
While GetModuleUsage(x%) > 0 ' Has Shelled program finished?
z% = DoEvents() ' If not, yield to Windows.
MsgBox "Shelled application just terminated", 64
4. From the Run menu, select Start (ALT, R, S) to run the program.
5. With the mouse click on Form1. The Notepad application is shelled.
The MsgBox statement following the Shell Function is not executed, as
it would normally would be without the While loop above it. The
message box does not appear until Notepad is closed by choosing Exit
from its File menu (ALT, F, X).