We help IT Professionals succeed at work.

shellexecute halts/stalls

ChirsJB
ChirsJB asked
on
I'm currently writting a program to launch a few windows and tile and size them in particular parts of the window.  This program seem to work with 99% of the apps that I tested it on but there is one app, the one I need that is causing me problems.  It's called FalconView. Below is the code clip:

hw& = GetDesktopWindow
STATUS = ShellExecute(hw&, "Open", APP_ASSOC,
                       vbNull,vbnull, 1)
IS_RUNNING = vbFalse
THE_TIME = DateAdd("s", 30, Time)
Do While IS_RUNNING = vbFalse
  hw& = FindWindow(vbNullString, APP_TEXT)
  If hw& > 0 Then IS_RUNNING = vbTrue
  If THE_TIME < Time Then IS_RUNNING = vbTrue
Loop

Here is the problem...the program starts by the association, but it seems to stall during the timeout.  The timeout completes and does not find the window.  After the timeout times out then the app finishes launching.  I don't know why the app is stalling in mid launch.  The timeout is needed so that the app can launch and then window handle can be found.  

The question is why is why is the app stalling and how can I get around it or fix it?
Comment
Watch Question

Commented:
what OS are you writing on ?

I personally would use CreateProcess to start the program

DarrinE

Commented:
It's better to use the CreateProcess API:

======================

' G. Choquette, Enron Corp, copyright 1998
' module to execute another program (windows or dos)
' and make that program retain total focus until completion
' uses Win32 API calls and therefore will not work on win 3.x

Public Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer
As String, ByVal nSize As Long) As Long

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 Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
     hHandle As Long, ByVal dwMilliseconds As Long) As Long


Private Declare Function CreateProcessA Lib "kernel32" (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 Long, _
     lpStartupInfo As STARTUPINFO, lpProcessInformation As _
     PROCESS_INFORMATION) As Long

Private Declare Function CloseHandle Lib "kernel32" (ByVal _
     hObject As Long) As Long


Private Proc As PROCESS_INFORMATION
Private Start As STARTUPINFO
Private Ret As Long

Private Const NORMAL_PRIORITY_CLASS = &H20
Private Const HIGH_PRIORITY_CLASS = &H80
Private Const INFINITE = -1&

Public Sub ExecuteAndWait(CmdLine As String)
 ' Initialize the STARTUPINFO structure:
 Start.cb = Len(Start)

 ' Start the shelled application:
 Ret = CreateProcessA(0&, CmdLine, 0&, 0&, 1&, _
    NORMAL_PRIORITY_CLASS, 0&, 0&, Start, Proc)
 DoEvents
 ' Wait for the shelled application to finish:
 Ret = WaitForSingleObject(Proc.hProcess, INFINITE)  'time in milliseconds
 DoEvents
 Ret = CloseHandle(Proc.hProcess)
 DoEvents
 Ret = CloseHandle(Proc.hThread)
 DoEvents
End Sub


'Execute your shell like:

ExecuteAndWait "\yourpathhere\Notepad.exe"

'the main thread of execution will halt until the shelled application is finished.

======================
From this question, answered by YourBuddyToo:
http://www.experts-exchange.com/jsp/qShow.jsp?ta=visualbasic&qid=20096820

It works great!

D'Mzzl!
RoverM

Author

Commented:
The way the app works is that it will not launch if you try to run it's exe....some how they have it locked down.  I was able to conferm this when I called the manufacture.  That is the reason that I am launching through an associated file.  I created an empty text file with an extention associated with the program and that seems to work.  Oh..I'm it's being written on win98 and win2000. VB6 SP5.  The funny part is that when I step through the program it works fine.  I think that the process is not releaseing before moving onto the next part of the program, the timer loop.
Ark
BRONZE EXPERT

Commented:
May be simply add DoEvents inside Loop?

Author

Commented:
Ark,  I'm not sure what you meen.  Can you be more specific?
Chris
BRONZE EXPERT
Commented:
Hi
Your code:
'======================
STATUS = ShellExecute(hw&, "Open", APP_ASSOC, vbNull, vbNull, 1)
Do While IS_RUNNING = vbFalse
 hw& = FindWindow(vbNullString, APP_TEXT)
 If hw& > 0 Then IS_RUNNING = vbTrue
 If THE_TIME < Time Then IS_RUNNING = vbTrue
Loop
'======================
ie, you start app and begin 'in-thread' loop. Some applications may wait for system idle or some mouse/keyboard evnts or smth else - your loop don't allow this. Just add:
Do While IS_RUNNING = vbFalse
   DoEvents
............
Loop

Cheers

Explore More ContentExplore courses, solutions, and other research materials related to this topic.