Shelling a document and waiting for it to be closed befor proceeding

I am shelling a document and want to wait until it has been closed before shelling the next one
How do i identify if the shelled doc is still open????????

'#################################################################
Option Explicit
#If Win32 Then

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Private Declare Function GetDesktopWindow Lib "user32" () As Long
#Else

Declare Function ShellExecute Lib "SHELL" (ByVal hwnd%, ByVal lpszOp$, ByVal lpszFile$, ByVal lpszParams$, ByVal lpszDir$, ByVal fsShowCmd%) As Integer

Declare Function GetDesktopWindow Lib "USER" () As Integer
#End If

Private Const SW_SHOWNORMAL = 1

Public Function StartNewDoc(ByVal DocName As String) As Long
Dim Scr_hDC As Long

   Scr_hDC = GetDesktopWindow()
   StartNewDoc = ShellExecute(Scr_hDC, "Open", DocName, vbNullString, "C:\", SW_SHOWNORMAL)

End Function
'############################################################
turloughmAsked:
Who is Participating?
 
WimConnect With a Mentor Commented:
You can use this (works fine for me) :


'this goes in general declarations:

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 String, 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 String, _
    lpStartupInfo As STARTUPINFO, lpProcessInformation As _
    PROCESS_INFORMATION) As Long

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

Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const INFINITE = -1&

Public Function ExecCmd(cmdline$)
    Dim proc As PROCESS_INFORMATION
    Dim start As STARTUPINFO
    Dim ret&

    ' Initialize the STARTUPINFO structure:
    start.cb = Len(start)
   
    ' Start the shelled application:
    ret& = CreateProcessA(vbNullString, cmdline$, 0&, 0&, 1&, _
    NORMAL_PRIORITY_CLASS, 0&, vbNullString, start, proc)
   
    ' Wait for the shelled application to finish:
    ret& = WaitForSingleObject(proc.hProcess, INFINITE)
    Call GetExitCodeProcess(proc.hProcess, ret&)
    Call CloseHandle(proc.hThread)
    Call CloseHandle(proc.hProcess)
    ExecCmd = ret&
End Function

'Where you want to run your shell app:
ExecCmd "your_commandline"

Greetz,
Wim
0
 
bruintjeCommented:
Hello turloughm,

you could look at this article which puts out a shell and wait for it to return
http://www.mvps.org/access/api/api0004.htm

hope this helps a bit
bruintje
0
 
turloughmAuthor Commented:
Hi
Thanks for your comment but my code above works for shelling the doc.
StartNewDoc function works fine. But how do i know when the shelled documents application is closed?

T
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
bruintjeCommented:
you cant use the Shell only if you really want to use ShellExecute though i recommend the code in my first comment
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=1102&lngWId=-1
0
 
bruintjeCommented:
@Wim that uses the same API calls as this http://www.mvps.org/access/api/api0004.htm
0
 
nffvrxqgrcfqvvcCommented:
If you have interface displayed . such as a form, you want to pound some messages to your application so it can respond to other events while waiting for event to be signaled. here my example/



'--------------- Module1.bas ------------------

Option Explicit

Private Const SEE_MASK_NOCLOSEPROCESS = &H40
Private Const SEE_MASK_INVOKEIDLIST = &HC
Private Const SEE_MASK_FLAG_NO_UI = &H400

Private Const WAIT_OBJECT_0& = 0
Private Const INFINITE = &HFFFF

Private Const QS_HOTKEY& = &H80
Private Const QS_KEY& = &H1
Private Const QS_MOUSEBUTTON& = &H4
Private Const QS_MOUSEMOVE& = &H2
Private Const QS_PAINT& = &H20
Private Const QS_POSTMESSAGE& = &H8
Private Const QS_SENDMESSAGE& = &H40
Private Const QS_TIMER& = &H10
Private Const QS_MOUSE& = (QS_MOUSEMOVE _
                            Or QS_MOUSEBUTTON)
Private Const QS_INPUT& = (QS_MOUSE _
                            Or QS_KEY)
Private Const QS_ALLEVENTS& = (QS_INPUT _
                            Or QS_POSTMESSAGE _
                            Or QS_TIMER _
                            Or QS_PAINT _
                            Or QS_HOTKEY)

Private Const QS_ALLINPUT& = (QS_SENDMESSAGE _
                            Or QS_PAINT _
                            Or QS_TIMER _
                            Or QS_POSTMESSAGE _
                            Or QS_MOUSEBUTTON _
                            Or QS_MOUSEMOVE _
                            Or QS_HOTKEY _
                            Or QS_KEY)

Private Const SW_NORMAL = 1

Private Type SHELLEXECUTEINFO
        cbSize As Long
        fMask As Long
        hwnd As Long
        lpVerb As String
        lpFile As String
        lpParameters As String
        lpDirectory As String
        nShow As Long
        hInstApp As Long
        lpIDList As Long
        lpClass As String
        hkeyClass As Long
        dwHotKey As Long
        hIcon As Long
        hProcess As Long
End Type

Private Declare Function MsgWaitForMultipleObjects Lib "user32" ( _
    ByVal nCount As Long, _
    pHandles As Long, _
    ByVal fWaitAll As Long, _
    ByVal dwMilliseconds As Long, _
    ByVal dwWakeMask As Long) As Long
   
Private Declare Function ShellExecuteEx Lib "shell32.dll" (SEI As SHELLEXECUTEINFO) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Public Sub ShellWait(ByVal hwnd As Long, ByVal ProgramPath As String)

Dim SEI As SHELLEXECUTEINFO
Dim lBusy As Long

With SEI
    .cbSize = Len(SEI)
    .fMask = SEE_MASK_NOCLOSEPROCESS
    .lpFile = ProgramPath
    .lpVerb = "open"
    .nShow = SW_NORMAL
    .lpDirectory = Left(ProgramPath, (InStrRev(ProgramPath, "\")) - 1)
    .hwnd = hwnd
End With

ShellExecuteEx SEI

Do
    lBusy = MsgWaitForMultipleObjects(1, SEI.hProcess, False, INFINITE, QS_ALLINPUT&)
        DoEvents
Loop Until lBusy = WAIT_OBJECT_0&

CloseHandle SEI.hProcess
End Sub


'----------------- Form1 ------------------

Private Sub Command1_Click()

ShellWait Me.hwnd, "C:\windows\system32\calc.exe"
    MsgBox "Application closed"
   
End Sub
0
 
turloughmAuthor Commented:
De_Wim99
Your code works well - One thing though , I know the file name so need to identify the program which is hooked to the files extension - how do i identify the program to shell ?

filename = C:\a.txt
Progam hooked = %SystemRoot%\system32\notepad.exe

cmdline$ =  "%SystemRoot%\system32\notepad.exe C:\a.txt"
ExecCmd(cmdline$)

0
 
nffvrxqgrcfqvvcCommented:
shellexecute can open the file directly for my example
0
 
WimCommented:
I only use this to run bat-files ...

I don't know why, but notepad doesn't work ?!

But with wordpad it works:

ExecCmd Environ("SYSTEMROOT") & "\system32\write.exe C:\a.txt"    '%systemroot% doesn't work

Wim
0
 
turloughmAuthor Commented:
sorry - I should have explained my question better
How do I know what program is used to open  C:\a.txt
0
 
WimCommented:
you can use a test before opening:

select case lcase(right(yourfilename,3))
    case "txt"
         varApplication = "Environ("SYSTEMROOT") & "\system32\write.exe"
   case "doc"
         varApplication = "your path to word"
   case "xls"
         varApplication = "your path to excel"
   case ....                'all the files you want to open
   case else
        msgbox "Unknow Application"
end select

ExecCmd varApplication & " " & yourfilename

Wim
0
 
visualbasicCommented:
But If I dont know the path of the application then I must get it from the registery!
How this done on the fly?
0
 
WimCommented:
I will look in to it, but i's maybe better to open a new question for this.

Wim
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.