VBA中的ShellExecuteEx

时间:2009-09-03 16:16:48

标签: vba shellexecute outlook-vba

我理解如何在VBA中使用ShellExecute(对于我的Outlook宏),但我希望能够使用ShellExecuteEx在我的脚本中等待执行的程序。有没有人有如何做到这一点的例子?目前我有这段代码:

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

然后我的代码调用实际程序(使用ShellExecute):

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

任何人都可以提供任何帮助来切换这个,所以我可以使用ShellExecuteEx等待我的HTA关闭,然后我的脚本继续执行吗?

3 个答案:

答案 0 :(得分:3)

改为使用CreateProcess() Windows API调用。

要运行流程并等待其完成,请使用调用CreateProcessA()的{​​{3}}。不要使用ShellExecuteEx()。 (您也可以考虑替换现有代码。)

原因:

  1. 建议由制造商直接推荐。其背后可能有几个原因,包括最近的原因:

  2. 稳定。从VBA调用时solution recommended by Microsoft

  3. 在回答上述链接问题时,Microsoft文章中的代码为ShellExecuteEx() is reported to throw exception after recent (2015) Windows updates

答案 1 :(得分:1)

老问题,但这是一个很多更简单的答案:

VBA Shell&Wait:简单方法!

Sub ShellAndWait(pathFile As String)
    With CreateObject("WScript.Shell")
        .Run pathFile, 1, True
    End With
End Sub

(您甚至可以将其压缩到一行,但这更易于阅读。)


用法示例:

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

改编自Chip Pearson's site(以及更多选项)。

答案 2 :(得分:0)

如果我没弄错的话,你需要在fMask参数中设置

SEE_MASK_NOASYNC
位。

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

修改

嗯,我也无法让它上​​班。你有没有考虑过GetFileInformationByHandle?