Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using Shell to execute a program

Status
Not open for further replies.

CFB

Programmer
Jan 11, 2001
74
US
I'm executing a program using a Shell command:
Shell("c:\myprogram.exe")
I need to wait until "myprogram.exe" finishes running before proceeding with the rest of my application. Does anyone know how to make your VB app wait for the Shell command to return from executing the application you ran?

MSDN says:
"Note: By default, the Shell function runs other programs asynchronously. This means that a program started with Shell might not finish executing before the statements following the Shell function are executed."

Is there a way to change this default setting? Or does anyone know another way to execute a program other than using a Shell command? Thanks for the help.
 
Using the process handle of the shelled application, call the WaitForSingleObject API. - Jeff Marler B-)
 
Try this,
Code:
'==== bas module - declarations section ========
Option Explicit

Private Declare Function OpenProcess Lib "kernel32" _
       (ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Long, _
        ByVal dwProcessId As Long) As Long
Private Declare Function WaitForInputIdle Lib "user32" _
       (ByVal hProcess As Long, _
        ByVal dwMilliseconds As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" _
        (ByVal hHandle As Long, _
         ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
         (ByVal hObject As Long) As Long

Private Const INFINITE = &HFFFF
Private Const SYNCHRONIZE = &H100000

'==== bas modue - code section ====
Public Sub ShellAndWait(sAppPath As String, _
          Optional iWindowStyle As VbAppWinStyle = _
          vbMinimizedFocus, _
    Optional  lmsTimeOut As Long = INFINITE)
    'Optional argument lmsTimeOut specifies milliseconds to wait.
   'Wait forever if omitted (default).
    Dim lPid As Long, hProc As Long, lTimeOut As Long

    lPid = Shell(sAppPath, iWindowStyle)
    hProc = OpenProcess(SYNCHRONIZE, 0&, lPid)
    If hProc <> 0& Then
        WaitForInputIdle hProc, INFINITE
        WaitForSingleObject hProc, lmsTimeOut
        CloseHandle hProc
    End If
End Sub
 
So, do I place this at the top of the code window and then call it from my other sub?

So....

Public Sub Example()

sAppPath = CommandLine

pkz = &quot;c:\winnt\system32\pkzip.exe&quot;
n = &quot;c:\test.zip&quot;
o = &quot;c:\test1.txt c:\test2.txt&quot;
CommandLine = pkz & &quot; &quot; & n & &quot; &quot; & o

p = Shell(CommandLine)

End Sub

Is this right then? Sory, I'm pretty new to all of this...

Thank you
 
Ok great, that helped a lot. I haven't used the OpenProcess function before and had one question about the piece of code that was posted:
&quot;hProc = OpenProcess(SYNCHRONIZE, 0&, lPid)
If hProc <> 0& Then&quot;

MSDN says:
&quot;HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance flag
DWORD dwProcessId // process identifier&quot;

The bInheritHandle parameter, '0&', which we passed is supposed to be a boolean value. hProc is supposed to be a handle returned by the OpenProcess function. I guess I just don't understand how a boolean value could or could not equal an open handle. Other than not understanding that part, the code looks like it's going to work great. Thanks again for all the help.

 
The bInheritHandle parameter accepts a value of Type BOOL which is not exactly the same as the VB type Boolean. Remember that when you come right down to it, everything on the computer is just numbers . . . therefore, keeping that in mind, False = 0 and 1 = True in BOOL . . . of course in VB's Boolean, False = 0 and -1 = True. There is a reason for this difference, but it starts to get involved . . . if you really want to know, ask me and I'll post it . . . other wise, just remember that you are simply using the numeric equivalents of the BOOL types for the API call. - Jeff Marler B-)
 
Ok, this has been a great help. One last question. Is it possible to pass a parameter to a program I am executing with a Shell command? In Visual FoxPro it's possible to execute a program using a MS-DOS Command. This allows me to pass parameters to programs I need to execute from within my application. Will the Shell function still work or do I need to take a different approach? Thanks again.
 
Pass the variable as a command line parameter . . . then use the VB Command function to get the command line parameters passed into the application. - Jeff Marler B-)
 
Ok, I did some reading about the Command() function, but can't seem to understand how it is going to work. I need to execute a non VB application from within my VB application and I need to pass that non VB application parameters. I may be wrong (which is likely the case), but how I understand the Command() function is that it will return what parameters I need to pass to a VB exe I'm executing. I already know the parameters I need to pass to the non VB application I'm executing, I just don't know how to do it. Sorry for the ignorance and thanks again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top