ShellExecuteEx in VBA

vba shellexecute wait for completion
vba shellexecute print
delphi shellexecute
shellexecute minimized
shellexecuteex runas
vba shellexecute sub or function not defined
vba execute
run shell commands in vba

I understand how to use ShellExecute in VBA (for my Outlook macros) but I'm looking to be able to use ShellExecuteEx to wait for the executed program in my script. Does anyone have an example of how to do this? Currently I have this code:

Const SW_SHOW = 1
Const SW_SHOWMAXIMIZED = 3

Public 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

'// Properties API
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 ShellExecuteEx _
    Lib "shell32.dll" ( _
        Prop As SHELLEXECUTEINFO) _
As Long

Public Function fnGetPropDlg(strFilepath As String) As Long
Dim Prop As SHELLEXECUTEINFO

With Prop
    .cbSize = Len(Prop)
    .fMask = &HC
    .Hwnd = 0&
    .lpVerb = "properties"
    .lpFile = strFilepath
End With

fnGetPropDlg = ShellExecuteEx(Prop)

End Function

and then my code calling the actual program (with ShellExecute):

RetVal = ShellExecute(0, "open", "C:\Documents and Settings\my\Desktop\zipTools.hta", "", "", SW_SHOWMAXIMIZED)

can anyone offer any help with switching this around so I can use ShellExecuteEx to wait for the closure of my HTA before my script execution continues?

Use CreateProcess() Windows API call instead.

For running a process and waiting until it finishes, use solution recommended by Microsoft which calls CreateProcessA(). Do not use ShellExecuteEx(). (You can also consider replacing your existing code.)

Reasons:

  1. It is recommended directly by manufacturer. There can be several reasons behind it including recent one:

  2. It is stable. ShellExecuteEx() is reported to throw exception after recent (2015) Windows updates when it is called from VBA.

In the answer to the above linked question, the code from Microsoft article is ready-to-use as separate VBA module.

Shell.ShellExecute method (Shldisp.h), This article describes how you can use the Windows SDK function ShellExecute from inside VBA to execute any program or short cut (.lnk) file. The ShellExecute function is not a VBA function so we need to declare it first telling it where it can be found (in SHELL32.DLL) and which parameters it takes. How. Start up your VBA enabled program, e.g. PowerPoint and go into the Tools | Macros menu and select the 'Visual Basic Editor' menu item (or click Alt+F11). This should open up the VBA editor.

Old question but here's a much simpler answer:

VBA Shell & Wait: the easy way!
Sub ShellAndWait(pathFile As String)
    With CreateObject("WScript.Shell")
        .Run pathFile, 1, True
    End With
End Sub

(You could even squish it to one line, but this is easier to read.)


Example Usage:
Sub demo_Wait()
    ShellAndWait ("notepad.exe")
    Beep 'this won't run until Notepad window is closed
    MsgBox "Done!"
End Sub

Adapted from (and more options at) Chip Pearson's site.

Using ShellExecute to start any program or short cut from inside VBA, This example needs the VBA declarations of the Windows API which can be found here. option explicit sub writeFile(filename as string) open filename for output as  As a final note, ShellExecute is a good example of a function that is being asked to perform too many different tasks. Internally these tasks may be related, but to the programmer executing a program, launching a search window, and exploring a folder are not closely related tasks.

If I am not mistaken, you need to set the

SEE_MASK_NOASYNC
bit in the fMask parameter.

Const SEE_MASK_NOASYNC As Long = &h0&
With Prop    
    .fMask = &HC Or SEE_MASK_NOASYNC
End With

Edit

Hmmm, I'm having trouble getting it to work too. Have you considered just GetFileInformationByHandle?

ShellExecute, ShellExecute Example. If you want to launch a document file of some sort, you can use VB/VBA's SHELL command, but that requires you to know the full path to​  This method is equivalent to launching one of the commands associated with a file's shortcut menu. Each command is represented by a verb string. The set of supported verbs varies from file to file. The most commonly supported verb is "open", which is also usually the default verb.

ShellExecute Example, ShellExecute is a Windows Application Programming Interface API function that is useful for starting other applications. Importantly, this function  Massive Data Parallelism on the GPU with Microsoft's C++ AMP (Accelerated Massive Parallelism) Latest articles. Android ListViews with Dynamic Data. Working with Mobile Devices in HTML5 and CSS3. Handling Page Orientation in Windows Phone 7. Microsoft Access. Latest articles. Building Your First Data Cube. To The Cloud: Moving Red Gate Tools to

Using the Windows Shell Execute API function, Re: ShellExecute or VBA.Shell? The ShellExecute function allows you to launch not just executable files, but also file types that have an  ShellExecuteEx() is reported to throw exception after recent (2015) Windows updates when it is called from VBA. In the answer to the above linked question, the code from Microsoft article is ready-to-use as separate VBA module .

[RESOLVED] ShellExecute or VBA.Shell?-VBForums, The ShellExecute API function takes these arguments: hWnd The window handle of the new program's parent. operation The operation to perform. file The name  The runas verb is undocumented but can be used to elevate permissions. When a script is run with elevated permissions several aspects of the user environment may change: The current directory, the current TEMP folder and any mapped drives will be disconnected. runas will fail if you are running in WOW64

Comments
  • so i've got shellexecuteex running with a string (absolute path) as an argument but how do i make my script wait until that program is finished before moving on? Public Function fnRunFileWait(strFilepath As String) As Long Dim Prop As SHELLEXECUTEINFO With Prop .cbSize = Len(Prop) .fMask = &HC .Hwnd = 0& .lpVerb = "open" .lpFile = strFilepath End With fnRunFileWait = ShellExecuteEx(Prop) End Function
  • i added the constant to the parameter you specified and it still continues code execution in my script. now out of curiosity (and possibly my ignorance), is this supposed to wait until the program is simply executed or does it wait for the executed program to close?
  • It was my understanding it would wait for the program to close.