我希望用shell运行的程序能同步执行,也就是说一直等到所运行的程序执行完毕退出后再往下运行,可是shell办不到。所以变通一下,用shell运行程序(比如说计算器后),我就循环,一直到该程序运行完毕。所以我要再循环中检测这个进程是否还存在。在网上找到一个方法,如下:Declare Function OpenProcess Lib "kernel32" Alias "OpenProcess" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'建立下面函数,用以判断程序是否在运行,如果是,则在运行时返回True。
'RetVal为程序返回参数,通过该参数返回句柄
'成检测到时为TRUE,没有检到时为FALSE
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  Function IsRunning(ByVal ProgramID) As Boolean  '传入进程标识ID
    Dim hProgram As Long   '被检测的程序进程句柄
    hProgram=OpenProcess(0,False,ProgramID)
    If Not hProgram=0 Then
     IsRunning=True
    Else
     IsRunning=False
    End If
    CloseHandle hProgram
  End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub Command1_Click()
'例调用某程序
   Dim RetVal
   MsgBox "开始运行"
   RetVal = Shell("1.EXE", 1)
   While IsRunning(RetVal)
     DoEvents
   Wend
   MsgBox "结束运行"
End Sub该方法在98下完全可行,效果很好。但是在2000和XP下就不行了,OpenProcess总是返回0。
有谁知道在2000或者XP下如何完成我所希望的功能?

解决方案 »

  1.   

    ' 试试这个函数' 以同步方式运行另一个程序, 该程序运行结束后才执行函数后面的语句
    ' AppName 为执行应用程序的文件名, ShowWindow 为窗口的显示方式
    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
    Declare Function CloseHandle Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long
    Const SYNCHRONIZE = &H100000
    Const WAIT_TIMEOUT = &H102&Function ShellForWait(ByVal AppName As String, Optional ByVal ShowWindow As VbAppWinStyle = vbMinimizedFocus) As Boolean
    Dim ID As Long, hwnd As Long, ret As Long
    On Error Resume Next
    ID = Shell(AppName, ShowWindow)
    If ID > 0 Then
        hwnd = OpenProcess(SYNCHRONIZE, 0, ID)
        If hwnd <> 0 Then
            Do
                ret = WaitForSingleObject(hwnd, 0)
                DoEvents
            Loop While ret = WAIT_TIMEOUT
            CloseHandle hwnd
            ShellForWait = True
        Else
            ShellForWait = False
        End If
    Else
        ShellForWait = False
    End If
    End Function
      

  2.   

    谢谢,看了你的程序,我发现只要把我的程序稍微改一下,也是可以正常运行的。
    改什么呢,改openprocess的参数,改成你的参数就正常了
    但是我不知道为什么改了之后就可以运行了,就是说为什么要这样写呢?
    请赐教!还有,我找到一个同步运行其他程序的API,帖出来大家看看吧
    Declare Function FSyncShell Lib "VB5STKIT.DLL" Alias "SyncShell" (ByVal strCmdLine As String, ByVal intCmdShow As Long) As Long
      

  3.   

    MSDN的说明:OpenProcess
    The OpenProcess function returns a handle to an existing process object. HANDLE OpenProcess(
      DWORD dwDesiredAccess,  // access flag
      BOOL bInheritHandle,    // handle inheritance flag
      DWORD dwProcessId       // process identifier
    );
     
    Parameters
    dwDesiredAccess 
    Specifies the access to the process object. For operating systems that support security checking, this access is checked against any security descriptor for the target process. Any combination of the following access flags can be specified in addition to the STANDARD_RIGHTS_REQUIRED access flags: Access Description 
    PROCESS_ALL_ACCESS Specifies all possible access flags for the process object. 
    PROCESS_CREATE_PROCESS Used internally. 
    PROCESS_CREATE_THREAD Enables using the process handle in the CreateRemoteThread function to create a thread in the process. 
    PROCESS_DUP_HANDLE Enables using the process handle as either the source or target process in the DuplicateHandle function to duplicate a handle. 
    PROCESS_QUERY_INFORMATION Enables using the process handle in the GetExitCodeProcess and GetPriorityClass functions to read information from the process object. 
    PROCESS_SET_INFORMATION Enables using the process handle in the SetPriorityClass function to set the priority class of the process. 
    PROCESS_TERMINATE Enables using the process handle in the TerminateProcess function to terminate the process. 
    PROCESS_VM_OPERATION Enables using the process handle in the VirtualProtectEx and WriteProcessMemory functions to modify the virtual memory of the process. 
    PROCESS_VM_READ Enables using the process handle in the ReadProcessMemory function to read from the virtual memory of the process. 
    PROCESS_VM_WRITE Enables using the process handle in the WriteProcessMemory function to write to the virtual memory of the process. 
    SYNCHRONIZE Windows NT: Enables using the process handle in any of the wait functions to wait for the process to terminate. 
    bInheritHandle 
    Specifies whether the returned handle can be inherited by a new process created by the current process. If TRUE, the handle is inheritable. 
    dwProcessId 
    Specifies the process identifier of the process to open. 
    Return Values
    If the function succeeds, the return value is an open handle to the specified process.If the function fails, the return value is NULL. To get extended error information, call GetLastError. Res
    The handle returned by the OpenProcess function can be used in any function that requires a handle to a process, such as the wait functions, provided the appropriate access rights were requested. When you are finished with the handle, be sure to close it using the CloseHandle function.QuickInfo
      Windows NT: Requires version 3.1 or later.
      Windows: Requires Windows 95 or later.
      Windows CE: Unsupported.
      Header: Declared in winbase.h.
      Import Library: Use kernel32.lib.
      

  4.   

    http://expert.csdn.net/Expert/FAQ/FAQ_Index.asp?id=18848