有一點危險,如果以這程子來看,您不是用F4來離開pe2而是用右上方 X 的結束
dos window那麼,會因為ExitCode的值永遠不會是0,而進入無窮的迴圈。
Dim pid As Long
pid = Shell("C:\tools\spe3\pe2.exe", vbNormalFocus)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION+SYNCHRONIZE, 0, pid)
isDone = False
Do
Call GetExitCodeProcess(hProcess, ExitCode)
Debug.Print ExitCode
DoEvents
Loop While ExitCode = STILL_ALIVE
Call CloseHandle(hProcess)
isDone = True
另外,如果您的shell所Create的程式,有視窗且為立刻Focus者,可另外用以
下的方式Dim pid As Long
Dim hwnd5 As Long
pid = Shell("c:\tools\spe3\pe2.exe", vbNormalFocus)
hwnd5 = GetForegroundWindow()
isDone = False
Do While IsWindow(hwnd5)
DoEvents
Loop
isDone = True
而如何強迫shell所Create的process結束呢,那便是
Dim aa As Long
If hProcess <> 0 Then
aa = TerminateProcess(hProcess, 3838)
End If
hProcess便是先前的例子中所取得的那個Process Handle, 3838所指的是傳給
GetExitCodeProcess()中的第二參數,這是我們任意給的,但最好不要是0,因為
0一般是代表正常結束,當然這樣設也不會有錯。當然不可設&H103,以這個例子來
看,如果程式正處於以下的LOOP
Do
Call GetExitCodeProcess(hProcess, ExitCode)
Debug.Print ExitCode
DoEvents
Loop While ExitCode = STILL_ALIVE
Debug.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,這便是一例。
所有程式如下:
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" _
(ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" _
(ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function IsWindow Lib "user32" _
(ByVal hwnd As Long) As Long
Private ExitCode As Long
Private hProcess As Long
Private isDone As Long
Private Sub Command1_Click()
Dim pid As Long
pid = Shell("C:\tools\spe3\pe2.exe", vbNormalFocus)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION+SYNCHRONIZE, 0, pid)
isDone = False
Do
Call GetExitCodeProcess(hProcess, ExitCode)
Debug.Print ExitCode
DoEvents
Loop While ExitCode = STILL_ALIVE
Call CloseHandle(hProcess)
isDone = True
End Sub
Private Sub Command2_Click()
Dim pid As Long
Dim ExitEvent As Long
pid = Shell("C:\tools\spe3\pe2.exe", vbNormalFocus)
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION+SYNCHRONIZE, 0, pid)
ExitEvent = WaitForSingleObject(hProcess, INFINITE)
Call CloseHandle(hProcess)
End Sub
Private Sub Command3_Click()
Dim aa As Long
If hProcess <> 0 Then
aa = TerminateProcess(hProcess, 3838)
End If
End Sub
Private Sub Command4_Click()
Dim pid As Long
Dim hwnd5 As Long
pid = Shell("c:\tools\spe3\pe2.exe", vbNormalFocus)
hwnd5 = GetForegroundWindow()
isDone = False
Do While IsWindow(hwnd5)
DoEvents
Loop
isDone = True
End Sub
Private Sub Command5_Click()
Dim pid As Long
'pid = Shell("c:\windows\command\xcopy c:\aa.bat a:", vbHide)
pid = Shell("c:\command.com /c c:\aa.bat", vbNormalFocus)
End Sub作者: mhfo 時間: 2012-11-25 13:51