Microsoft KB Archive/102019
WD: Shell Command Doesn't Wait for Application to Finish
The information in this article applies to:
- Microsoft Word for Windows, versions 2.0, 2.0a, 2.0a-CD, 2.0b, 2.0c, 6.0, 6.0a, 6.0c
- Microsoft Word for Windows, versions 7.0, 7.0a
When you use the Shell command to run another program from a WordBasic macro, Word does not wait for the shelled program to finish running before it processes the rest of the macro.
WordBasic macro processing is considered "asynchronous." This means that macro commands are executed independently of any timing process, such as a clock. Macros do not wait for a shelled program to finish before executing the next command. This can cause problems in your macro, particularly if the subsequent commands rely on processing performed by the shelled program.
WARNING: ANY USE BY YOU OF THE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this macro code "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.
Word versions 7.0, 7.0a
When you use Word 7.x with Windows 95 or Windows NT, the following macro will test to see if an application is still running and won't continue on until the test application has finished running:
Sub MAIN test = AppIsRunning("app string") While test = - 1 test = AppIsRunning("app string") Wend MsgBox "app has quit" End Sub
Word versions 2.0, 6.0
The following WordBasic user-defined function, WaitShell(), uses the Windows function GetModuleUsage() to determine if the shelled application has terminated. If the WinExec() function is successful in starting the program, it returns a module handle which identifies the instance of the loaded application. When the application is no longer running, the module handle will be invalid and GetModuleUsage() will return a value of 0. WaitShell() loops until the module handle is invalid, at which point the remaining macro commands are executed.
Declare Function WinExec Lib "kernel"(lpszCmdLine$, fuCmdShow As \ Integer) As Integer Declare Sub Yield Lib "kernel"() Declare Function GetModuleUsage Lib "kernel"(hInst As Integer) As \ Integer Sub MAIN WaitShell("MYPROG.EXE") MsgBox "Done." End Sub Sub WaitShell(szAppToRun$) hInst = WinExec(szAppToRun$, 1) While GetModuleUsage(hInst) > 0 Yield 'Waiting Wend End Sub Declare Function GetModuleUsage Lib "Kernel"(hModule As Integer) \ As Integer Declare Function WinExec Lib "kernel"(lpszCmdLine$, fuCmdShow As \ Integer) As Integer Declare Sub WaitMessage Lib "User"() Sub MAIN WaitShell("MYPROG.EXE") 'MYPROG.EXE is any program to run MsgBox "Done." End Sub Sub WaitShell(szAppToRun$) hMod = WinExec(szAppToRun$, 1) If(hMod > 32) Then While(GetModuleUsage(hMod)) WaitMessage() Wend Else MsgBox "Unable to start the Application" End If End Sub
"Microsoft Windows Programmer's Reference," volume 2: Functions, pages 404, 979, and 983
Kbcategory: kbusage kbmacro
Additional query words: 2.0 2.0a-cd winword 7.0 word95 word7 word6 winword2 yield doevents pause
Keywords : kbmacro kbmacroexample
Issue type :
Last Reviewed: November 4, 2000