Here is what I use on a daily basis to do synchronous shelling. I see a few differences between this and how you're using it. You already covered why you're not using infinite. Then there's the false instead of 0, but a false is zero in vb so that should work too. You say you use the line:
WaitForSingleObject(nhandle, 0)
But you can't call a function in VB using the parenthesis without assigning the return value to something. I tried changing the line:
WaitForSingleObject phnd, INFINITE
In my code below to:
WaitForSingleObject(phnd, INFINITE)
And it's immeadiately flagged as an error "= expected" or something like that. I'm not saying that's your error but this code might help you. Just put it in a standard module and call SyncShell instead of Shell. That will remove any doubt about whether or not you are using the API calls directly. Also, if you try to run this script from a command line what happens?
Oh yeah, when the script 'freezes' what is in the title bar of the window it is running in? The reason i added the "command.com /c " to the command line is that without it any programs i shelled to on Win95 machines would hang. when i made the dos window visible i saw that in the title bar it said Finished, it just wasn't closing the window. the /c tells it to close the window when it's done.
Code:
Option Explicit
'-------- API calls declaration ---------
Public Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)
Public Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessID As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Public Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hProcess As Long, _
ByVal dwMilliseconds As Long) As Long
'---------------- global constants -------
Global Const INFINITE = &HFFFFFFFF
Global Const SYNCHRONIZED = &H100000
Public Sub SyncShell(ByVal sql As String, _
Optional ByVal vbwindowmode As VbAppWinStyle = vbMinimizedFocus)
Dim pid As Long
Dim phnd As Long
pid = Shell("command.com /c " & sql, vbwindowmode)
If pid <> 0 Then
phnd = OpenProcess(SYNCHRONIZED, 0, pid)
If phnd <> 0 Then
DoEvents
WaitForSingleObject phnd, INFINITE
CloseHandle phnd
DoEvents
End If
End If
End Sub
Ruairi
Could your manufacturing facility benefit from real time process monitoring? Would you like your employees to be able to see up to the minute goal and actual production?
For innovative, low cost solutions check out my website.