Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender

Forumthread: Externes Programm mit VBA schließen

Externes Programm mit VBA schließen
Murino
Hallo und einen schönen Gruß an alle,
hätte eine große bitte, ich komme nämlich nicht weiter.
Aus Excel heraus habe ich über VBA ein externes Programm geöffnet
Private Sub Label1_Click()
Shell "be-Key.exe", 1
End Sub

Bis hierher alle klar. Könnte mir bitte Jemand einen Tipp geben, wie ich das Programm
über VBA wieder schließen könnte
Danke im Voraus
Liebe Grüße
Aki
Anzeige
AW: Externes Programm mit VBA schließen
08.03.2010 00:09:41
Josef

Hallo Aki,

'src:=http://www.vb-archiv.de/faq/faq_allg_exitprocess.html

Option Explicit

Private Declare Function CloseHandle Lib "kernel32" ( _
  ByVal hObject As Long) As Long

Private Declare Function OpenProcess Lib "kernel32" ( _
  ByVal dwDesiredAccess As Long, _
  ByVal bInheritHandle As Long, _
  ByVal dwProcessId As Long) As Long

Private Declare Function TerminateProcess Lib "kernel32" ( _
  ByVal hProcess As Long, _
  ByVal uExitCode As Long) As Long

Const PROCESS_TERMINATE = &H1

Public lTaskID As Long

Private Sub cmdTerminate_Click()
  Dim hTask As Long
  Dim lResult As Long
  hTask = OpenProcess(PROCESS_TERMINATE, 0&, lTaskID)
  lResult = TerminateProcess(hTask, 1&)
  lResult = CloseHandle(hTask)
End Sub

Private Sub Label1_Click()
  lTaskID = Shell("be-Key.exe", 1)
End Sub


Gruß Sepp

Anzeige
AW: Externes Programm mit VBA schließen
08.03.2010 00:52:36
Jens
siehe mal den Kill - Befehl an !
AW: Externes Programm mit VBA schließen
08.03.2010 12:27:46
Murino
Hallo Sepp
Vielen Dank für die schnelle Hilfe. Leider bekomme ich ein Debbug und bekomme das Programm weder auf, noch zu!. Als Beisp. habe ich es mal mit „wordpad.exe“ probiert.
Außerdem verstehe ich nicht, wie das Makro verstehen kann dass das Programm „wordpad.exe“ geschlossen werden soll. Ich kenne mich leider sehr wenig aus, was soll ich mit "Option Explicit machen".
**********************************************************************************
Option Explicit
Private Declare Function CloseHandle Lib "kernel32" ( _
ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function TerminateProcess Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal uExitCode As Long) As Long
Const PROCESS_TERMINATE = &H1
Public lTaskID As Long
Private Sub cmdTerminate_Click()
Dim hTask As Long
Dim lResult As Long
hTask = OpenProcess(PROCESS_TERMINATE, 0&, lTaskID)
lResult = TerminateProcess(hTask, 1&)
lResult = CloseHandle(hTask)
End Sub

Private Sub Label1_Click()
lTaskID = Shell("wordpad.exe", 1)
End Sub
Vielen Dank
Gruß Aki
Anzeige
AW: Externes Programm mit VBA schließen
08.03.2010 12:40:34
Josef

Hallo Aki,
mit "Option Explicit" brauchst du gar nichts machen, ausser es einfach so stehen lassen, schau in die Hilfe, um zu verstehen was es bedeutet.
"Außerdem verstehe ich nicht, wie das Makro verstehen kann dass das Programm „wordpad.exe“ geschlossen werden soll."
Beim öffnen wird die TaskID ermittelt und mit genau dieser kann man das Programm wieder schliessen.
Zu deinem Programm musst du den kompletten Pfad angeben (z.B.: "C:\Ordner\Programm.exe")

Gruß Sepp

Anzeige
AW: Externes Programm mit VBA schließen
08.03.2010 12:43:18
Renee
Hi Aki,
Bei welcher Zeile bleibt der Debugger stehen?
Ich vermute mal bei der Shell-Zeile, denn da fehlt die Angabe in welchem Verzeichnis das Wordpad.exe steht.
Das Makro merkt sich die eindeutige TaskId (über eine globale Variable) und schliesst darum auch automatisch wieder die richtige Applikation.
GreetZ Renée
Anzeige
AW: Externes Programm mit VBA schließen
08.03.2010 13:19:02
Murino
Vielen Dank auch an dich Renée für die Aufklärung, du hast recht es war ein kleine Fehler drin. Dennoch besteht noch ein Problem!!
Das Programm (übrigens eine Virtuelle Tastatur) wird einwandfrei minimiert, was auch richtig ist, nur beim erneuten Start wird es nicht maximiert, sondern ein zweites Mal gestartet. Das bedeutet dass bei 10X starten, 10X das Programm in der Taskleiste vorhanden ist.
Wahrscheinlich sollte der Befehl statt „neu starten“ besser „Maximieren lauten“.
Sorry, leider bekomme ich das nicht hin. Wäre wirklich sehr nett wenn Ihr noch mal helfen könntet.
Nochmals vielen Dank
Gruß
Aki
Private Sub cmdTerminate_Click()
Dim hTask As Long
Dim lResult As Long
hTask = OpenProcess(PROCESS_TERMINATE, 0&, lTaskID)
lResult = TerminateProcess(hTask, 1&)
lResult = CloseHandle(hTask)
End Sub
Private Sub Label1_Click()
lTaskID = Shell("C:\Programme\be-Key\be-key.exe", 1)
End Sub

Anzeige
10 x starten = 10 x schliessen!
08.03.2010 13:34:02
Renee
Hi Aki,
Ich versteh nicht was du da zusammenbastelst!
Der vorgeschlagene Code beruht auf dem Prinzip 1 Applikation zu starten (Label1_Click) und anschliessend (via cmdTerminate_Click) wieder zu schliessen. Von minimieren war bis jetzt nicht die Rede und er Code macht auch nichts in der Richtung. Falls du eine Applikation 10 x startest, müsste sich der Code 10 ID's merken und dann auch wissen, unter welchen Bedingungen er welche dieser ID's er wieder schliessen soll! Dafür ist der vorliegende Code eindeutig nicht vorgesehen.
Also definierst du am Besten nochmals deine Anforderungen, so genau und vollständig wie möglich.
GreetZ Renée
Anzeige
AW: 10 x starten = 10 x schliessen!
08.03.2010 14:10:45
Murino
entschuldige Renée, keine Ahnung warum das Programm nicht beendet wurde.
Habe neu gebootet Jetzt funktioniert es jedenfalls, vielen dank für deine große Hilfe.
Jetzt habe ich mir natürlich ein Wurm ins Ohr gesetzt. An eine Minimierung und Maximierung hatte
ich überhaupt nicht gedacht, für eine Virtuelle Tast. wäre das allerdings die optimale Lösung.
Falls du noch den Nerv hast mir eine Lösung zu geben wäre sehr Nobel von dir,
ansonsten auch Ok kann mit der jetzigen Möglichkeit leben.
Nochmals vielen Dank.
Wünsche dir alles gute.
Aki
Anzeige
AW: 10 x starten = 10 x schliessen!
08.03.2010 15:34:38
Josef

Hallo Aki,
Label1_Click startet die Awendung und stellt, wenn die Anwendung schon läuft, das Fenster wieder her.
cmdMinimize_Click minimiert die Anwendung, cmdTerminate_Click beendet die Anwendung.

' **********************************************************************
' Modul: Modul2 Typ: Allgemeines Modul
' **********************************************************************

Option Explicit

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As _
  Long

Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As _
  Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long

Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As _
  Long, ByVal uExitCode As Long) As Long

Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal _
  nCmdShow As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal _
  lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As _
  Long, lpdwProcessId As Long) As Long

Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd _
  As Long) As Long

Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long

Private Const PROCESS_TERMINATE = &H1
Private Const GW_HWNDNEXT As Long = &H2
Private Const SW_MINIMIZE = &H6
Private Const SW_RESTORE = &H9

Public lTaskID As Long
Public hWnd As Long
Private Retval As Long

Private Function ShellTohWnd(ByVal hhwPfad As String, Optional Mode As VbAppWinStyle)
  Dim ProcHWN As Long
  
  lTaskID = Shell(hhwPfad, Mode)
  
  Retval = FindWindow(vbNullString, vbNullString)
  Do While Retval <> 0
    If GetParent(Retval) = 0 Then
      Call GetWindowThreadProcessId(Retval, ProcHWN)
      
      If ProcHWN = lTaskID Then
        ShellTohWnd = Retval
        Exit Do
      End If
    End If
    
    Retval = GetWindow(Retval, GW_HWNDNEXT)
  Loop
End Function

Private Sub cmdTerminate_Click()
  Dim hTask As Long
  Dim lResult As Long
  If lTaskID > 0 Then
    hTask = OpenProcess(PROCESS_TERMINATE, 0&, lTaskID)
    lResult = TerminateProcess(hTask, 1&)
    lResult = CloseHandle(hTask)
    lTaskID = 0
    hWnd = 0
  End If
End Sub

Private Sub cmdMinimize_Click()
  Dim lResult As Long
  If lTaskID > 0 Then lResult = ShowWindow(hWnd, SW_MINIMIZE)
End Sub

Private Sub Label1_Click()
  Dim lResult As Long
  If lTaskID = 0 Then
    hWnd = ShellTohWnd("c:\windows\notepad.exe", vbNormalNoFocus)
  Else
    lResult = ShowWindow(hWnd, SW_RESTORE)
  End If
End Sub

Gruß Sepp

Anzeige
AW: 10 x starten = 10 x schliessen!
08.03.2010 16:11:56
Murino
Uuuuuuunglaublich!!
Ich bin begeistert. Ich weis nicht wie ich euch danken soll.
Es funktioniert ganz fantastisch.
vielen vielen Dank
Nochmal alles Gute
Liebe Grüße
Aki
AW: Externes Programm mit VBA schließen
08.03.2010 00:58:18
Jens
Sorry, Sorry.
Der Kill - Befehl geht da natürlich nicht. Der löscht.........
AW: Externes Programm mit VBA schließen
08.03.2010 01:04:57
Jens
Habe mal recheriert, Villiecht hilft Dir das.
siehe Link:
http://vb-tec.de/xshell.htm
Anzeige
;
Anzeige
Anzeige

Infobox / Tutorial

Externes Programm mit VBA schließen


Schritt-für-Schritt-Anleitung

Um ein externes Programm über VBA zu schließen, kannst du die folgenden Schritte ausführen:

  1. Öffne das VBA-Editor-Fenster in Excel, indem du Alt + F11 drückst.

  2. Erstelle ein neues Modul:

    • Klicke mit der rechten Maustaste auf das Projekt im Projektfenster.
    • Wähle „Einfügen“ > „Modul“.
  3. Füge den folgenden Code in das Modul ein:

    Option Explicit
    
    Private Declare Function CloseHandle Lib "kernel32" ( _
       ByVal hObject As Long) As Long
    Private Declare Function OpenProcess Lib "kernel32" ( _
       ByVal dwDesiredAccess As Long, _
       ByVal bInheritHandle As Long, _
       ByVal dwProcessId As Long) As Long
    Private Declare Function TerminateProcess Lib "kernel32" ( _
       ByVal hProcess As Long, _
       ByVal uExitCode As Long) As Long
    
    Const PROCESS_TERMINATE = &H1
    Public lTaskID As Long
    
    Private Sub cmdTerminate_Click()
       Dim hTask As Long
       Dim lResult As Long
       hTask = OpenProcess(PROCESS_TERMINATE, 0, lTaskID)
       lResult = TerminateProcess(hTask, 1)
       lResult = CloseHandle(hTask)
    End Sub
    
    Private Sub Label1_Click()
       lTaskID = Shell("C:\Programme\be-Key\be-key.exe", 1)
    End Sub
  4. Starte das Programm über die Label1_Click-Prozedur.

  5. Schließe das Programm über die cmdTerminate_Click-Prozedur.


Häufige Fehler und Lösungen

  • Fehler: „Debug-Fehler“ beim Starten des Programms
    Lösung: Stelle sicher, dass der Pfad zur EXE-Datei korrekt angegeben ist. Nutze den vollständigen Pfad, z.B. C:\Programme\be-Key\be-key.exe.

  • Fehler: Program schließt nicht richtig
    Lösung: Überprüfe, ob die lTaskID korrekt gesetzt ist. Wenn der Prozess nicht mehr existiert, kann das Programm nicht geschlossen werden.

  • Fehler: Mehrere Instanzen des Programms starten
    Lösung: Stelle sicher, dass das Programm durch die Shell-Funktion nicht mehrfach gestartet wird. Nutze die ShowWindow-Funktion, um die Anwendung bei Bedarf zu maximieren.


Alternative Methoden

  1. Kill-Befehl in VBA: Du kannst auch den Kill-Befehl verwenden, um ein Programm zu schließen, wenn du den Prozessnamen kennst:

    Shell "taskkill /F /IM be-Key.exe", vbHide
  2. Benutzung von WMI: Mit Windows Management Instrumentation (WMI) kannst du Prozesse gezielt ansprechen und beenden:

    Dim objWMI As Object
    Set objWMI = GetObject("winmgmts:\\.\root\cimv2")
    Dim colItems As Object
    Set colItems = objWMI.ExecQuery("SELECT * FROM Win32_Process WHERE Name='be-Key.exe'")
    For Each objItem In colItems
       objItem.Terminate
    Next

Praktische Beispiele

  • Beispiel 1: Schließen von Notepad

    Private Sub CloseNotepad()
       lTaskID = Shell("notepad.exe", vbNormalFocus)
       ' Logik zum Schließen hier hinzufügen
    End Sub
  • Beispiel 2: Maximieren von Wordpad

    Private Sub MaximizeWordpad()
       lTaskID = Shell("wordpad.exe", vbNormalFocus)
       ' Maximierungslogik hier hinzufügen
    End Sub

Tipps für Profis

  • Verwende Option Explicit: Dies hilft, Fehler durch nicht deklarierte Variablen zu vermeiden und macht den Code leichter lesbar.
  • Globale Variablen: Nutze globale Variablen für die lTaskID, um den aktuellen Prozess über verschiedene Subroutinen hinweg zu verfolgen.
  • Error Handling: Implementiere Fehlerbehandlung, um die Robustheit deines Codes zu erhöhen:
    On Error Resume Next
    ' Dein Code hier
    If Err.Number <> 0 Then
      MsgBox "Fehler: " & Err.Description
    End If

FAQ: Häufige Fragen

1. Frage
Wie kann ich das Programm schließen, ohne es zu beenden?
Antwort: Du kannst die ShowWindow-Funktion verwenden, um das Fenster zu minimieren oder wiederherzustellen, anstatt es zu beenden.

2. Frage
Was ist OpenProcess und wie funktioniert es?
Antwort: OpenProcess ist eine Funktion, die es dir ermöglicht, einen Handle auf einen laufenden Prozess zu erhalten, um damit Operationen wie das Beenden des Prozesses durchzuführen.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige