VBShell調(diào)用后等待程序運(yùn)行結(jié)束

字號(hào):

VB啟動(dòng)/結(jié)束另一程序(Shell 等待程序運(yùn)行結(jié)束)
    VB 中,常以Shell指令來(lái)執(zhí)行外部程式,然而它在Create該外部process 後,立刻就會(huì)回到vb 的下一行程式,無(wú)法做到等待該P(yáng)rocess結(jié)束時(shí),才執(zhí)行下一行指令,或是說(shuō),無(wú)法得知該P(yáng)rocess是否已結(jié)束,甚者,該P(yáng)rocess執(zhí)行到一半,又該如何中止其執(zhí)行等等,這些都不是Shell指令所能控制的,因此我們需使API的幫助來(lái)完成。
    第一個(gè)問(wèn)題,如何等待shell所Create的process結(jié)束後才往後執(zhí)行vb的程式。
    首先要知道的是,每個(gè)Process有的一個(gè)ProcessID,這是OS給定的,用來(lái)區(qū)別每個(gè) Process,這個(gè)Process ID(PID)主要可用來(lái)取得該P(yáng)rocess相對(duì)應(yīng)的一些資訊,然而要對(duì)該P(yáng)rocess的控制,卻大多透過(guò) Process Handle(hProcess)。VB Shell指令的傳回值是PID,而非hProcess,所以我們需透過(guò)OpenProcess這個(gè)API來(lái)取得 hProcess而OpenProcess()的第一個(gè)叁數(shù),指的是所取得的hProcess所具有的能力,像 PROCESS_QUERY_INFORMATION 便是讓GetExitCode()可取得hProcess所指的process之狀態(tài),而PROCESS_TERMINATE,便是讓TerminateProcess(hProcess……)
    的指令能夠生效,也就是說(shuō),不同叁數(shù)設(shè)定,使hProcess所具有的權(quán)限、能力有所不同。取得 hProcess後便可以使用WaitForSingleObject()來(lái)等待hProcess狀態(tài)的改變,也就是說(shuō),它會(huì)等待 hProcess所指的process執(zhí)行完,這個(gè)指令才結(jié)束,它第二個(gè)叁數(shù)所指的是 WaitForSingleObject()所要等待的時(shí)間(in milliseconds )
    如果超過(guò)所指的時(shí)間,就TimeOut而結(jié)束WaitForSingleObject()的等待。若要它無(wú)限的等下去,就設(shè)定為INFIN99vE.
    pid = Shell("C:\tools\spe3\pe2.exe", vbNormalFocus)
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
    ExitEvent = WaitForSingleObject(hProcess, INFIN99vE)
    Call CloseHandle(hProcess)
    上例會(huì)無(wú)限等待shell指令create之process結(jié)束後,才再做後面的vb指令。有時(shí)覺(jué)得那會(huì)等太久,所以有第二個(gè)解決方式:等process結(jié)束時(shí)再通知vb 就好,即:設(shè)定一個(gè)公用變數(shù)(isDone),當(dāng)它變成True時(shí)代表Shell所Create的Process已結(jié)束。當(dāng)Process還在執(zhí)行時(shí),GetExitCodeProcess會(huì)傳&H103給其第二個(gè)叁數(shù),直到結(jié)束時(shí)才傳另外的數(shù)值,如果程式正常結(jié)束,那Exitcode = 0,否則就得看它如何結(jié)束了?;蛟S有人在其他地方看到 loop的地方是Loop while Exitcode <> 0,那有一點(diǎn)危險(xiǎn),如果以這程子來(lái)看,您不是用F4來(lái)離開(kāi)pe2而是用右上方 X 的結(jié)束dos window那麼,會(huì)因?yàn)镋xitCode的值永遠(yuǎn)不會(huì)是0,而進(jìn)入無(wú)窮的回圈。
    Dim pid As Long
    pid = Shell("C:\tools\spe3\pe2.exe", vbNormalFocus)
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid)
    isDone = False
    Do
    Call GetExitCodeProcess(hProcess, ExitCode)
    Debug.Print ExitCode
    DoEvents
    Loop While ExitCode = STILL_ALIVE
    Call CloseHandle(hProcess)
    isDone = True