Window State eines extern Prozesses ermitteln

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von Westerwälder.

    Window State eines extern Prozesses ermitteln

    Hallo zusammen,
    Google schon den halben Tag, finde aber nicht wirklich eine Lösung.
    Zeige einfach mal den Code

    VB.NET-Quellcode

    1. For Each oProcess As Process In Process.GetProcesses ' Erfassen der nun aktiven Prozesse
    2. Me.ListAktiveProzesse_Aktuell.Add(oProcess.ProcessName.ToString)
    3. If Not oProcess.MainWindowTitle.ToString = Nothing Then
    4. ' Hier:
    5. ' Wenn Prozess minimiert, Prozess beenden
    6. End If
    7. Next
    Gruß Markus
    Habe den Beitrag auch schon gelesen. Unten drunter steht:

    Das ganze lässt sich jetzt auf jedes Window anwenden. Um nun den Status eines externen Windows abzufragen, musst das Windowhandle bekannt sein. Dieses kann ggf. über die FindWindow-API ermittelt werden.

    Also werde ich mit diesem Code nicht hin kommen.
    Denke es gibt doch sicherlich in Net was neues um dieses auszulesen. Oder?
    Gruß Markus

    Westerwälder schrieb:

    Also werde ich mit diesem Code nicht hin kommen.
    Denke es gibt doch sicherlich in Net was neues um dieses auszulesen. Oder?
    Nö gibt es nicht.
    Außerdem weshalb solltest du damit nicht weit kommen? a) kannst du die FindWindow Funktion auch in .net finden und b) hast du schon das Fensterhandle oProcess.MainWindowHandle.


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    japp, mit find window oder mit dem Hanwndl des Proccesses. Wenn du ein Bestimmtest fenster suchst, kannst du auch in meiner Signatur mal auf MySpy Klicken :)
    Meine Projekte Genesis Game Engine | GFX | smartli.me - Der smarte URL shortener

    Habe nun die beiden Funktionen in mein Programm übernommen (Long gegen Integer ausgetauscht)

    VB.NET-Quellcode

    1. Private Declare Function GetWindowPlacement Lib "user32" (ByVal hWnd As Integer, lpwndpl As WINDOWPLACEMENT) As Integer
    2. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
    3. Private nState As SW_CMD
    4. Private Structure RECT
    5. Public Left As Integer
    6. Public Top As Integer
    7. Public Right As Integer
    8. Public Bottom As Integer
    9. End Structure
    10. Private Structure POINTAPI
    11. Public X As Integer
    12. Public Y As Long
    13. End Structure
    14. Private Structure WINDOWPLACEMENT
    15. Public Length As Integer
    16. Public flags As Integer
    17. Public showCmd As Integer
    18. Public ptMinPosition As POINTAPI
    19. Public ptMaxPosition As POINTAPI
    20. Public rcNormalPosition As RECT
    21. End Structure
    22. Public Enum SW_CMD
    23. SW_HIDE = 0
    24. SW_SHOWNORMAL = 1
    25. SW_SHOWMINIMIZED = 2
    26. SW_SHOWMAXIMIZED = 3
    27. SW_SHOWNOACTIVATE = 4
    28. SW_SHOW = 5
    29. SW_MINIMIZE = 6
    30. SW_SHOWMINNOACTIVE = 7
    31. SW_SHOWNA = 8
    32. SW_RESTORE = 9
    33. End Enum
    34. Public Function GetWindowState(ByVal hWnd As Integer) As SW_CMD
    35. Dim W As WINDOWPLACEMENT
    36. If GetWindowPlacement(hWnd, W) = 0 Then
    37. ' Fehler! Evtl. wurde kein Window mit dem
    38. ' angegebenen Handle gefunden
    39. GetWindowState = -1
    40. Else
    41. ' Fensterstatus zurückgeben
    42. GetWindowState = W.showCmd
    43. End If
    44. End Function


    Hier dann der Auftruf

    VB.NET-Quellcode

    1. If Not oProcess.MainWindowTitle.ToString = Nothing Then
    2. ' Hier Prozess auf minimiert prüfen und eventuell beenden
    3. Dim Handle As Integer = FindWindow(Nothing, oProcess.MainWindowTitle.ToString)
    4. If Not Handle = 0 Then ' Fenster gefunden
    5. nState = GetWindowState(Handle)
    6. Select Case nState
    7. Case SW_CMD.SW_HIDE
    8. MsgBox("Fenster ist hidden")
    9. Case SW_CMD.SW_SHOWMAXIMIZED
    10. MsgBox("Fenster ist maximiert")
    11. Case SW_CMD.SW_SHOWMINIMIZED
    12. MsgBox("Fenster is minimiert")
    13. Case SW_CMD.SW_SHOWNORMAL
    14. MsgBox("Fenster wird normal angezeigt")
    15. End Select
    16. End If
    17. End If


    Fehler:

    Ein Aufruf an die PInvoke-Funktion "MBPRGM!MBPRGM.MBMaxmodus::GetWindowPlacement" hat das Gleichgewicht des Stapels gestört. Wahrscheinlich stimmt die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur überein. Überprüfen Sie, ob die Aufrufkonvention und die Parameter der PInvoke-Signatur mit der nicht verwalteten Zielsignatur übereinstimmen.
    Gruß Markus
    Nochmal: Du brauchst das FindWindow nicht. Das Handle des Hauptfensters des Prozesses hast du schon.

    thefiloe schrieb:

    b) hast du schon das Fensterhandle oProcess.MainWindowHandle.
    Da -> MainWindowHandle (nicht MainWindowTitle) sondern Handle.

    Zu deinem Fehler:
    Ich gehe davon aus, dass du ein x64 System hast. Auf einem 64 bit System sind Zeiger 64 bit groß. Auf einem 32 bit System sind diese 32 bit groß.
    hWnd ist ein Zeiger. Du verwendest jedoch standardmäßig immer einen 32bit Integer. Wenn du jetzt ein 64 bit System hast, dann geht das verständlicher weise nicht.
    Deshalb gibt es für Zeiger in .NET den Datentyp IntPtr.
    Somit gibt FindWindow keinen Integer sondern einen IntPtr zurück, GetWindowPlacement hat beim ersten Parameter nicht hWnd As Integer sondern hWnd As IntPtr(das Gleiche gilt auch für GetWindowState).
    Nebenbei bemerkt, bin ich mir fast sicher, dass bei POINTAPI das Y auch ein Integer und kein Long ist :).


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.
    Danke für Deine Mühe.
    Mein Betriebssystem: Windows 7 - 32 bit

    Geändert habe ich nun:

    VB.NET-Quellcode

    1. Private Declare Function GetWindowPlacement Lib "user32" (ByVal hWnd As IntPtr, lpwndpl As WINDOWPLACEMENT) As IntPtr
    2. Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    3. Private Structure POINTAPI
    4. Public X As Integer
    5. Public Y As Integer
    6. End Structure
    7. Public Function GetWindowState(ByVal hWnd As IntPtr) As SW_CMD
    8. Dim W As WINDOWPLACEMENT
    9. If GetWindowPlacement(hWnd, W) = 0 Then
    10. ' Fehler! Evtl. wurde kein Window mit dem
    11. ' angegebenen Handle gefunden
    12. GetWindowState = -1
    13. Else
    14. ' Fensterstatus zurückgeben
    15. GetWindowState = W.showCmd
    16. End If
    17. End Function
    18. For Each oProcess As Process In Process.GetProcesses ' Erfassen der nun aktiven Prozesse
    19. Me.ListAktiveProzesse_Aktuell.Add(oProcess.ProcessName.ToString)
    20. If Not oProcess.MainWindowTitle.ToString = Nothing Then
    21. nState = GetWindowState(oProcess.MainWindowHandle)
    22. Select Case nState
    23. Case SW_CMD.SW_HIDE
    24. MsgBox("Fenster ist hidden")
    25. Case SW_CMD.SW_SHOWMAXIMIZED
    26. MsgBox("Fenster ist maximiert")
    27. Case SW_CMD.SW_SHOWMINIMIZED
    28. MsgBox("Fenster is minimiert")
    29. Case SW_CMD.SW_SHOWNORMAL
    30. MsgBox("Fenster wird normal angezeigt")
    31. End Select
    32. End If
    33. Next


    Der Fehler bleibt weiterhin der gleiche.
    Kann es sein, dass die Funktionen falsch aus VB 6 übernommen wurden?
    Gruß Markus
    Ok ich habe mir jetzt mal die Funktion selbst angeschaut. Und die Signatur stimmt von vorne bis hinten nicht. Es fängt damit an, dass GetWindowPlacement einen Boolean zurück gibt.

    Zum anderen ist der zweite Parameter nicht nur ein Parameter sondern eine Referenz, die einen anderen Wert bekommen soll.
    Also probiere folgendes:

    VB.NET-Quellcode

    1. Private Declare Function GetWindowPlacement Lib "user32" (ByVal hWnd As IntPtr, ByRef lpwndpl As WINDOWPLACEMENT) As Boolean



    Zudem steht auf msdn:
    Before calling GetWindowPlacement, set the length member to sizeof(WINDOWPLACEMENT).GetWindowPlacement fails if lpwndpl-> length is not set correctly.

    VB.NET-Quellcode

    1. Public Function GetWindowState(ByVal hWnd As IntPtr) As SW_CMD Dim W As New WINDOWPLACEMENT
    2. W.length = Marshal.SizeOf(W)
    3. If GetWindowPlacement(hWnd, W) = 0 Then
    4. ' Fehler! Evtl. wurde kein Window mit dem
    5. ' angegebenen Handle gefunden
    6. Return (SW_CMD)-1
    7. Else
    8. ' Fensterstatus zurückgeben
    9. Return (SW_CMD)W.showCmd
    10. End If
    11. End Function


    Opensource Audio-Bibliothek auf github: KLICK, im Showroom oder auf NuGet.