我在一个工程里以shell的方式执行的了一个exe文件
当我Unload这个工程的时候想要先关掉这个exe文件请问该怎样执行?

解决方案 »

  1.   

    a=shell(x.exe)
    那个A就是 启动程序的句柄 向A中发送关闭消息就好了
      

  2.   

    来源:
    http://www.zjol.com.cn/vbbible/software/program/vb/ccw/htmapi77.htm
                    正常结束由Shell所引发的Window 程式
    来源:cww我们曾在使Shell指令具Wait功能的文章中
    提过,使用TerminateProcess()来结束一个由Shell所引发的Process,但也说过,这可
    能会有一些问题,如果说,所引发的是一般正常且单一的Window程式(如NotePad),那
    是有办法令之正常结束的,那便是使用PostMessage(hWnd, WM_CLOSE,0,0),令该Window
    结束。然而,Shell的传回值是Process ID而不是hWnd,所以要加一些动作来取得hWnd。
    我们可以用 GetForegroundWindow来做(如果该Shell是指定vbNormalFocus),另也可以使
    用FindWindow来做,但是,如果有两个NotePad在时,会取到那一个,实在不知。另外使
    EnumWindows来做,该Function用来巡行Top Level的Window,我们传入ProcessID当做
    EnumWindows的第二个叁数,於是EnumWindowProcedure中的lParam便是该ProcessID,我
    们另外用tid = GetWindowThreadProcessId(hwnd, pid)来取得hWnd所属的ProcessID
    与我们传入的ProcessID(lParam)做比较,若相同,代表我们已找到所要的hWnd了。
    EnumWindows的用法请叁考尝试寻找电脑中执行的程式当然,这个程式的做法不是万能的,如果产生的Process又产生有好多个Window,我们结束
    的,可能只是其中之一,那程式可能要改一下,变成只要在EnumWindow Procedure中找到
    一个PID与Shell传回值的PID相同者,就使用PostMessage(hwnd, WM_CLOSE, 0,0)来结束
    之,但这也不一定就全然可行,如果产生的不是一个有Window的程式,那使用WM_CLOSE
    是没有用的,唯一能做的,就是使用TerminateProcess来强迫中断程式。以下程式在.BAS
    Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
    Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Declare Function SetForegroundWindow Lib "user32" Alias "SetForegroundWindow" (ByVal hwnd As Long) As Long
    Declare Function OpenProcess Lib "kernel32" _
        (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
         ByVal dwProcessId As Long) As Long
    Declare Function WaitForSingleObject Lib "kernel32" _
        (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    Declare Function CloseHandle Lib "kernel32" _
        (ByVal hObject As Long) As Long
    Declare Function GetExitCodeProcess Lib "kernel32" _
        (ByVal hProcess As Long, lpExitCode As Long) As Long
    Declare Function TerminateProcess Lib "kernel32" _
        (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
    Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
        (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
         ByVal lParam As Long) As LongPublic Const SYNCHRONIZE = &H100000
    Public Const STILL_ALIVE = &H103
    Public Const INFINITE = &HFFFF
    Public Const WM_CLOSE = &H10
    Public hWnd5 As Long
    Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
        Dim S As String
        If GetParent(hwnd) = 0 Then
           Dim tid As Long, pid As Long
           tid = GetWindowThreadProcessId(hwnd, pid)
           If pid = lParam Then
      hWnd5 = hwnd
      EnumWindowsProc = False
           End If
        End If
        EnumWindowsProc = True ' 表示继续列举 hWnd
    End Function
     
    以下程式在Form
    Option Explicit
     Private ExitCode As Long
     Private hProcess As Long
     Private isDone As Long
     Private Sub Command1_Click()
     Dim pid As Long
     pid = Shell("notepad.exe", vbNormalFocus)
     Call EnumWindows(AddressOf EnumWindowsProc, pid) '设定hWnd5的值
     hProcess = OpenProcess(SYNCHRONIZE , 0, pid)
     isDone = False
     Do
       Call GetExitCodeProcess(hProcess, ExitCode)
       DoEvents
     Loop While ExitCode = STILL_ALIVE Or isDone
     Call CloseHandle(hProcess)
     isDone = True
     Label1.Caption = "Over"
     End Sub Private Sub Command2_Click()
     Dim i As Long
     Call SetForegroundWindow(hWnd5)
     Call PostMessage(hWnd5, WM_CLOSE, 0, 0)
     End Sub Private Sub Form_Unload(Cancel As Integer)
     isDone = True
     End Sub