Gustav Brock
gustav at cactus.dk
Fri May 7 07:23:33 CDT 2004
Hi Mark
> The different versions of ShellWait utilize the API call CreateProcessA
> instead of ShellExecuteA. I can't seem to get CreateProcessA to open
> anything...yet no errors are returned. Is CreateProcessA like ShellExecuteA
> in that as long as I pass a valid path/filename with a registered extension,
> it will automagically do its thing? ...because it isn't:(
It's hard to tell why it fails without knowing more.
But here's another approach - I can't remember where I got it:
<code>
Option Compare Database
Option Explicit
Private Const SYNCHRONIZE = &H100000
' Wait forever.
Private Const INFINITE = &HFFFF
' The state of the specified object is signaled.
Private Const WAIT_OBJECT_0 = 0
' The time-out interval elapsed and the objects state is nonsignaled.
Private Const WAIT_TIMEOUT = &H102
Private Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId 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
' The WaitForSingleObject function returns when one of the following occurs:
' - The specified object is in the signaled state.
' - The time-out interval elapses.
'
' The dwMilliseconds parameter specifies the time-out interval, in milliseconds.
' The function returns if the interval elapses, even if the objects state is
' nonsignaled. If dwMilliseconds is zero, the function tests the objects state
' and returns immediately. If dwMilliseconds is INFINITE, the functions time-out
' interval never elapses.
'
' This example waits an INFINITE amount of time for the process to end. As a
' result this process will be frozen until the shelled process terminates. The
' down side is that if the shelled process hangs, so will this one.
'
' A better approach is to wait a specific amount of time. Once the time-out
' interval expires, test the return value. If it is WAIT_TIMEOUT, the process
' is still not signaled. Then you can either wait again or continue with your
' processing.
'
' DOS Applications:
' Waiting for a DOS application is tricky because the DOS window never goes
' away when the application is done. To get around this, prefix the app that
' you are shelling to with "command.com /c".
'
' For example: lngPid = Shell("command.com /c " & strCommand.Text, vbNormalFocus)
Function ShellWait( _
ByVal strCommand As String) _
As Boolean
Dim lngPid As Long
Dim lngHnd As Long
Dim lngReturn As Long
Dim booSuccess As Boolean
If Len(Trim$(strCommand)) > 0 Then
lngPid = Shell(strCommand, vbNormalFocus)
If lngPid <> 0 Then
' Get a handle to the shelled process.
lngHnd = OpenProcess(SYNCHRONIZE, 0, lngPid)
' If successful, wait for the application to end and close the handle.
If lngHnd <> 0 Then
lngReturn = WaitForSingleObject(lngHnd, INFINITE)
CloseHandle (lngHnd)
booSuccess = True
End If
MsgBox "Just terminated.", vbInformation, "Shelled Application"
End If
End If
ShellWait = booSuccess
End Function
</code>
Beware of line breaks.
/gustav