我现在是用如下语句等待程序的运行结束的: Do hProcess = OpenProcess(fdwAccess, False, ProcessID) If Not hProcess = 0 Then IsRunning = True Else IsRunning = False End If Call CloseHandle(hProcess) DoEvents Loop While IsRunning 结果是返回的hProcess 值始终不为0,陷入死循环。如果能用waitforsingerobject解决的话,就好了
Option Explicit '************************************************************************* '**模 块 名:ModShellEx '**说 明:增强SHELL函数 '**创 建 人:马大哈 '**描 述:紫水晶工作室 http://www.m5home.com/ '**日 期:2007年4月24日 '**版 本:V1.0 '*************************************************************************Private Declare Function GetProcessVersion Lib "kernel32" (ByVal ProcessId As Long) As Long Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)Public Function ShellEx(ByVal FileName As String, Optional ByVal WindowStyle As VbAppWinStyle = vbNormalFocus, Optional ByVal DelayTime As Long = -1) As Long '与SHELL函数一样的参数,不过是阻塞执行.(同步) 'FileName - 目标文件名 'WindowStyle - 程序运行时窗口的样式 'DelayTime - 等待的时间,单位为ms '备注: ' DelayTime设置为-1时表示一直等待,直到目标程序运行结束 Dim I As Long, J As Long
I = Shell(FileName, WindowStyle) ShellEx = I Do If GetProcessVersion(I) = 0 Then Exit Do '目标进程退出时跳出 Sleep 10 J = J + 1 DoEvents If DelayTime <> -1 And J > DelayTime \ 10 Then Exit Do '非永远等待+等待时间达到时跳出 Loop End Function 有次翻MSDN时无意中发现了GetProcessVersion这个API,就用起来了.
Declare Function OpenProcess Lib "kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
说明 打开一个现有进程的句柄
2.返回值 Long,如执行成功,返回进程句柄;零表示失败。会设置GetLastError
3.参数表 参数 类型 及 说明 dwDesiredAccess Long,指定这个句柄要求的访问方法。指定API32.TXT文件中以PROCESS_???开头的一个或多个常数 bInheritHandle Long,如句柄能够由子进程继承,则为TRUE dwProcessId Long,要打开那个进程的进程标识符
4.注解 这个函数经常用来打开一个要进行同步的进程(同步:即步调协同,你说完,我再说,按说好的先后次序来)
5.举例 hProcess = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
打开进程
If hProcess Then
ReadProcessMemory hProcess, ByVal &H12F82C, base, 4, 0&
读写进程内存
CloseHandle hProcess
结束进程
End If
我现在是用如下语句等待程序的运行结束的:
Do
hProcess = OpenProcess(fdwAccess, False, ProcessID)
If Not hProcess = 0 Then
IsRunning = True
Else
IsRunning = False
End If
Call CloseHandle(hProcess)
DoEvents
Loop While IsRunning
结果是返回的hProcess 值始终不为0,陷入死循环。如果能用waitforsingerobject解决的话,就好了
就这样:waitforsingerobject hProcess,-1
就进入等待状态,直到程序运行结束,不然下一句不会执行。
'*************************************************************************
'**模 块 名:ModShellEx
'**说 明:增强SHELL函数
'**创 建 人:马大哈
'**描 述:紫水晶工作室 http://www.m5home.com/
'**日 期:2007年4月24日
'**版 本:V1.0
'*************************************************************************Private Declare Function GetProcessVersion Lib "kernel32" (ByVal ProcessId As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)Public Function ShellEx(ByVal FileName As String, Optional ByVal WindowStyle As VbAppWinStyle = vbNormalFocus, Optional ByVal DelayTime As Long = -1) As Long
'与SHELL函数一样的参数,不过是阻塞执行.(同步)
'FileName - 目标文件名
'WindowStyle - 程序运行时窗口的样式
'DelayTime - 等待的时间,单位为ms
'备注:
' DelayTime设置为-1时表示一直等待,直到目标程序运行结束
Dim I As Long, J As Long
I = Shell(FileName, WindowStyle)
ShellEx = I
Do
If GetProcessVersion(I) = 0 Then Exit Do '目标进程退出时跳出
Sleep 10
J = J + 1
DoEvents
If DelayTime <> -1 And J > DelayTime \ 10 Then Exit Do '非永远等待+等待时间达到时跳出
Loop
End Function
有次翻MSDN时无意中发现了GetProcessVersion这个API,就用起来了.
waitforsingerobject 一样可以设置超时为0,然后自己循环里面加doevents来避免挂起。ps:不过....如果加上老汉WS的多线程,那就完美了!
If hProcess <> 0 Then '句柄获得成功 则执行if内语句
Call WaitForSingleObject(hProcess, INFINITE) ' 无限等待,直到程序结束
Call CloseHandle(hProcess) '释放句柄
End If