软件注册站
热情软件屋

 
顺序调用多个可执行文件
编号: QA000021    
建立日期: 1998年5月1日 最后修改日期: 2001年7月22日
所属类别: Visual Basic - 其他方面
   
    我初学VB 5.0,想用SHELL函数调用三个可执行文件,但在VB 5.0中,SHELL函数是异步执行的,也就是说,第一个可执行文件调用完了,第二个文件还未运行完就跳到第三个可执行文件了,该如何使它们一个一个地运行呢?
    (林怀青)
   
    这是一个特别常见的问题,相信很多人都会遇到。
    如果使用VB.Net,Shell函数增加了一个参数表示是否等待。例子:
     Dim sysPath as String
     SysPath = System.Environment.GetFolderPath _
     (Environment.SpecialFolder.System)
     Shell(sysPath & "\notepad.exe", _
     AppWinStyle.NormalFocus, True)
    
    

    但如果使用VB 5.0/6.0,就比较麻烦了,一般实现这种等待的方法有四种:
    一种是利用是利用Win32 API的FindWindow函数。该函数可以搜索指定标题或类的窗口,你可以在调用第一个可执行文件后用FindWindow函数去找指定的窗口,如果找到了,就说明第一个文件还未运行完,等待,直到用FindWindow函数找不到指定窗口,就可以调用第二个文件。这种方法简单,但有个毛病,就是如果满足条件的窗口不只一个,比如用户打开了两个有相同类或标题的窗口(一个是VB程序打开的,而另一个可能是用户自行打开的),那么除非用户关闭这两个窗口,否则VB程序不会继续运行。比如Wise Install生成的安装程序就有这个毛病,它在安装过程中可能会用NotePad打开ReadMe文件,等用户看完ReadMe文件关闭窗口后继续安装,但如果用户此时用NotePad打开了其他文件,安装程序就会继续等待,应为FindWindow函数找到了NotePad窗口,可实际上这个窗口跟安装程序毫无关系。
    第二种是利用Windows 95新增加的命令Start。这个命令可以调用Windows程序,通常用在批文件中。它有一个/w开关,在被调用的程序继续运行结束之前等待。比如,你要调用的三个可执行文件为Command1、Command2和Command3,你可以构造一个批文件如下:
     Start/w Command1
     Start/w Command2
     Start/w Command3
    这个方法可以保证三个按既定顺序运行,但VB程序不能知道什么时候该批文件执行完毕。
    第三种方法是利用Windows API的OpenProcess和CloseHandle函数来实现对被调用软件的检测:
    1) 在VB中新建一个标准EXE工程;
    2) 在Form1中声明OpenProcess和 CloseHandle 这两个Windows API 函数;
     Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal
     bInheritHandle As Long, ByVal dwProcessId As Long) As Long
     Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    

    3) 然后编写下面的函数:
     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
    

    4) 在Form_Click()中加入代码:
     Sub Form_Click()
     Dim X
     Me.Caption = "开始运行"
     X = Shell("NotePad.EXE", 1)
     While IsRunning(X)
     DoEvents
     Wend
     Me.Caption = "结束运行"
     End Sub
    

    第四种方法是利用Win32 API的CreateProcess函数和WaitForSingleObject函数来进行这一工作。它的原理比较复杂,在此只介绍如何使用。首先建立一个模块(module),然后输入以下语句:
     Option Explicit
    
     Type STARTUPINFO
     cb As Long
     lpReserved As String
     lpDesktop As String
     lpTitle As String
     dwX As Long
     dwY As Long
     dwXSize As Long
     dwYSize As Long
     dwXCountChars As Long
     dwYCountChars As Long
     dwFillAttribute As Long
     dwFlags As Long
     wShowWindow As Integer
     cbReserved2 As Integer
     lpReserved2 As Long
     hStdInput As Long
     hStdOutput As Long
     hStdError As Long
     End Type
     Type PROCESS_INFORMATION
     hProcess As Long
     hThread As Long
     dwProcessID As Long
     dwThreadID As Long
     End Type
     Global Const NORMAL_PRIORITY_CLASS = &H20&
     Global Const INFINITE = -1&
     Declare Function CloseHandle Lib "kernel32" (hObject As Long) As Boolean
     Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
     Declare Function CreateProcessA Lib "kernel32" ( _
     ByVal lpApplicationName As Long, _
     ByVal lpCommandLine As String, ByVal lpProcessAttributes As Long, ByVal _
     lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal _
     dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal _
     lpCurrentDirectory As Long, lpStartupInfo As STARTUPINFO, _
     lpProcessInformation As PROCESS_INFORMATION) As Long
    
     Public Sub ShellAndWait(cmdline$)
     Dim NameOfProc As PROCESS_INFORMATION
     Dim NameStart As STARTUPINFO
     Dim X As Long
    
     NameStart.cb = Len(NameStart)
     X = CreateProcessA(0&, cmdline$, 0&, 0&, 1&, NORMAL_PRIORITY_CLASS, _
     0&, 0&, NameStart, NameOfProc)
     X = WaitForSingleObject(NameOfProc.hProcess, INFINITE)
     X = CloseHandle(NameOfProc.hProcess)
     End Sub
     建立一个窗体,并放一个命令按钮(Command1)在其上。在Command1_Click事件中输入以下内容:
     Private Sub Command1_Click()
     Dim AppToLaunch As String
    
     AppToLaunch = "c:\win95\notepad.exe"
     ShellAndWait AppToLaunch
     End Sub
    
    
运行该程序,按下Command1,就会调用NotePad,在NotePad运行完毕之前,VB程序不会继续执行。你可以在程序中使用ShellAndWait来代替Shell命令。

    

此问题由李海回答。

附加关键字:编程, 源程序, programming, source code, Visual Basic, VB, 其他方面,

   
 
把这个问题推荐给朋友
   
 
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio