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