uroveits
Goto Top

Windows XP - Systray-Leiste automatisch aktualisieren

Hallo !

Meine Frage bzw. Problem bezieht sich auf die Systray-Leiste (für Windows XP). Mein Problem ist folgendes:
Ich habe eine Batch-Datei bzw. ein VB-Skript erstellt, dass einen Prozess (d.h. Programm) beendet und nach Abarbeitung bestimmter Punkte diesen Prozess wieder aufruft.
Danach erscheint das Symbol für diesen Prozess zweimal im Systray:
1. Mal: "altes" Symbol wird nach Beenden des Prozeesse nicht gelöscht.
2. Mal: Starten des Prozesses.
Wenn ich nun die Systray-Leiste mit der Maus komplett anzeigen lasse, verschwinden die zwei Symbole und es bleibt nur ein (1) Symbol übrig.
Ich möchte nun wissen, ob es eine Möglichkeit gibt, dass die Systray-Leiste automatisch aktualisiert wird (ohne dass ich mit der Maus "ran" muss).


Folgendes VB-Skript verwende ich:
Dim oWMI, sQuery, Proz, Task
On Error Resume Next
Set oWMI = GetObject("winmgmts:{impersonationLevel=impersonate,(debug)}")  
sQuery = "select * from win32_process where name = '" & "<Programm>" & "'"  
Set Task = oWMI.ExecQuery(sQuery)
For Each Proz In Task
Proz.Terminate 0
Next
Vielen Dank im Voraus.

Content-ID: 76929

Url: https://administrator.de/contentid/76929

Ausgedruckt am: 20.11.2024 um 08:11 Uhr

misterdemeanor
misterdemeanor 04.01.2008 um 14:52:16 Uhr
Goto Top
Grüß Dich,

also mit Win Boardmitteln fällt mir da leider auch nichts ein. Bzw. eben nur über die Win-Api, also eine kleine .Exe proggen die Du dann aus Deinem Skript aufrufst.

Exe sollte schnell getippt sein:

Finden des "SysPager" Handles und ein UpdateWindow Aufruf.

Aber vielleicht kennt ja doch jemand eine bessere Methode...viell. in Richtung Shell...

bg, Felix -misterdemeanor-
uroveits
uroveits 04.01.2008 um 15:39:30 Uhr
Goto Top
Hallo Felix,

erst einmal vielen Dank für Deinen Vorschlag.
Exe sollte schnell getippt sein:
Finden des "SysPager" Handles und ein UpdateWindow Aufruf.
Leider kann ich mit der Information auf UpdateWindow nichts anfangen, da ich von den dort besprochenen Punkten keine Ahnung habe. Ich möchte daher anfragen, ob Du Deinen Vorschlag hier darstellen könntest.

Gruß

uroveits
misterdemeanor
misterdemeanor 04.01.2008 um 15:55:28 Uhr
Goto Top
Hi,

bei "UpdateWindow" handelt es sich um eine API-32 Funktion die das neuzeichnen eines /Bereiches/ bewirkt. In deinem Fall wäre dieser /Bereich/ eben der /Systray/. Um diesen zu "finden" wäre ein voriger Aufruf einer anderen API-Funktion nötig : FindWindow(...) .

Dummerweise lassen sich API-Funktionen nicht aus einem /Skript/ heraus aufrufen, deswegen müsstest Du mit einer Programmiersprache die kompilierte .Exe Dateien erstellen kann und WIN-32 APi kompatibel ist diesen Zwischenweg einschlagen.

Jetzt weiß ich nicht welche Programiersprache(n) Dir zu Verfügung stehen, kostenlos aber eher Overkill wäre da eine /.Net/ Sprache. Persönlich würde ich das schnell in VB6 tippen, steht mir momentan aber nicht zur Verfügung...
uroveits
uroveits 04.01.2008 um 16:20:22 Uhr
Goto Top
Hallo Felix,

Overkill wäre da eine /.Net/ Sprache.
Overkill kenne ich nicht. Einarbeitungszeit rechtfertigt nicht den Benefit.

Persönlich würde ich das schnell in VB6 tippen
Klingt gut. Aber ich verstehe zum einen nicht, warum dies funktionieren sollte. Du hast doch weiter oben gesagt:
Dummerweise lassen sich API-Funktionen nicht aus einem /Skript/ heraus aufrufen
Ist das kein Widerspruch ?
Oder willst Du das von Dir vorgeschlagene Skript kompilieren und als exe-Datei in mein Skript einbinden ?

Zum anderen hätte ich gerne gewußt, was Du in VB6 eintrippen würdest. Vielleicht kannst Du dies bei Gelegenheit posten. Oder noch besser: exe-Datei mailen.

Danke

uroveits
misterdemeanor
misterdemeanor 06.01.2008 um 20:46:27 Uhr
Goto Top
Hallo Felix,

Hallo uroveits,

>> Overkill wäre da eine /.Net/ Sprache.

Overkill kenne ich nicht. Einarbeitungszeit
rechtfertigt nicht den Benefit.

eben.

>> Persönlich würde ich das schnell in VB6 tippen

Klingt gut. Aber ich verstehe zum einen
nicht, warum dies funktionieren sollte. Du
hast doch weiter oben gesagt:
>> Dummerweise lassen sich API-Funktionen nicht aus einem /Skript/ heraus aufrufen

deswegen (zB) in Visual Basic 6 eine Exe erstellen. VB6 hat mit VBS (direkt) nichts zu tun. Natürlich Syntax-mäßig praktisch identisch aber eben eine Programmiersprache.

Ist das kein Widerspruch ?

^^Nein.

Oder willst Du das von Dir vorgeschlagene
Skript kompilieren und als exe-Datei in mein
Skript einbinden ?

Wie im ersten Post geschrieben: Exe kompilieren (in zB VB6) und aus dem Skript heraus aufrufen.,


Zum anderen hätte ich gerne
gewußt, was Du in VB6 eintrippen
würdest. Vielleicht kannst Du dies bei
Gelegenheit posten.

So, mit meinem Vorschlag der API-Funktion UpdateWindow(...) funktioniert es ohnehin nicht. Windows scheint in dem /Systray/ tatsächlich nur auf Mausereignisse zu reagieren. Aber mit API lässt sich ja auch dies programmtechnisch bewältigen (SendMessage("MOUSEMOVE@"...).

Und wie ich meine Leute auf ActiveVB kenne, hat sich schon jemand mit Deinem/Unseren Problem auseinandergesetzt. Fertiges Modul. Nur als Konsolenprogramm kompilieren...fertig. Eine Windowsversion-Check Routine ist bereits integriert-->Win98/NT-->NT;2K;XP haben im enstprechenden /Systray-Bereich/ kleine Unterschiede.

Oder noch besser:
exe-Datei mailen.

Wow, da danke ich Dir aber für Dein Vertrauen face-wink. Jetzt habe ich noch nicht einmal nach "vb6 compiler" gegoogled, aber wenn Du dieses enorme Risiko eingehen willst schicke ich Dir eine kompilierte Konsolenversion von der fertigen Vorlage von Activevb.de.


Danke

Bitte.

BG, Felix -mrdemeanor-
uroveits
uroveits 06.01.2008 um 23:44:06 Uhr
Goto Top
Hallo Felix,

erst einmal vielen Dank für Deine Bemühungen.

Wow, da danke ich Dir aber für Dein Vertrauen
Im Rahmen unseres Dialogs habe ich doch glatt vergessen, dass ich mich im Internet befinde. Dein Hinweis bzgl. einer exe-Datei ist natürlich vollkommen gerechtfertigt.
Ich möchte daher anfragen, ob es möglich ist, das "fertige Modul" als Text zu posten. Ich möchte nicht die zip-Datei öffnen, da ich etwas unsicher geworden bin, ob sich nicht doch jemand einen kleinen Spaß erlaubt.

Gruß

uroveits
misterdemeanor
misterdemeanor 07.01.2008 um 06:19:13 Uhr
Goto Top
Hi uroveits,

konnte den Author nicht ausfindig machen, aber wie geschrieben, stammt dieses Modul von ActiveVB.de.

Option Explicit

'Messagekonstante  
Private Const WM_MOUSEMOVE = &H200

'Strucktur mit den Fensterabmaßen  
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Dim hSystray As Long

Private Declare Function GetVersionEx Lib "kernel32.dll" Alias "GetVersionExA" (lpVersionInformation As Any) As Long  
Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128 ' Maintenance string for PSS usage  
End Type

Private Type OSVERSIONINFOEX
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128  ' Maintenance string for PSS usage  
    wServicePackMajor As Integer
    wServicePackMinor As Integer
    wSuiteMask As Integer
    bProductType As Byte
    bReserved As Byte
End Type

Private Const VER_NT_DOMAIN_CONTROLLER As Long = &H2
Private Const VER_NT_SERVER As Long = &H3
Private Const VER_NT_WORKSTATION As Long = &H1

Private Const VER_SUITE_BACKOFFICE As Long = &H4
Private Const VER_SUITE_BLADE As Long = &H4
Private Const VER_SUITE_COMMUNICATIONS As Long = &H8
Private Const VER_SUITE_DATACENTER As Long = &H80
Private Const VER_SUITE_EMBEDDEDNT As Long = &H40
Private Const VER_SUITE_ENTERPRISE As Long = &H2
Private Const VER_SUITE_SINGLEUSERTS As Long = &H100
Private Const VER_SUITE_SMALLBUSINESS As Long = &H1
Private Const VER_SUITE_SMALLBUSINESS_RESTRICTED As Long = &H20
Private Const VER_SUITE_TERMINAL As Long = &H10
Private Const VER_SUITE_PERSONAL As Long = &H200
Private Const VER_SUITE_SERVERAPPLIANCE As Long = &H400

Private Const VER_PLATFORM_WIN32_NT As Long = 2
Private Const VER_PLATFORM_WIN32_WINDOWS As Long = 1
Private Const VER_PLATFORM_WIN32s As Long = 0

Private Declare Function GetVersion Lib "kernel32.dll" () As Long  
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long  
Private Declare Function GetClientRect Lib "user32.dll" (ByVal hwnd As Long, lpRect As RECT) As Long  
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long  
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long  


Private Function Refresh(ByVal hTray As Long) As Boolean
Dim x As Long, rRect As RECT, z As Long

If hTray = 0 Then Exit Function
'Größe des Fensters ermitteln  
x = GetClientRect(hTray, rRect)

'Zeilenweise durchgehen  
For z = 0 To (rRect.Bottom / 20) - 1
    'zu jerder x Position ein MouseMove senden  
    For x = 0 To rRect.Right
        SendMessage hTray, WM_MOUSEMOVE, 0, ByVal ((((z * 20) + 10) * &H10000) Or x)
    Next
Next
Refresh = True

End Function
Private Function FindSysTray() As Long
Dim h1 As Long, h2 As Long, h3 As Long
'Handle vom Tray suchen  
h1 = FindWindow("Shell_TrayWnd", vbNullString)  
If h1 <> 0 Then
    'Handle vom TrayNotify ermitteln  
    h2 = FindWindowEx(h1, 0, "TrayNotifyWnd", vbNullString)  
    If (GetBS > 14) Or (GetBS = 5) Then
        If GetBS > 15 Then h2 = FindWindowEx(h2, 0, "SysPager", vbNullString)  
        If h2 <> 0 Then
            'Handle von der Toolbar ermitteln  
            h3 = FindWindowEx(h2, 0, "ToolbarWindow32", vbNullString)  
            FindSysTray = h3
        End If
    Else
        FindSysTray = h2
    End If
End If

End Function
Private Function GetBS() As Long
Dim WinVer As String
Dim udtOS As OSVERSIONINFO

udtOS.dwOSVersionInfoSize = Len(udtOS)

Call GetVersionEx(udtOS)

Debug.Print udtOS.dwBuildNumber
Debug.Print udtOS.dwMajorVersion
Debug.Print udtOS.dwMinorVersion
Debug.Print udtOS.szCSDVersion

Select Case udtOS.dwPlatformId
    Case VER_PLATFORM_WIN32_NT
        If udtOS.dwMajorVersion = 3 Then
            GetBS = 13 'NT 3.51  
        ElseIf udtOS.dwMajorVersion = 4 Then
            GetBS = 14 'NT 4.0  
        ElseIf udtOS.dwMajorVersion = 5 Then
            If udtOS.dwMinorVersion = 0 Then
                GetBS = 15 'Win2000  
            ElseIf udtOS.dwMinorVersion = 1 Then
                GetBS = 16 'WinXP  
            ElseIf udtOS.dwMinorVersion = 2 Then
                GetBS = 17 'Win .NET/2003  
            End If
        End If
    Case VER_PLATFORM_WIN32_WINDOWS
        If udtOS.dwMinorVersion = 0 Then
            GetBS = 3 'Win 95  
        ElseIf udtOS.dwMinorVersion = 10 Then
            GetBS = 4 'Win 98  
        ElseIf udtOS.dwMinorVersion = 90 Then
            GetBS = 5 'Win ME  
        End If
    Case VER_PLATFORM_WIN32s
        GetBS = 1
End Select

End Function
Public Function SysTrayRefresh() As Boolean

'Fensterhandle vom Systray ermitteln  
hSystray = FindSysTray
'Systray refreshen  
If Refresh(hSystray) Then SysTrayRefresh = True
End Function
Property Get hwnd() As Long
hwnd = hSystray
End Property
Public Function BSInfo() As String
Dim WinVer As String, lngBS As Long
Dim udtOSEX As OSVERSIONINFOEX, udtOS As OSVERSIONINFO

lngBS = GetBS

udtOS.dwOSVersionInfoSize = Len(udtOS)
udtOSEX.dwOSVersionInfoSize = Len(udtOSEX)

If lngBS > 13 Then
    If GetVersionEx(udtOSEX) Then
        If (udtOSEX.bProductType And VER_NT_WORKSTATION) Then
            If lngBS > 14 Then
                WinVer = " Profesional" & vbCrLf  
            Else
                WinVer = " Workstation" & vbCrLf  
            End If
        Else
            WinVer = " Server" & vbCrLf  
        End If
        If (udtOSEX.wSuiteMask And VER_SUITE_PERSONAL) Then WinVer = "Home Edition"  
        WinVer = WinVer & udtOSEX.szCSDVersion
    Else
        Call GetVersionEx(udtOS)
        WinVer = WinVer & udtOS.szCSDVersion
    End If
End If

If lngBS = 1 Then BSInfo = "Win32s"  
If lngBS = 3 Then BSInfo = "Win 95"  
If lngBS = 4 Then BSInfo = "Win 98"  
If lngBS = 5 Then BSInfo = "Win ME"  
If lngBS = 13 Then BSInfo = "Win NT 3.51" & WinVer  
If lngBS = 14 Then BSInfo = "Win NT 4.0" & WinVer  
If lngBS = 15 Then BSInfo = "Win 2000" & WinVer  
If lngBS = 16 Then BSInfo = "Win XP" & WinVer  
If lngBS = 17 Then BSInfo = "Win 2003/.NET" & WinVer  

End Function

bg, Felix