VB中调用外部可执行程序,当外部exe程序执行完毕以后,为什么hProcess = OpenProcess(fdwAccess, False, ProcessID)返回的hProcess 值不为0?
前不久发的一个贴子已经冷了,但问题还是没有解决,请大侠们帮忙解决啊!

解决方案 »

  1.   

    1.VB声明   
    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
      

  2.   

    CreateProcess可以在创建成功后直接返回进程的句柄
      

  3.   

    我以前也是遇到过这样的问题,才放弃了这个方案。waitforsingerobject才是王道,相信我。
      

  4.   


    我现在是用如下语句等待程序的运行结束的:
    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解决的话,就好了
      

  5.   

    我服了LZ你了,waitforsingerobject 使用很简单的。
    就这样:waitforsingerobject hProcess,-1
    就进入等待状态,直到程序运行结束,不然下一句不会执行。
      

  6.   

    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,就用起来了.
      

  7.   

    waitforsingerobject有个问题,就是整个进程都挂起了.自己检测状态再doevents可以只让本过程挂起.
      

  8.   


    waitforsingerobject 一样可以设置超时为0,然后自己循环里面加doevents来避免挂起。ps:不过....如果加上老汉WS的多线程,那就完美了!
      

  9.   

     我根据3楼的建议,代码如下,问题得以解决,谢谢大家的热情帮助哦  hProcess = OpenProcess(SYNCHRONIZE, 0, ProcessID) ' 取得 Process Handle 得到的进程句柄
        If hProcess <> 0 Then '句柄获得成功 则执行if内语句
           Call WaitForSingleObject(hProcess, INFINITE) ' 无限等待,直到程序结束
           Call CloseHandle(hProcess) '释放句柄
        End If
      

  10.   

    老汉的WS多线程还是不错的,虽然VB中多线程确实都是不安全的,但是无奈的时候用用也没什么大不了的。