Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Shell Complete Flag?

0 views
Skip to first unread message

Phil Field

unread,
May 31, 2001, 4:43:36 PM5/31/01
to
The shell function is asynchronous, that is, my vb code keeps on running before
the shelled program loads. I am opening the IE browser to a specific web site
and want to use SendKeys to populate the default text boxes on that site.
Currently, I use a loop to delay my vb code from going on until the web site is
loaded before using the SendKeys.

There must be some way of finding out when the browser has completed loading
AND the specific web page has finished loading. Does anyone have an idea?

Thanks,

Phil

Rick Rothstein

unread,
May 31, 2001, 11:56:32 PM5/31/01
to
MICROSOFT'S OFFICIAL WAY
========================
See this link

http://support.microsoft.com/support/kb/articles/Q129/7/96.asp

Note: This method doesn't use Shell -- it uses CreateProcessA


FAST AND DIRTY METHOD (WORKS ALMOST ALL THE TIME)
=================================================
Paste these lines in the (General)(Declarations) section of the form where the Shell is
being called (or remove the Private keywords and put them in a BAS module if more than one
form will use them):

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

Call your Shell command in this form with the appropriate Shell arguments placed in the
parentheses:

PID = Shell( <<Put Shell Arguments Here>> )

And finally, paste the following IMMEDIATELY after the PID=Shell statement above (making
sure to handle the possible error where indicated; i.e. stop the code from falling through
to your other commands if the Shell failed):

If PID = 0 Then
'
'Handle Error, Shell Didn't Work
'
Else
hProcess = OpenProcess(&H100000, True, PID)
WaitForSingleObject hProcess, -1
CloseHandle hProcess
End If

One note -- there are some NT systems (those with VERY tight security measures in place)
where this call won't work. No problem at all on 95/98 though.

Rick

"Phil Field" <phf...@home.com> wrote in message
news:Y1yR6.2685$Cb.1...@dfiatx1-snr1.gtei.net...

Phil Field

unread,
Jun 1, 2001, 9:56:20 AM6/1/01
to
Thanks so much, Rick, for your prompt and very helpful reply. That's exactly
what I needed!

In article <3b171...@news4.newsfeeds.com>, rick_ne...@email.com says...

Phil Field

unread,
Jun 1, 2001, 11:08:59 AM6/1/01
to
On second thought, although this fix will be very helpful, it only tells me
when the application has FINISHED. I need to know when the application has
completed LOADING so I can use SendKeys to populate textboxes on the web site.
Is this unrealistic? Is there a way to know that the application (in this
case the IE brower) has completed loading and is ready to accept keystrokes?

Thanks for your help and patience.

Randy Birch

unread,
Jun 1, 2001, 12:52:19 PM6/1/01
to
Try using WaitForInputIdle ... not positive if it will work with a shell
app, but worth a try. The second param in WaitForInputIdle is the
milliseconds to wait. You can specify a large number, such as 10000 to wait
10 seconds for the app to respond, or set it to INFINITE, which will suspend
your app until the process has started. If it never starts, using this flag,
you app will hang requiring a three-finger salute.

Option Explicit

Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadID As Long
End Type

Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const HIGH_PRIORITY_CLASS = &H80
Private Const REALTIME_PRIORITY_CLASS = &H100
Private Const INFINITE = -1&
Private Const STARTF_USESHOWWINDOW = &H1
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_SHOWNORMAL = 1
Private Const SW_SHOWNOACTIVATE = 4


Private Declare Function CreateProcess Lib "kernel32" _
Alias "CreateProcessA" _
(ByVal lpApplicationName As Long, _
ByVal lpCommandLine As String, _
ByVal lpProcessAttributes As Long, _
ByVal lpThreadAttributes As Long, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, _
ByVal lpCurrentDirectory As Any, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION) As Long

Private Declare Function CloseHandle Lib "kernel32" _


(ByVal hObject As Long) As Long

Private Declare Function WaitForInputIdle Lib "user32" _
(ByVal hProcess As Long, _


ByVal dwMilliseconds As Long) As Long

Private Declare Function GetCurrentProcess Lib "kernel32" () As Long


Private Sub Command1_Click()

Dim appname As String
Dim params As String

appname = Chr$(34) & "C:\Office\msaccess.exe" & Chr$(34)
params = Chr$(34) & "C:\Documents\some.mdb" & Chr$(34)

If CreateRemoteApplication(appname & " " & params) <> 0 Then
MsgBox "App is ready"
Else
MsgBox "No luck. If the app started and hung, and you specified
INFINTE, you won't see this"
End If

End Sub


Private Function CreateRemoteApplication(cmdline As String) As Long

Dim proc As PROCESS_INFORMATION
Dim start As STARTUPINFO
Dim hwndMyApp As Long
Dim visMyApp As Long
Dim startupDir As String

'set the command line and starting directory
startupDir = App.Path

'initialize the STARTUPINFO
With start
.cb = Len(start)
.dwFlags = STARTF_USESHOWWINDOW
.wShowWindow = SW_SHOWMAXIMIZED
End With


'start the app using CreateProcess
If CreateProcess(0&, _
cmdline, _
ByVal 0&, _
ByVal 0&, _
0&, _
NORMAL_PRIORITY_CLASS, _
ByVal 0&, _
ByVal startupDir, _
start, _
proc) Then

'the process was started, so wait
'for it's initialization to complete
Call WaitForInputIdle(proc.hProcess, INFINITE)

'return the process ID as sign of success
CreateRemoteApplication = GetCurrentProcess()

End If

End Function


--

Randy Birch
MVP Visual Basic

http://www.mvps.org/vbnet/

Please respond only to the newsgroups so all can benefit.

"Rick Rothstein" <rick_ne...@email.com> wrote in message
news:3b171...@news4.newsfeeds.com...
: MICROSOFT'S OFFICIAL WAY

: >
:


0 new messages