Kontakt
DSVGO
Historie | |
---|---|
19.12.2002 | Rückgabewert als Long definiert; Hinweis für VBA-Nutzer |
29.10.2001 | Funktion liefert nun den ExitCode des aufgerufenen Programms zurück |
30.11.2000 | Hinweis bzgl. Ausführung von DOS-Befehlen hinzugefügt |
14.10.2000 | Beispiel hinzugefügt |
??.??.1999 | Erste Version; mit Unterstützung von Mathias Schiffer |
Oft muß ein externes Programm gestartet werden (z.B. eine Batch) und auf Beendigung desselben gewartet werden, um beispielsweise auf Rückgabeergebnisse (in Form von erzeugten Dateien) zugreifen zu können.
Die VB-Funktion Shell bietet diese Möglichkeit leider nicht standardmäßig, d.h. die Programmausführung in VB wird fortgesetzt, sobald das externe Programm gestartet wurde.
Glücklicherweise kann durch API-Einsatz eine Synchronisierung erzwungen werden. Die unten gezeigte Routine erweitert die Shell-Funktion von VB u.a. um einen optionalen Parameter Events, welcher angibt, ob die VB-Anwendung auf Events reagieren soll (Voreinstellung) oder nicht (die "Vater"-Anwendung reagiert dann nicht mehr).
Das folgende Beispiel startet (bei Klick auf die Form) den Texteditor von Windows und wartet auf seine Beendigung. Erst wenn Notepad beendet wurde, geht die Programmausführung weiter: Es piept kurz, bevor das Formular sich entlädt.
Private Sub Form_Click() ShellX "notepad.exe", vbNormalFocus Beep ' :-) Unload Me End Sub
Die ShellX-Funktion liefert den ExitCode eines Programms zurück. Oft enthält dieser einen Wert ungleich Null, falls ein Fehler aufgetreten ist. Dies kann z.B. mit dem in "Programm mit ErrorLevel beenden" gezeigten Verfahren dazu benutzt werden, kleine Informationen (genauer: eine Ganzzahl) an das aufrufende Programm zu übergeben:
n = ShellX("D:\Test\BigCalc.exe 27319 98765") MsgBox "Ergebnis: " & n
Soll ein DOS-interner Befehl wie z.B. dir ausgeführt werden, so muss der Kommandozeilen-Interpreter mit dem Schalter "/c" aufgerufen werden:
Private Sub Form_Click() Dim sCmd As String Dim sShell As String sCmd = "dir > C:\Data\Test.tmp" sShell = Environ$("COMSPEC") ShellX sShell & " /c " & sCmd, vbHide End Sub
Im Deklarationsteil eines Moduls müssen folgende API-Funktionen bekanntgemacht werden:
Private Declare Function CloseHandle Lib "kernel32" ( _ ByVal hObject As Long) As Long Private Declare Function GetExitCodeProcess Lib "kernel32" ( _ ByVal hProcess As Long, lpExitCode As Long) As Long Private Declare Function OpenProcess Lib "kernel32" ( _ ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _ ByVal dwProcessId As Long) As Long
Die eigentliche Funktion erwartet (wie die VB-Funktion Shell) den Pfad zur Anwendung sowie (optional) den Fensterstil. Mit Shell wird die Anwendung wie gewünscht gestartet. Die Process-ID wird in ein Process-Handle transformiert, womit dann solange GetExitCodeProcess aufgerufen wird, bis der ExitCode nicht mehr STILL_ACTIVE ist, d.h. die Anwendung beendet wurde:
' ©2002 by Jost Schwider, http://vb-tec.de/ Public Function ShellX( _ ByVal PathName As String, _ Optional ByVal WindowStyle As VbAppWinStyle = vbMinimizedFocus, _ Optional ByVal Events As Boolean = True _ ) As Long 'Deklarationen: Const STILL_ACTIVE = &H103& Const PROCESS_QUERY_INFORMATION = &H400& Dim ProcId As Long Dim ProcHnd As Long 'Prozess-Handle holen: ProcId = Shell(PathName, WindowStyle) ProcHnd = OpenProcess(PROCESS_QUERY_INFORMATION, True, ProcId) 'Auf Prozess-Ende warten: Do If Events Then DoEvents GetExitCodeProcess ProcHnd, ShellX Loop While ShellX = STILL_ACTIVE 'Aufräumen: CloseHandle ProcHnd End Function
Tipp: Unter Office (VBA) sind die VB-Enumerationen (hier: VbAppWinStyle) nicht bekannt. Da diese intern als Long betrachtet werden, kann man die obige Deklaration (z.B. in Excel oder Word) auch so schreiben:
' ©2002 by Jost Schwider, http://vb-tec.de/ Public Function ShellX( _ ByVal PathName As String, _ Optional ByVal WindowStyle As Long = vbMinimizedFocus, _ Optional ByVal Events As Boolean = True _ ) As Long
© Jost Schwider, 30.04.2000-20.12.2002 - http://vb-tec.de/xshell.htm