vb Shell 等待程序运行结束.doc_第1页
vb Shell 等待程序运行结束.doc_第2页
vb Shell 等待程序运行结束.doc_第3页
vb Shell 等待程序运行结束.doc_第4页
vb Shell 等待程序运行结束.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

VB启动/结束另一程序(Shell 等待程序运行结束)VB 中,常以Shell指令来执行外部程式,然而它在Create该外部process 後,立刻就会回到vb 的下一行程式,无法做到等待该Process结束时,才执行下一行指令,或是说,无法得知该Process是否已结束,甚者,该Process执行到一半,又该如何中止其执行等等,这些都不是Shell指令所能控制的,因此我们需使API的帮助来完成。第一个问题,如何等待shell所Create的process结束後才往後执行vb的程式。首先要知道的是,每个Process有唯一的一个ProcessID,这是OS给定的,用来区别每个 Process,这个Process ID(PID)主要可用来取得该Process相对应的一些资讯,然而要对该Process的控制,却大多透过 Process Handle(hProcess)。VB Shell指令的传回值是PID,而非hProcess,所以我们需透过OpenProcess这个API来取得 hProcess而OpenProcess()的第一个叁数,指的是所取得的hProcess所具有的能力,像 PROCESS_QUERY_INFORMATION 便是让GetExitCode()可取得hProcess所指的process之状态,而PROCESS_TERMINATE,便是让TerminateProcess(hProcess)的指令能够生效,也就是说,不同叁数设定,使hProcess所具有的权限、能力有所不同。取得 hProcess後便可以使用WaitForSingleObject()来等待hProcess状态的改变,也就是说,它会等待 hProcess所指的process执行完,这个指令才结束,它第二个叁数所指的是 WaitForSingleObject()所要等待的时间(in milliseconds )如果超过所指的时间,就TimeOut而结束WaitForSingleObject()的等待。若要它无限的等下去,就设定为INFIN99vE.pid = Shell(C:toolsspe3pe2.exe, vbNormalFocus)hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)ExitEvent = WaitForSingleObject(hProcess, INFIN99vE)Call CloseHandle(hProcess)上例会无限等待shell指令create之process结束後,才再做後面的vb指令。有时觉得那会等太久,所以有第二个解决方式:等process结束时再通知vb 就好,即:设定一个公用变数(isDone),当它变成True时代表Shell所Create的Process已结束。当Process还在执行时,GetExitCodeProcess会传&H103给其第二个叁数,直到结束时才传另外的数值,如果程式正常结束,那Exitcode = 0,否则就得看它如何结束了。或许有人在其他地方看到 loop的地方是Loop while Exitcode 0,那有一点危险,如果以这程子来看,您不是用F4来离开pe2而是用右上方 X 的结束dos window那麽,会因为ExitCode的值永远不会是0,而进入无穷的回圈。Dim pid As Longpid = Shell(C:toolsspe3pe2.exe, vbNormalFocus)hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)isDone = FalseDoCall GetExitCodeProcess(hProcess, ExitCode)Debug.Print ExitCodeDoEventsLoop While ExitCode = STILL_ALIVECall CloseHandle(hProcess)isDone = True另外,如果您的shell所Create的程式,有视窗且为立刻Focus者,可另外用以下的方式Dim pid As LongDim hwnd5 As Longpid = Shell(c:toolsspe3pe2.exe, vbNormalFocus)hwnd5 = GetForegroundWindow()isDone = FalseDo While IsWindow(hwnd5)DoEventsLoopisDone = True而如何强迫shell所Create的process结束呢,那便是Dim aa As LongIf hProcess 0 Thenaa = TerminateProcess(hProcess, 3838)End IfhProcess便是先前的例子中所取得的那个Process Handle, 3838所指的是传给GetExitCodeProcess()中的第二叁数,这是我们任意给的,但最好不要是0,因为0一般是代表正常结束,当然这样设也不会有错。当然不可设&H103,以这个例子来看,如果程式正处於以下的LOOPDoCall GetExitCodeProcess(hProcess, ExitCode)Debug.Print ExitCodeDoEventsLoop While ExitCode = STILL_ALIVEDebug.print ExitCode而执行了 TerminateProcess(hProcess, 3838)那会看到ExitCode = 3838.然而,这个方式在win95没问题,在NT中,可能您要在OpenProcess()的第一个叁数要更改成 PROCESS_QUERY_INFORMATION Or PROCESS_TERMINATE 这样才能Work.不过良心的建议,非到最後关头,不要使用TerminateProcess(),因不正常的结束,往往许多程式结束前所要做的事都没有做,可能造成Resource的浪费,甚者,下次再执行某些程式时会有问题,例如:本人常使用MS-dos Shell Link 的方式执行一程式,透过Com port与大电脑的联结,如果Ms-dos Shell Link 不正常结束,下次再想Link时,会发现too Many Opens,这便是一例。另外,有人使用Shell来执行。bat档,即:pid = Shell(c:aa.bat, vbNormalFocus)可是却遇上aa.bat结束了,但ms-dos的Window却仍活着,那可以用以下的方式来做pid = Shell(c: /c c:aa.bat, vbNormalFocus)那是执行C,而C指定执行c:aa.bat 而且结束时自动Close所有程式如下: Private Declare Function OpenProcess Lib kernel32 _(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _ByVal dwProcessId As Long) As LongPrivate Declare Function WaitForSingleObject Lib kernel32 _(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As LongPrivate Declare Function CloseHandle Lib kernel32 _(ByVal hObject As Long) As LongPrivate Declare Function GetExitCodeProcess Lib kernel32 _(ByVal hProcess As Long, lpExitCode As Long) As LongPrivate Declare Function TerminateProcess Lib kernel32 _(ByVal hProcess As Long, ByVal uExitCode As Long) As LongPrivate Declare Function GetForegroundWindow Lib user32 () As LongPrivate Declare Function IsWindow Lib user32 _(ByVal hwnd As Long) As LongConst PROCESS_QUERY_INFORMATION = &H400Const STILL_ALIVE = &H103Const INFIN99vE = &HFFFFPrivate ExitCode As LongPrivate hProcess As LongPrivate isDone As LongPrivate Sub Command1_Click()Dim pid As Longpid = Shell(C:toolsspepe2.exe, vbNormalFocus)hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)isDone = FalseDoCall GetExitCodeProcess(hProcess, ExitCode)Debug.Print ExitCodeDoEventsLoop While ExitCode = STILL_ALIVECall CloseHandle(hProcess)isDone = TrueEnd SubPrivate Sub Command2_Click()Dim pid As LongDim ExitEvent As Longpid = Shell(C:toolsspe3pe2.exe, vbNormalFocus)hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)ExitEvent = WaitForSingleObject(hProcess, INFIN99vE)Call CloseHandle(hProcess)End SubPrivate Sub Command3_Click()Dim aa As LongIf hProcess 0 Thenaa = TerminateProcess(hProcess, 3838)End IfEnd SubPrivate Sub Command4_Click()Dim pid As LongDim hwnd5 As Longpid = Shell(c:toolsspe3pe2.exe, vbNormalFocus)hwnd5 = GetForegroundWindow()isDone = FalseDo While IsWindow(hwnd5)DoEventsLoopisDone = TrueEnd SubPrivate Sub Command5_Click()Dim pid As Longpid = Shell(c:windowscommandxcopy c:aa.bat a:, vbHide)pid = Shell(c: /c c:aa.bat, vbNormalFocus)End SubModest:在使用shell后,如何等待此程序完成后,程序才继续执行。我们使用 shell 调用一个外部程序的时候,通常 vb(a) 会在调用之后继续下面的语句,而不管此 shell 程序执行完成没有。有时我们需要在此 shell 执行完成之后才继续,又当如何呢?请看源程:Public Declare Function OpenProcess Lib kernel32 Alias OpenProcess (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPublic Declare Function WaitForSingleObject Lib kernel32 Alias WaitForSingleObject (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As LongPublic Declare Function CloseHandle Lib kernel32 Alias CloseHandle (ByVal hObject As Long) As LongDim lngPId As LongDim lngPHandle As LonglngPId = Shell(Notepad, vbNormalFocus)lngPHandle = OpenProcess(SYNCHRONIZE, 0, lngpId)If lngPHandle 0 ThenCall WaitForSingleObject(lngPHandle, INFINITE) 无限等待, 直到程式结束Call CloseHandle(lngPHandle)End If需要注意的是,在 shell 程序未完成前,你的程序不能做任何事,请小心为之【laviewpbt】:Private Declare Function WaitForSingleObject Lib kernel32 (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As LongPrivate Declare Function CloseHandle Lib kernel32 (ByVal hObject As Long) As LongPrivate Declare Function ShellExecuteEx Lib shell32.dll Alias ShellExecuteExA (lpInfo As Any) As LongPriva

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论