VBA 中的 ShellExecuteEx

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1374433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 10:45:19  来源:igfitidea点击:

ShellExecuteEx in VBA

vbashellexecuteoutlook-vba

提问by thepip3r

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:

我了解如何在 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

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

然后我的代码调用实际程序(使用 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?

任何人都可以提供任何帮助来解决这个问题,以便我可以在脚本执行继续之前使用 ShellExecuteEx 等待 HTA 关闭?

回答by miroxlav

Use CreateProcess()Windows API call instead.

请改用CreateProcess()Windows API 调用。

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

要运行进程并等待它完成,请使用Microsoft 推荐的解决方案,解决方案调用CreateProcessA(). 不要使用ShellExecuteEx(). (您也可以考虑替换现有代码。)

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 updateswhen it is called from VBA.

  1. 它是由制造商直接推荐的。其背后可能有多种原因,包括最近的一个:

  2. 它是稳定的。ShellExecuteEx()据报道,当从 VBA 调用它时,在最近(2015 年)Windows 更新后抛出异常

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

在对上述链接问题的回答中,Microsoft 文章中的代码可以作为单独的 VBA 模块随时使用

回答by ashleedawg

Old question but here's a muchsimpler answer:

老问题,但这里有一个简单的答案:

VBA Shell & Wait: the easy way!

VBA Shell & Wait:简单的方法!

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.

改编自(以及更多选项)Chip Pearson 的网站

回答by Oorang

If I am not mistaken, you need to set the

如果我没记错的话,你需要设置

SEE_MASK_NOASYNC
fMask 参数中的位。

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?

嗯,我也很难让它工作。您是否只考虑过 GetFileInformationByHandle?