确定 shell 进程何时结束-杨雪
Access软件网QQ交流学习群(群号码198465573),欢迎您的加入!
首页 >技术文章> Access数据库-模块/函数/VBA


确定 shell 进程何时结束

发表时间:2022/11/5 5:44:27 评论(0) 浏览(1189)  评论 | 加入收藏 | 复制
   
摘 要:创建 Shelled 进程,等待 Shelled 进程结束。
正 文:
当您在 VBA Visual Basic for Applications (中运行 Shell) ,它将异步启动可执行程序,并返回对该过程的控制权。 此 Shelled 程序将继续独立于您的过程运行,直到关闭它。

如果您的过程需要等待 Shelled 进程结束,则可以使用 Windows API 来轮询应用程序的状态,但此方法并不是很有效。 本主题介绍一种更有效的方法。

Windows API 具有集成功能,该功能可以使应用程序等待,直到 Shelled 进程完成。 要使用这些函数,需要有 Shelled 程序的句柄。 要完成此操作,应使用 CreateProcess 函数而不是 Shell 函数来开始 Shelled 程序。

创建 Shelled 进程
若要创建可寻址进程,请使用 CreateProcess 函数来启动 Shelled 应用程序。 CreateProcess 函数会通过它传递的其中一个参数来为您的程序提供 Shelled 进程的进程句柄。

等待 Shelled 进程结束
使用 CreateProcess 函数取得进程句柄后,可以将该句柄传递给 WaitForSingleObject 函数。 这样会使 VBA 过程暂停执行,直到 Shelled 程序结束。

构建使用 CreateProcess 函数运行 Windows 记事本应用程序的 VBA 过程需要执行下列步骤。 以下代码说明在继续执行之前,如何使用 Windows API CreateProcess 和 WaitForSingleObject 函数等待,直到 Shelled 进程结束。

CreateProcess 函数的语法比较复杂,因此在示例代码中,该函数被封装在一个名为 ExecCmd 的函数中。 ExecCmd 利用一个参数(即应用程序的命令行)来执行。

创建一个标准模块,并将以下行粘贴到声明节:

Option Explicit 

Private Type STARTUPINFO 
cb As Long 
lpReserved As String 
lpDesktop As String 
lpTitle As String 
dwX As Long 
dwY As Long 
dwXSize As Long 
dwYSize As Long 
dwXCountChars As Long 
dwYCountChars As Long 
dwFillAttribute As Long 
dwFlags As Long 
wShowWindow As Integer 
cbReserved2 As Integer 
lpReserved2 As Long 
hStdInput As Long 
hStdOutput As Long 
hStdError As Long 
End Type 

Private Type PROCESS_INFORMATION 
hProcess As Long 
hThread As Long 
dwProcessID As Long 
dwThreadID As Long 
End Type 

Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal _ 
hHandle As Long, ByVal dwMilliseconds As Long) As Long 

Private Declare Function CreateProcessA Lib "kernel32" (ByVal _ 
lpApplicationName As Long, ByVal lpCommandLine As String, ByVal _ 
lpProcessAttributes As Long, ByVal lpThreadAttributes As Long, _ 
ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _ 
ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _ 
lpStartupInfo As STARTUPINFO, lpProcessInformation As _ 
PROCESS_INFORMATION) As Long 

Private Declare Function CloseHandle Lib "kernel32" (ByVal _ 
hObject As Long) As Long 

Private Const NORMAL_PRIORITY_CLASS = &H20& 
Private Const INFINITE = -1& 
将以下代码粘贴到模块中:

Public Sub ExecCmd(cmdline As String) 
Dim proc As PROCESS_INFORMATION 
Dim start As STARTUPINFO 
Dim ReturnValue As Integer 

' Initialize the STARTUPINFO structure: 
start.cb = Len(start) 

' Start the shelled application: 
ReturnValue = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, _ 
NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc) 

' Wait for the shelled application to finish: 
Do 
ReturnValue = WaitForSingleObject(proc.hProcess, 0) 
DoEvents 
Loop Until ReturnValue <> 258 

ReturnValue = CloseHandle(proc.hProcess) 
End Sub


若要测试函数,请在"立即"窗口中粘贴 以下代码 ,然后按 Enter。 记事本启动。 片刻后,关闭记事本。 关闭时,将显示记事本框。

ExecCmd "NOTEPAD.EXE": MsgBox "Process Finished" 




Access软件网交流QQ群(群号:198465573)
 
 相关文章
SHELL命令在VBA中的妙用  【赵文斌  2011/7/19】
【Access自定义函数】VBA删除进程代码  【金宇  2015/7/31】
Shell 获取 返回(输出文本)  【litao  2018/2/8】
【Access自定义函数】Access打开文件及Access打开文...  【麥田  2021/2/8】
【转载】国外VBA 调用PowerShell压缩和解压缩文件代码  【金宇  2021/11/2】
【转载】VBA 调用PowerShell脚本并返回字符的哈希值  【金宇  2021/11/9】
常见问答
技术分类
相关资源
文章搜索
关于作者

杨雪

文章分类

文章存档

友情链接