跳轉到內容

Visual Basic/外部程序

來自華夏公益教科書,自由的教科書

通常情況下,已經存在一個程式可以完成某些工作,因此與其在 Visual Basic 中重新編寫該程式,不如從 Visual Basic 中執行現有程式更有效。這對於命令列程式或任何語言編寫的指令碼非常有效。

一般方案是建立一個包含命令列的字串,呼叫一個函式來執行它,然後等待命令完成。可以進行許多改進,包括各種向新程序傳送資料、從中讀取結果、暫停它、設定其優先順序等的方法。

Shell 函式

[編輯 | 編輯原始碼]

執行外部程式的最簡單方法是執行類似以下操作

Shell "cmd /c dir %temp%"

Shell 是 Visual Basic 中的內建函式,它執行命令列並返回對該程序的控制代碼Shell 接受一個可選引數,該引數控制新程序的視窗樣式(最大化、正常、隱藏等)。

不幸的是,像這樣執行另一個程式並不會讓你對正在發生的事情有太多控制。特別是,沒有明顯的方法可以知道程式是否已完成其工作。

幸運的是,Shell 實際上比啟動程式做得更多。它還返回程序 ID。這是任務管理器顯示的數字,可用於檢查程序的狀態。不幸的是,正如 Visual Basic 和 Windows 的許多情況下那樣,沒有內建函式,甚至沒有單個 API 函式可以直接使用它。因此,我們必須編寫更多程式碼。首先,我們必須宣告一些 API 函式和常量

  Option Explicit
  
  Const SYNCHRONIZE = &H100000
  Const INFINITE = &HFFFF    'Wait forever
  Const WAIT_OBJECT_0 = 0    'The state of the specified object is signaled.
  Const WAIT_TIMEOUT = &H102 'The time-out interval elapsed, and the object’s state is nonsignaled.
  
  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
  
  Dim ProcessID As Long
  Dim hProcess As Long

以下是一個執行命令並等待其完成的函式示例

  Function ShellWait(CommandLine As String, _
                     TimeOut As Long, _
                     WindowState As VbAppWinStyle) As Boolean
    
    Dim ProcessID As Long
    Dim hProcess As Long
    
    ProcessID = Shell(CommandLine,WindowState)
    If ProcessID <> 0 Then
      'non-zero (True) so Shell worked
      ' Get a process handle for the PID (Wait takes a handle)
      hProcess = OpenProcess(SYNCHRONIZE, False, ProcessID)
      If hProcess <> 0 Then
        ' Got process handle
        ' Wait until process finishes before going on
        If WaitForSingleObject(hProcess, TimeOut) = WAIT_OBJECT_0 Then
          ShellWait = True
        Else
          ShellWait = False
        End If
      Else
        'Failed to get process handle.
        'Perhaps the process terminated very quickly
        'or it might not really have executed at all even though Windows
        ' started a process.
        ShellWait = False
      End If
    Else
      ' PID zero (False) so Shell failed
      ShellWait = False
    End If
  End Function

像這樣呼叫它

  If ShellWait("calc.exe") then
    MsgBox "Success :-)"
  Else
    MsgBox "Failure :-("
  End If
  • 修改 ShellWait 示例函式,以便呼叫者可以區分啟動程序失敗和超時。
  • 建議一個原因,說明為什麼這可能是個好主意。


前一個: Windows_API 目錄 下一個: 面向物件程式設計
華夏公益教科書