Results 1 to 33 of 33

Thread: [Resolved] ShellExcecute - wait

  1. #1

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429

    [Resolved] ShellExcecute - wait

    Good Morning (Night) all,

    I want to set the mouse to 'HourGlass' until ShellExcecute has
    loaded the appropriate app and file, then I want to set the mouse back to 'Default' (I know the sytax etc for the mouse).

    So, what I'm after is the Return, from that API call, to determine the app has loaded. - I guess something similar to SendKeys [wait]

    VB Code:
    1. ShellExecute Me.hwnd, vbNullString, sPathName, vbNullString, "C:\", SW_SHOWNORMAL


    Regards,
    Bruce.
    Last edited by Bruce Fox; Nov 14th, 2002 at 07:11 PM.

  2. #2
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Here's a ShellWait that I use sometimes for similiar situations...
    VB Code:
    1. Private Type STARTUPINFO
    2.     cb As Long
    3.     lpReserved As String
    4.     lpDesktop As String
    5.     lpTitle As String
    6.     dwX As Long
    7.     dwY As Long
    8.     dwXSize As Long
    9.     dwYSize As Long
    10.     dwXCountChars As Long
    11.     dwYCountChars As Long
    12.     dwFillAttribute As Long
    13.     dwFlags As Long
    14.     wShowWindow As Integer
    15.     cbReserved2 As Integer
    16.     lpReserved2 As Long
    17.     hStdInput As Long
    18.     hStdOutput As Long
    19.     hStdError As Long
    20. End Type
    21. Private Type PROCESS_INFORMATION
    22.     hProcess As Long
    23.     hThread As Long
    24.     dwProcessID As Long
    25.     dwThreadID As Long
    26. End Type
    27.  
    28. Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _
    29.     hHandle As Long, ByVal dwMilliseconds As Long) As Long
    30.  
    31. Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
    32.     lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _
    33.     lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _
    34.     ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
    35.     ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
    36.     lpStartupInfo As STARTUPINFO, lpProcessInformation As _
    37.     PROCESS_INFORMATION) As Long
    38.  
    39. Private Declare Function CloseHandle Lib "kernel32" (ByVal _
    40.     hObject As Long) As Long
    41.  
    42. Public Function ShellWait(Pathname As String, Optional WindowStyle As Long)
    43.     Dim proc As PROCESS_INFORMATION
    44.     Dim start As STARTUPINFO
    45.     Dim ret As Long
    46.     ' Initialize the STARTUPINFO structure:
    47.     With start
    48.         .cb = Len(start)
    49.         If Not IsMissing(WindowStyle) Then
    50.             .dwFlags = &H1
    51.             .wShowWindow = WindowStyle
    52.         End If
    53.     End With
    54.     ' Start the shelled application:
    55.     ret& = CreateProcessA(0&, Pathname, 0&, 0&, 1&, _
    56.             &H20&, 0&, 0&, start, proc)
    57.     ' Wait for the shelled application to finish:
    58.     ret& = WaitForSingleObject(proc.hProcess, -1&)
    59.     ret& = CloseHandle(proc.hProcess)
    60. End Function
    Hope it helps
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  3. #3

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Thanks for the reply technitaes,

    I was hoping for something less intense


    Cheers,
    Bruce.

  4. #4
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    That's the standard way to do a 'shell and wait', it's in MSDN this way.

    ShellExecute and ShellExecuteEx don't allow you to wait on process termination of the shelled process.

  5. #5

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Thanks Jim,

    I kinda figured that'd be the case, I'm just plugging it into a Module now


    Regards,
    Bruce.

  6. #6
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Well, the thing about it is you can copy and past this into a module, save it as something like "modShellWait.bas", copy it to a back up directory, then copy it into any programs you write in the future that need the functionality, and all you need to do at that point is call the public function ...
    VB Code:
    1. MousePointer = vbHourglass
    2. ShellWait "C:\SomeDir\SomeFile.bat"
    3. MousePointer = vbDefault
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  7. #7

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Yep, thats what I've done

    Thanks again for your time. Just testing it now.


    Bruce.

  8. #8

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Hmmmm,

    Dosn't seem to be working.

    I can hear the CD run up (thats where the source file is), however,
    there never is an instance of the associated app!


    I have steped thru the API to no avail


    I'm using:
    VB Code:
    1. Call modStartApp.ShellWait(sPathName)


    Running on Windows 2000
    Last edited by Bruce Fox; Nov 11th, 2002 at 05:07 PM.

  9. #9
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Hmmm...

    What OS are you running? I haven't tested it on any machines beyond 98SE/ME. I think we're running an app that's using it on an NT box, but I'd have to double check to be sure.

    As you can tell, we're a little behind in updating our machines. The new bells and whistles haven't appeared cost effective as of yet.
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  10. #10

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Win 2000 (in an Access 2000 db VBA).

  11. #11
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Well, it could be the Win2k or it could be the Access db. I've only run it in VB6 apps on the afore mentioned OS's.

    Wait...
    I remember my boss having a little trouble with an app he was using this in. He's out today, but I can check with him tomorrow and see if he remembers what it was and how he fixed it. Just so I'll know for reference, is the app you calling a Windows GUI program, some kind of batch file/dos file, or something else?
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  12. #12

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    The files range from .txt, pdf, .jpg's etc.

    I have the file (path) and FileName listed in a Recorset, the user
    can dblClick on the FileName and have the file open with its associated
    application. (The ShellExcecute worked well, however, I was
    adding the Hourgalss as a user prompt etc as previously discussed).

    Thanks again technitaes.



    Bruce.

  13. #13
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    There shouldn't be any problems running the code on Win2k. The problem is the following part of the code:
    VB Code:
    1. If Not IsMissing(WindowStyle) Then
    2.             .dwFlags = &H1
    3.             .wShowWindow = WindowStyle
    4.         End If
    Since WindowStyle is declared as an optional Long argument it is never missing. The IsMissing can only be used with Variants. If you don't pass a value to WindowStyle the default value will be 0 which is the same as vbHide. So the code is executing the shelled app but the window is hidden. Try using this call instead:
    VB Code:
    1. Call modStartApp.ShellWait(sPathName, vbNormalFocus)
    But as I have understood your original question you just want to show the hourglass while the shelled application is loading. This code will stop the execution of your application until the shelled application is closed.

    Best regards

  14. #14

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Ahhh...

    Thanks Joacim, Correct - I don't want to wait till the opened app is closed....


    (For what its worth, I had set the WindowStyle to no avail)

    To re-ittereate I need the Hourglass just for the duration the
    (associated) app is loading.


    Regards to All Con

  15. #15

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    *Thought* Can I ShellExcecute, capture the Hwnd and then use
    an API to monitor the Hwnd till it's loaded (checking in a Do-Loop).


    Bruce.

  16. #16

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Ideas?

  17. #17

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    *Fummp*

  18. #18
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Bruce,

    Sorry I misunderstood exactly what you were trying to accomplish. You can use your loop idea though, to check for the loading of another program by using the FindWindow API.

    VB Code:
    1. 'Module General Declarations
    2. Declare Function FindWindow Lib "User" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Integer
    3. 'Same Module
    4. Public Function ApplicationLoaded(ByVal Title As String) As Boolean
    5.   Dim intWindowHandle As Integer
    6.  
    7.   intWindowHandle = FindWindow(0&, Title)
    8.   ApplicationLoaded = (intWindowHandle <> 0)
    9. End Function
    10. '
    11. 'Some Form ...
    12. MousePointer = vbHourglass
    13. Shell "Notepad.exe"
    14. Do While Not ApplicationLoaded("Untitled - NotePad")
    15.   Me.Refresh
    16. Loop
    17. MousePointer = vbDefault
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  19. #19

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    technitaes,

    Thanks again for your response.

    That was the approach I've been playing with. However, I must use
    ShellExcecute as I'm not sure what the app will be.

    Having said that, I can't use that method with that ApplicationLoaded API.

    So, I'm stuck now trying to incorporate an API that can give me that hwnd of the ShellExec app, and loop until that has loaded.

    Again, appreciate your help

    Bruce.

  20. #20

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    ideas, thoughts?

  21. #21
    Frenzied Member Shawn N's Avatar
    Join Date
    Dec 2001
    Location
    Houston
    Posts
    1,631
    How exactly can you tell when a program is done loading?

    I'm assuming that it's different app everytime so you can't wait for the splash screen since not all will definetley have one.
    Please rate my post.

  22. #22
    Hyperactive Member vbud's Avatar
    Join Date
    Jan 2002
    Location
    Mru 20 17S, 57 33E Goal: Get out of the BOX Status: In The Shadows!!! Target Posts: 3,000,000,000
    Posts
    378

    Cool

    hmmm...see this thread, try the code I mentionned and tell me how it goes...

    http://www.vbforums.com/showthread.p...47#post1258647
    >!v!<
    Free your mind, stop thinking
    http://inspirone.blogspot.com

    Please rate this post if it helped you

  23. #23

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Thanks Vbud, But that too looks like it waits till the (opened) app closes...

    Regards,
    Bruce.

  24. #24
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Hey Bruce,

    I just had a thought. If you're Shelling these files out to a normal window, the new app should take system focus away from you program. You might simply try setting the MousePointer to an hourglass before the shell call, then use the Form_LostFocus event to return the MousePointer to default.

    You'd need to test it out a fair bit, and probably put in some safety checks (like turning the hourglass off when a certain control is clicked or when a function key [F5?] is pressed or something). It might just do the trick though and you could forget worrying about all the API business.

    Just a thought...
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  25. #25
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    Originally posted by technitaes
    I just had a thought. If you're Shelling these files out to a normal window, the new app should take system focus away from you program. You might simply try setting the MousePointer to an hourglass before the shell call, then use the Form_LostFocus event to return the MousePointer to default.
    Pretty good idea, except that VB doesn't raise the Form_LostFocus event when another application gets focus

  26. #26
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Originally posted by Joacim Andersson
    Pretty good idea, except that VB doesn't raise the Form_LostFocus event when another application gets focus
    Ahh Yes, Joacim Andersson. What a bummer... VB doesn't quite do what you'd expect it to all the time now does it!

    So OK. Bruce, this has just about got me fed up! I hate it when I know something MUST be possible, but I just can't seem to solve it. So try this...
    VB Code:
    1. 'In a modules General Declarations...
    2. Public Declare Function GetActiveWindow Lib "user32" () As Long
    3. Public Declare Function ShellExecute Lib "shell32.dll" Alias _
    4. "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As _
    5. String, ByVal lpFile As String, ByVal lpParameters As String, _
    6. ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    7.  
    8. 'In the click/dblclick event you're writing...
    9.     Dim lhWnd As Long
    10.    
    11.     lhWnd = GetActiveWindow()    'Should be the same as Me.hWnd
    12.     MousePointer = vbHourglass
    13.     ShellExecute Me.hWnd, vbNullString, sFileName, vbNullString, sDefDir, vbNormalFocus
    14.     Do While lhWnd = GetActiveWindow()
    15.         DoEvents
    16.     Loop
    17.     MousePointer = vbDefault
    Since the first call to GetActiveWindow() actually returns the same value as Me.hWnd, you could forego the lhWnd variable and shorten the code to ...
    VB Code:
    1. 'in the click/dblclick event...
    2.     MousePointer = vbHourglass
    3.     ShellExecute Me.hWnd, vbNullString, sFileName, vbNullString, sDefDir, vbNormalFocus
    4.     Do While Me.hWnd = GetActiveWindow()
    5.         DoEvents
    6.     Loop
    7.     MousePointer = vbDefault
    Disclaimer, if the user selects another application while waiting on the shelled program to load then the Hourglass will return to default. Likewise if the program associated with the file has a splash screen, as soon as it appears (and thus becomes the active window) then the Hourglass will return to default.

    I've actually tested this!

    Hope it helps!
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  27. #27

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Legendary


    Thanks technitaes for ALL your efforts, much appreciated.

    This is the winning combination - Inital testing going well..
    VB Code:
    1. Screen.MousePointer = vbHourglass
    2.     ShellExecute Me.hWnd, vbNullString, sFileName, vbNullString, sDefDir, vbNormalFocus
    3.     Do While Me.hWnd = GetActiveWindow()
    4.         DoEvents
    5.     Loop
    6.   Screen.MousePointer = vbDefault


    Regards,
    Bruce.

  28. #28
    Guru Aaron Young's Avatar
    Join Date
    Jun 1999
    Location
    Red Wing, MN, USA
    Posts
    2,177
    You could utilize the WaitForInputIdle() API, i.e.
    VB Code:
    1. Option Explicit
    2.  
    3. Private Type SHELLEXECUTEINFO
    4.   cbSize As Long
    5.   fMask As Long
    6.   hwnd As Long
    7.   lpVerb As String
    8.   lpFile As String
    9.   lpParameters As String
    10.   lpDirectory As String
    11.   nShow As Long
    12.   hInstApp As Long
    13.   lpIDList As Long
    14.   lpClass As String
    15.   hkeyClass As Long
    16.   dwHotKey As Long
    17.   hIcon As Long
    18.   hProcess As Long
    19. End Type
    20.  
    21. Private Declare Function ShellExecuteEx Lib "shell32.dll" (lpExecInfo As SHELLEXECUTEINFO) As Long
    22. Private Declare Function WaitForInputIdle Lib "user32" (ByVal hProcess As Long, ByVal dwMilliseconds As Long) As Long
    23.  
    24. Private Const SEE_MASK_NOCLOSEPROCESS = &H40
    25.  
    26. Public Sub ShellWait(ByVal sFile As String)
    27.   Dim tSEI As SHELLEXECUTEINFO
    28.   Dim lResult As Long
    29.      
    30.   With tSEI
    31.     .fMask = SEE_MASK_NOCLOSEPROCESS
    32.     .lpFile = sFile
    33.     .lpVerb = "OPEN"
    34.     .nShow = 1
    35.     .cbSize = Len(tSEI)
    36.   End With
    37.   ' Launch the File in with it's associated application (if applicable.)
    38.   Call ShellExecuteEx(tSEI)
    39.  
    40.   ' Wait for the application to Idle (Finish Loading.)
    41.   Do
    42.     lResult = WaitForInputIdle(tSEI.hProcess, 10)
    43.     DoEvents
    44.   Loop While lResult <> 0
    45. End Sub

  29. #29

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Thanks Aaron,

    Looks like a few ideas are begining to surface now

    I was surprised that I had difficulty finding (via Search) similar posts.



    Regards,
    Bruce.

  30. #30

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Feedback.

    Not too sure if this is working as expected

    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
    4. (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
    5. ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
    6.  
    7. Private Declare Function GetActiveWindow Lib "user32" () As Long
    8.  
    9. Const SW_SHOWNORMAL = 1
    10.  
    11. Private Sub Command0_Click()
    12.  
    13. Debug.Print Me.hwnd & vbTab & GetActiveWindow()
    14.  
    15.         ShellExecute Me.hwnd, vbNullString, "D:\COSYS RMN.jpg", vbNullString, "C:\", vbMinimizedNoFocus 'SW_SHOWNORMAL
    16.  
    17. Debug.Print Me.hwnd & vbTab & GetActiveWindow()
    18.        
    19.         Do While Me.hwnd = GetActiveWindow()
    20.  
    21. Debug.Print Me.hwnd & vbTab & GetActiveWindow()
    22.             DoEvents
    23.        
    24.         Loop
    25.  
    26. End Sub

  31. #31

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    Aaron,

    That example seems to work well.

    technitaes: GetActiveWindow() never seems to be the same
    as the Me.Hwnd? (Hence, bypassing the Do.. While)


    Again, Thanks guys.
    Bruce.

  32. #32
    Lively Member technitaes's Avatar
    Join Date
    Oct 2002
    Location
    Tennessee, USA
    Posts
    112
    Bruce,
    Sorry it didn't seem to work for you. I tried out both of the pieces of code I posted, and it worked every time (used a call to an .exe, .txt, .htm, and .gif all of which obviously use different programs to load). Not sure what the difference might have been.

    Aaron,
    Sweet! Glad someone was able to come up with a solution that would work for Bruce.
    tecnithV -- artisan, artificer, workman, mechanic, architect, or builder
    VB6, ASP, HTML, XML, Oracle, Access, MySql, PHP, C++, Etc...
    To format your VB code in this forum use tags like this [vbcode]your code here[/vbcode]

  33. #33

    Thread Starter
    INXSIVE Bruce Fox's Avatar
    Join Date
    Sep 2001
    Location
    Melbourne, Australia
    Posts
    7,429
    technitaes,

    In an app like Access, with sub forms etc, you need to use Application.hWndAccessApp instead of Me.Hwnd!

    That was the problem...

    It now works well



    So, many thanks for your time.

    It looks like we now have two methods to acheive this goal!


    Thanks again,

    Regards,
    Bruce.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width