Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0124: Beliebigen Task ermitteln und terminieren

 von 

Beschreibung 

Dieser Tip baut auf dem letzten auf und erweitert ihn um die Möglichkeit nach Belieben Task zu terminieren.

Achtung: Dieser Weg lässt der Anwendung keine Zeit, Dateien zu speichern oder Objekte zu entladen. Er sollte nur verwendet werden, wenn die Anwendung auf keinen konventionellen Weg mehr zu beenden ist.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

CloseHandle, GetDesktopWindow, GetParent, GetWindow, GetWindowLongA (GetWindowLong), GetWindowTextA (GetWindowText), GetWindowTextLengthA (GetWindowTextLength), GetWindowThreadProcessId, OpenProcess, TerminateProcess

Download:

Download des Beispielprojektes [3,12 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Project1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Schaltfläche "Command1"
' Steuerelement: Schaltfläche "Command2"
' Steuerelement: Kontrollkästchen-Steuerelement "Check1"
' Steuerelement: Listen-Steuerelement "List1" (Index von 0 bis 2)
' Steuerelement: Optionsfeld-Steuerelement "Option2"
' Steuerelement: Optionsfeld-Steuerelement "Option1"
' Steuerelement: Beschriftungsfeld "Label3"
' Steuerelement: Beschriftungsfeld "Label2"
' Steuerelement: Beschriftungsfeld "Label1"

Option Explicit

Private Declare Function GetDesktopWindow Lib "user32" () _
        As Long

Private Declare Function GetWindow Lib "user32" (ByVal hWnd _
        As Long, ByVal wCmd As Long) As Long
        
Private Declare Function GetWindowLong Lib "user32" Alias _
        "GetWindowLongA" (ByVal hWnd As Long, ByVal wIndx As _
        Long) As Long
        
Private Declare Function GetWindowTextLength Lib "user32" _
        Alias "GetWindowTextLengthA" (ByVal hWnd As Long) _
        As Long
        
Private Declare Function GetWindowText Lib "user32" Alias _
        "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString _
        As String, ByVal cch As Long) As Long
               
Private Declare Function GetParent Lib "user32" (ByVal hWnd _
        As Long) As Long
        
Private Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hWnd As Long, lpdwProcessId As Long) As Long
        
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 GW_HWNDFIRST = 0
Const GW_HWNDLAST = 1
Const GW_HWNDNEXT = 2
Const GW_HWNDPREV = 3
Const GW_OWNER = 4
Const GW_CHILD = 5
Const GW_MAX = 5

Const GWL_STYLE = (-16)

Const WS_VISIBLE = &H10000000
Const WS_BORDER = &H800000

Const PROCESS_TERMINATE = &H1

Private Sub Check1_Click()
  Call EnumWindows
End Sub

Private Sub Command1_Click()
  Call EnumWindows
End Sub

Private Sub Command2_Click()
  Dim Result&, Task&
    
    If List1(2).ListIndex > -1 Then
      Result = CLng(List1(2).List(List1(2).ListIndex))
     
      Task = OpenProcess(PROCESS_TERMINATE, 0&, Result)
      Result = TerminateProcess(Task, 1&)
      Result = CloseHandle(Task)
    End If
End Sub

Private Sub Form_Load()
  Call EnumWindows
End Sub

Private Sub List1_Click(Index As Integer)
  Static Flag, x%
    If Flag Then Exit Sub
    Flag = True
    For x = 0 To List1.UBound
      List1(x).ListIndex = List1(Index).ListIndex
      List1(x).TopIndex = List1(Index).TopIndex
    Next x
    Flag = False
End Sub

Private Sub EnumWindows()
  Dim hWnd&
  
    List1(0).Clear
    List1(1).Clear
    List1(2).Clear
    
    'Auch der Desktop ist ein Fenster
    hWnd = GetDesktopWindow
    Call GetWindowInfo(hWnd)
    
    'Einstieg
    hWnd = GetWindow(Me.hWnd, GW_HWNDFIRST)
    
    'Alle vorhandenen Fenster abklappern
    Do
      Call GetWindowInfo(hWnd)
      hWnd = GetWindow(hWnd, GW_HWNDNEXT)
    Loop Until hWnd = 0
End Sub

Private Sub GetWindowInfo(ByVal hWnd&)
  Dim Parent&, Task&, Result&, x&, Style&, Title$
  
    'Darstellung des Fensters
    Style = GetWindowLong(hWnd, GWL_STYLE)
    Style = Style And (WS_VISIBLE Or WS_BORDER)
            
    'Title des Fenster auslesen
    Result = GetWindowTextLength(hWnd) + 1
    Title = Space$(Result)
    Result = GetWindowText(hWnd, Title, Result)
    Title = Left$(Title, Len(Title) - 1)
    
    'In Abhängigkeit der Optionen die Ausgabe erstellen
    If (Title <> "" Or (Check1.Value = vbChecked)) And _
       (Style = (WS_VISIBLE Or WS_BORDER) Or Option2.Value) Then
       
      List1(0).AddItem CStr(hWnd)
      List1(1).AddItem Title
      
      'Elternfenster ermitteln
      Parent = hWnd
      Do
        Parent = GetParent(Parent)
      Loop Until Parent = 0
      
      'Task Id ermitteln
      Result = GetWindowThreadProcessId(hWnd, Task)
      List1(2).AddItem Task
    End If
End Sub

Private Sub Option1_Click()
  Call EnumWindows
End Sub

Private Sub Option2_Click()
  Call EnumWindows
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Project1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 11 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Dirk am 16.11.2007 um 03:42

Ist mal jemand aufgefallen, dass die Task-IDs, die dieser Tipp liefert in der Liste aus Tipp 273 gar nicht auftauchen?

Da fehlt anscheinend noch ein Zwischenschritt, der aus der aus der "WindowThread"-ID die tatsächliche Process-ID macht.

Ist jetzt sehr ärgerlich für mich, weil ich so den Prozessen die Fenster nicht zuordnen kann. Ich weiß, dass der Tipp nicht mehr der Jüngste ist, aber vielleicht schaut ja mal einer vom ActiveVB-Team zufällig hier rein und weiß da Hilfe ;-)

Kommentar von Konrad L. M. Rudolph am 28.03.2005 um 02:00

@Hans: Na, das ist doch logisch. Wenn Du den Explorer beendest, beendet er sich nun mal. Der Desktop ist Teil des Explorers bzw. er ist ein Explorer-Prozess.

Kommentar von Hans Louis Ineichen am 04.03.2005 um 18:09

Ich habe soeben festgestellt, dass der um 17:47 beschriebene Effekt nur beim Terminieren des Microsoft Explorers auftritt. Wieso das?

Kommentar von Hans Louis Ineichen am 04.03.2005 um 17:47

Tipp 0124: Beliebigen Task ermitteln und terminieren
Der Code funktioniert mit VB6/Windows XP an und für sich aber er löscht den kompletten Desktop und die Taskleiste. Anschliessend im Code mit Shell Explorer starten, bringt Desktop und Taskleiste zurück, aber das kann ja nicht die Lösung sein. Wie kann das Problem besser gelöst werden?

Kommentar von Franz-Josef Huth am 11.01.2004 um 16:31

Ich möchte gerne das Programm ohne Formular anwenden. Leider bekomme ich keinen Eingang da der Me. abgewiesen wird.
Mir geht es eigentlich darum festszstellen welche ID eine bestimmte Task hat um ihr dan über sendkeys Daten zu schicken.
Hat jemand da einen Hinweis ?

vielen Dank

Franz-Josef Huth

Kommentar von FM am 17.12.2003 um 14:24

Beispiel ok, jedoch wird der Serverprozess nicht beendet.
TerminateProcess + CloseHandle reichen dafür so nicht aus.

Kommentar von Stefan am 19.04.2003 um 14:02

hallo, super source doch ist er für mich leicht zu hoch da ich nochnicht lange progge :/
kann man das nicht in ein modul packen und einfach mit
TerminatePrg "easyChat server@1000"
irgendwie machen?

Kommentar von Dodger am 28.02.2003 um 14:02

Das gesamte Program kann mn runterladen, wenn man auf die Diskette auf der linken Seite unterhalb des gezeigten Quellcodes clickt.

Wenn man sich das Formular ansieht, merkt man dann auch, weshalb es bei euch nicht geklapt hat.

@Autor des Quellcodes
Super Arbeit! Dieses Beispiel hat mich weiter gebracht.
Allerdings wäre für den Laien(wie mich) etwas mehr Kommentar besser.
Schließlich will ich mehr als nur Copy&Paste.
Trotzdem vielen Dank!

Kommentar von AJ am 27.02.2003 um 22:39

Ich würde das tool ja gerne einsetzen .. aber wie die Vorgänger auch schon bemerkten funktioniert das so nicht. Ich vermute zu dem VBA code fehlt noch das entsprechende Formular ??? Wie komm ich da ran .... ??

Kommentar von Rudolf Lanneshausen am 26.06.2001 um 07:17

Das gleiche Problem wie big_sexy@web.de habe ich leider auch (unter VB 6, Windows98). Hat sich da eine Lösung gefunden?
Rudolf

Kommentar von C-DOGG am 27.05.2001 um 23:45

bei mir kommt immer eine fehlermeldung das etwas nicht stimmt mit
Private Sub List1_Click(Index As Integer)
kannst du mir helfen?
MFG
C-DOGG