How to determine when a shelled process has terminated

See AlsoVMZ7S4


This article reprinted from the Microsoft Technical Support

Knowledge Base.  To view

the article, maximize your help window.  This information applies to

Visual Basic

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.


More Information:


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.


Code Example



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

   End Sub


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).