[VB6] Anwendungen starten und beenden

Im folgenden zeige ich, wie man eine externe Anwendung (fremdes Programm)  mit Visual Basic startet und auch wieder beendet.

Starten einer externen Anwendung

Zum starten einer Anwendung (also eines fremden Programmes) kann man die Shell-Funktion benutzen:

' Programm startet in Normalgröße mit Fokus
TaskID = Shell("C:\Pfad\Programm.exe", vbNormalFocus)

Damit ist das aufgerufene Programm sofort im Vordergrund.

Neben der Konstante vbNormalFocus stehen noch folgende weitere Konstanten zur Verfügung:

vbHide (0): Das Fenster ist ausgeblendet, und das ausgeblendeteFenster erhält den Fokus.

vbNormalFocus (1): Das Fenster hat den Fokus, und die ursprüngliche Größeund Position wird wiederhergestellt.

vbMinimizedFocus (2): Das Fenster wird als Symbol mit Fokus angezeigt.

vbMaximizedFocus (3): Das Fenster wird maximiert mit Fokus angezeigt.

vbNormalNoFocus (4): Die zuletzt verwendete Größe und Position des Fensters wirdwiederhergestellt. Das momentan aktive Fenster bleibt aktiv.

vbMinimizedNoFocus (6): Das Fenster wird als Symbol angezeigt. Das momentan aktiveFenster bleibt aktiv.


Ab Windows Vista ist eine andere Alternative etwas besser: Shellexecute startet Anwendungen und öffnet Dokumente

Viele Programmierer verwenden zum Aufruf externen Programme aus der eigenen Anwendung heraus die Shell-Anweisung von VB, die oben vorgestellt wurde. Ab Windows Vista – mit aktivierter Benutzerkontensteuerung – funktioniert das Ganze jedoch nicht immer, meist nämlich dann nicht, wenn man nicht als Admin angemeldet ist bzw. die eigene Anwendung mit Adminrechten aufgerufen hat.

Eine Alternative zur Shell-Anweisung ist die API-Funktion ShellExecute. Diese lässt sich nicht nur für den Aufruf von verknüpften Dokumenten verwenden, sondern auch zum Aufruf ausführbarer Anwendungen. Die Funktion startet eine Anwendung oder ein Dokument mit der verknüpften Anwendung, wobei man noch den Start- und Fenstermodus festlegen kann.

Deklaration:

Declare Function ShellExecute Lib "shell32.dll" _
  Alias "ShellExecuteA" ( _
  ByVal hwnd As Long, _
  ByVal lpOperation As String, _
  ByVal lpFile As String, _
  ByVal lpParameters As String, _
  ByVal lpDirectory As String, _
  ByVal nShowCmd As Long) As Long

Beispiel:

g = ShellExecute(GetDesktopWindow(), "Open", Anwendungspfad/Anwendungsname, "", "C:\", 1)

Parameter:

hwnd    

Handle des aufrufenden Fensters

lpOperation    

Erwartet eine Zeichenfolge, die beschreibt, welche Operation ausgeführt werden soll. Bei diesen Operationen handelt es sich um Befehle, die in der Windows-Registry stehen und auch im Kontextmenü der Datei im Windows-Explorer zu finden sind. Wird ein leerer String übergeben, wird der Standard-Öffnenbefehl benutzt. Ist dieser Standard-Befehl nicht in der Windows-Registry vorhanden, wird die Datei mit dem “Open””-Kommando geöffnet. Unter Windows 2000 wird ebenfalls versucht das Dokument per Standard-Kommando zu öffnen. Ist kein Standard-Kommando definiert, so bedient sich Windows 2000 dem ersten Registryeintrag, welcher bei der verknüpften Datei gefunden wird. Gültige Kommandos sind die folgenden Strings.

lpOperation

“edit” Verhält sich so, als würde man im Kontextmenü des Explorers auf “Bearbeiten” klicken.

“explore” Handelt es sich bei “lpFile” um einen Verzeichnispfad, wird der Windows Explorer in Verbindung mit diesem Verzeichnis geöffnet.

“find” Handelt es sich bei “lpFile” um einen Verzeichnispfad, wird der Windows Suchen-Dialog gestartet.

“open” Öffnet die Datei mit dem lt. Registry verknüpften Programm.

“print” Druckt das Dokument in Verbindung mit der verknüpften Anwendung.

“properties” Zeigt die Verzeichnis- oder Datei-Eigenschaften

lpFile   

Verzeichnisnamen, Datei oder Dokument, welches mit der verknüpften Anwendung geöffnet werden soll.

lpParameters   

Optionale Angabe von zusätzlichen Aufruf-Parametern.

lpDirectory   

Legt das Arbeitsverzeichnis fest.

nCmdShow   

Erwartet ein Konstante, die beschreibt, wie sich das Anwendungs-Fenster berhalten soll. Folgende Konstanten kann man wählen:

' versteckt das Fenster
Const SW_HIDE = 0
 
' maximiert das Fenster
Const SW_MAXIMIZE = 3
 
' minmiert das Fenster
Const SW_MINIMIZE = 6
 
' aktiviert das Fenster
Const SW_NORMAL = 1
 
' zeigt das Fenster
Const SW_SHOW = 5
 
' stellt die Fenstergröße wieder her
Const SW_RESTORE = 9
 
' zeigt das Fenster an und maximiert es
Const SW_SHOWMAXIMIZED = 3
 
' zeigt das Fenster an und minimiert es
Const SW_SHOWMINIMIZED = 2
 
' minimiert das Fenster und aktiviert es nicht
Const SW_SHOWMINNOACTIVE = 7
 
' zeigt das Fenster an, aber aktiviert es nicht
Const SW_SHOWNA = 8
 
' zeigt das Fenster an ohne es zu aktivieren
Const SW_SHOWNOACTIVATE = 4
 
' zeigt das Fenster und aktiviert dies
Const SW_SHOWNORMAL = 1

Beispiel 2:

Private Declare Function ShellExecute Lib "shell32.dll"Alias "ShellExecuteA" ( _
  ByVal hwnd As Long, _
  ByVal lpOperation As String, _
  ByVal lpFile As String, _
  ByVal lpParameters As String, _
  ByVal lpDirectory As String, _
  ByVal nShowCmd As Long) As Long
 
Private Const SW_HIDE = 0
Private Const SW_MAXIMIZE = 3
Private Const SW_MINIMIZE = 6
Private Const SW_NORMAL = 1
Private Const SW_SHOW = 5
Private Const SW_RESTORE = 9
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_SHOWMINIMIZED = 2
Private Const SW_SHOWMINNOACTIVE = 7
Private Const SW_SHOWNA = 8
Private Const SW_SHOWNOACTIVATE = 4
Private Const SW_SHOWNORMAL = 1
 
Private Const ERROR_BAD_FORMAT = 11&
Private Const SE_ERR_ACCESSDENIED = 5
Private Const SE_ERR_ASSOCINCOMPLETE = 27
Private Const SE_ERR_DDEBUSY = 30
Private Const SE_ERR_DDEFAIL = 29
Private Const SE_ERR_DDETIMEOUT = 28
Private Const SE_ERR_DLLNOTFOUND = 32
Private Const SE_ERR_FNF = 2
Private Const SE_ERR_NOASSOC = 31
Private Const SE_ERR_OOM = 8
Private Const SE_ERR_PNF = 3
Private Const SE_ERR_SHARE = 26


Private Sub Command1_Click()
  Dim Retval As Long
 
  Retval = ShellExecute(Me.hwnd, "open", "C:\Windows\Notepad.exe", _
    "C:\AutoExeC.bat", "c:\", SW_SHOWNORMAL)
 
  ' Der gleiche Vorgang kann auch ausgeführt werden mittels...
  ' Retval = ShellExecute(Me.hwnd, "edit", "C:\AutoExeC.bat", "", "c:\", 'SW_SHOWNORMAL)
 
  Select Case Retval
    Case SE_ERR_NOASSOC
      MsgBox "Datei ist nicht Assizoiert", vbInformation, "Fehler"
      Exit Sub
    Case SE_ERR_PNF
      MsgBox "Pfad wurde nicht gefunden", vbInformation, "Fehler"
      Exit Sub
    Case SE_ERR_FNF
      MsgBox "Datei wurde nicht gefunden", vbInformation, "Fehler"
      Exit Sub
    Case 8, 26, 32, 28, 29, 30, 27, 5, 11 ' alle anderen Fehler
      Exit Sub
  End Select
End Sub

Ich habe das Ganze einmal in eine Universal-Funktion verpackt. Nachfolgenden Code am besten in ein Modul kopieren:

Option Explicit
 
' benötigte API-Deklaration
Private Declare Function ShellExecute Lib "shell32.dll" _
  Alias "ShellExecuteA" ( _
  ByVal hWnd As Long, _
  ByVal lpOperation As String, _
  ByVal lpFile As String, _
  ByVal lpParameters As String, _
  ByVal lpDirectory As String, _
  ByVal nShowCmd As Long) As Long
  
  
  ' externe Anwendung starten 
Public Function RunApp(ByVal sFile As String, _
  Optional ByVal hWnd As Long = 0, _
  Optional ByVal sParam As String = "") As Boolean
 
  Dim nResult As Long
  Dim bResult As Boolean
 
  bResult = True
 
  ' 1. Versuch: ShellExecute verwenden
  nResult = ShellExecute(hWnd, "open", sFile, sParam, "", 1)
  If nResult < 33 Then
    ' Bei Fehler, Shell-Anweisung verwenden
    On Error Resume Next
    Shell Chr$(34) & sFile & IIf(Len(sParam) > 0, " " & sParam, "") & Chr$(34), vbNormalFocus
    bResult = (Err.Number = 0)
    On Error GoTo 0
  End If
 
  RunApp = bResult
End Function

Beenden einer Anwendung

Zum beenden einer Anwendung oder eines Prozesses kann diese Funktion in Visual Basic (6.0 oder VBA) verwendet werden:

Public Sub KillProcess(NameProcess As String)
Dim RProcessFound As Long
Dim hSnapshot As Long
Dim SzExename As String
Dim ExitCode As Long
Dim MyProcess As Long
Dim AppKill As Boolean
Dim AppCount As Integer
Dim i As Integer
Dim WinDirEnv As String

       On Error GoTo h
       If NameProcess <> "" Then
          AppCount = 0

          uProcess.dwSize = Len(uProcess)
          hSnapshot = CreateToolhelpSnapshot(TH32CS_SNAPPROCESS, 0&)
          RProcessFound = ProcessFirst(hSnapshot, uProcess)

          Do
            i = InStr(1, uProcess.szexeFile, Chr(0))
            SzExename = LCase$(Left$(uProcess.szexeFile, i - 1))
            WinDirEnv = Environ("Windir") + "\"
            WinDirEnv = LCase$(WinDirEnv)

            If Right$(SzExename, Len(NameProcess)) = LCase$(NameProcess) Then
               AppCount = AppCount + 1
               MyProcess = OpenProcess(PROCESS_ALL_ACCESS, False, uProcess.th32ProcessID)
               AppKill = TerminateProcess(MyProcess, ExitCode)
               Call CloseHandle(MyProcess)
            End If
            RProcessFound = ProcessNext(hSnapshot, uProcess)
          Loop While RProcessFound
          Call CloseHandle(hSnapshot)
       End If
h:
End Sub