问题
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?
回答1:
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:
It is recommended directly by manufacturer. There can be several reasons behind it including recent one:
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.
回答2:
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.
回答3:
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?
来源:https://stackoverflow.com/questions/1374433/shellexecuteex-in-vba