[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

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

Posted on 2006-05-03
13
Medium Priority
?
237 Views
Last Modified: 2010-04-07
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
'############################################################
0
Comment
Question by:turloughm
  • 4
  • 3
  • 3
  • +2
13 Comments
 
LVL 44

Expert Comment

by:bruintje
ID: 16595121
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
 

Author Comment

by:turloughm
ID: 16595233
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
 
LVL 44

Expert Comment

by:bruintje
ID: 16595261
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 4

Accepted Solution

by:
Wim earned 500 total points
ID: 16595550
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
 
LVL 44

Expert Comment

by:bruintje
ID: 16595602
@Wim that uses the same API calls as this http://www.mvps.org/access/api/api0004.htm
0
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 16595746
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
 

Author Comment

by:turloughm
ID: 16596052
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
 
LVL 29

Expert Comment

by:nffvrxqgrcfqvvc
ID: 16596598
shellexecute can open the file directly for my example
0
 
LVL 4

Expert Comment

by:Wim
ID: 16596951
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
 

Author Comment

by:turloughm
ID: 16598123
sorry - I should have explained my question better
How do I know what program is used to open  C:\a.txt
0
 
LVL 4

Expert Comment

by:Wim
ID: 16598596
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
 

Expert Comment

by:visualbasic
ID: 16603907
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
 
LVL 4

Expert Comment

by:Wim
ID: 16606939
I will look in to it, but i's maybe better to open a new question for this.

Wim
0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
I was working on a PowerPoint add-in the other day and a client asked me "can you implement a feature which processes a chart when it's pasted into a slide from another deck?". It got me wondering how to hook into built-in ribbon events in Office.
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Suggested Courses

834 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question