VBA 中的 ShellExecuteEx

发布于 2024-08-03 07:44:13 字数 1614 浏览 3 评论 0原文

我了解如何在 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 关闭吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

榆西 2024-08-10 07:44:13

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

VBA Shell &等等:简单的方法!

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 网站

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.

看春风乍起 2024-08-10 07:44:13

请改用 CreateProcess() Windows API 调用。

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

原因:

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

  2. 它很稳定。 ShellExecuteEx() 据报告在最近 (2015) Windows 更新后调用时会抛出异常来自VBA。

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

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.

余生共白头 2024-08-10 07:44:13

如果我没记错的话,您需要设置 < /a>

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

编辑

嗯,我也无法让它工作。您是否考虑过 GetFileInformationByHandle?

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?

丿*梦醉红颜 2024-08-10 07:44:13

事实上,上面的建议

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

很简单并且有效!

值 1 指定显示窗口,0 为默认值。 True 值指定等待完成;错误立即返回。

pathFile 遵循在批处理文件中使用的正常构造规则 - 如果需要,请将程序路径和名称放在引号中,并且后面可以跟参数。

Indeed the suggestion above

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

is simple and works!

The value 1 specifies to show the window, 0 is the default. The value True specifies to wait for completion; False returns immediately.

The pathFile follows the normal rules of construction you would use in a batch file - put the program path and name in quotes if necessary and can be followed by parameters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文