ProcessExists für einzelne Benutzer

  • Hallo zusammen,

    ich habe schon ein wenig gegoogelt aber leider nicht die richtige Lösung für mich gefunden, die ich auch verstehe :P

    Grundproblem:

    Es geht darum, das sich Benutzer mit MDE Geräten am Terminal Server anmelden sollen. Hier soll eine Software gestartet werden für die Lagerverwaltung.

    Natürlich möchte ich vermeiden das die einfach das Programm aus machen und anfangen am Server rum zuspielen. Daher weise ich den Benutzern im DC eine umgebung zu die nur ein Programm ausführen soll und der Rest gesperrt bleibt bzw nicht sichtbar ist.

    Natürlich kann es aber auch vorkommen das dass Programm abstürzt oder jemand einfach auf Beenden klickt... Nun kann er das Programm natürlich nicht mehr Starten da er ja nicht ein mal einen Desktop hat. Er muss also ausgeloggt werden.

    Hierfür wollte ich einfach ein kleines einfaches Script zusammen schustern ^^ Soweit der Plan....

    Idee:

    Script wird ausgeführt, das Script startet das Programm mit den Argumenten und checkt alle Paar sekunden ob das Programm noch läuft. Wenn nicht einfach ausloggen

    Code
        $cmd1 = "shutdown.exe -l"
    run ("C:\sog\tools\bin\hhexew.exe -asstartcond -hhproj sogerp -hhfirm 01 hhpxProjWinFrame.exe -mskvar mini -nas -liz vstore","C:\sog\tools\bin\")
    While 1
    if ProcessExists("hhpxprojwinframe.exe") Then
    Else
        Sleep (3000)
    RunWait(@ComSpec & " /c " & $cmd1)
    Sleep (3000)
    EndIf
    WEnd

    Probleme:

    Das Script läut an sich super... nur wenn jemand anderes (also Benutzer) das Programm auf hat, denkt das Script das der Prozess noch läuft und tut nichts... Aber ich muss dies ja Benutzer abhängig steuern.

    Hat jemand dafür eine einfach und Simple Lösung? Leider bin ich nicht gerade sehr Firm in dem Thema mit UDF´s usw.. Hoffe ihr habt noch weitere Ideen und könnt mir Helfen.


    Lg

  • Versuche es mal anstelle ProcessExists("hhpxprojwinframe.exe") mit: _Singleton ().

    _Singleton ( $sOccurrenceName [, $iFlag = 0] )

    Für $sOccurrenceName kannst du dann z.B. den Namen des aktuellen Users (@UserName) oder den Profilpfad (@AppDataDir) angeben.

  • Was macht denn _Singleton genau?

    Ein Blick in die Dokumentation genügt:

    Enforce a design paradigm where only one instance of the script may be running

    Es erlaubt dir dein AutoIt-Skript nur einmal pro System am laufen zu haben. Das $sOccurenceName ist dabei der Identifikator.

    Du nimmst als Identifikator einfach den Benutzernamen und versuchst das Skript zu starten, startet es mit einer Fehlermeldung von _Singleton weißt du, dass der aktuelle Benutzer es noch benutzt.

    Startet es ohne Fehlermeldung, weißt du, dass es nicht läuft und kannst es beenden und dich ausloggen.

  • Ein Blick in die Dokumentation genügt:

    Es erlaubt dir dein AutoIt-Skript nur einmal pro System am laufen zu haben. Das $sOccurenceName ist dabei der Identifikator.

    Du nimmst als Identifikator einfach den Benutzernamen und versuchst das Skript zu starten, startet es mit einer Fehlermeldung von _Singleton weißt du, dass der aktuelle Benutzer es noch benutzt.

    Startet es ohne Fehlermeldung, weißt du, dass es nicht läuft und kannst es beenden und dich ausloggen.

    Bedeutet also, das ich gar nicht den Prozess abfrage, sondern nur Abfrage ob dieses Skript läuft?

    Das würde mir ja auch nichts bringen, da das Programm ja geschlossen wurde aber das Script läuft ja weiterhin.

    Kann mir das vielleicht jemand genauer erklären? Ich verstehe es irgendwie nicht. Sry

    Einmal editiert, zuletzt von Springstil (6. Februar 2019 um 12:47)

  • Das würde mir ja auch nichts bringen, da das Programm ja geschlossen wurde aber das Script läuft ja weiterhin.

    Wenn es ein externes Programm ist kannst du das auch über WMI machen, hier mal ein Thread aus dem blauen Forum. https://www.autoitscript.com/forum/topic/94…user-or-system/

    Dort kriegst du den Usernamen des Benutzers angezeigt der den Prozess ausgeführt hat.

  • Für mich dann doch ein wenig Kompliziert

    Das ist ja wohl die faulste Ausrede die ich seit langem gehört habe, du gibst dir ja nicht mal Mühe das ganze zu verstehen.

    Der Hauptgegentand ist die For-Schleife in dem die Prozesse aufgelistet werden, hast du das Skript nicht mal ausgeführt?

    Alles was du machen musst ist nur die Prozessliste durchgehen und zu prüfen ob der Username mit dem übereinstimmt den du vergleichen willst, das sind vielleicht 2 Minuten Arbeit.

  • Für mich dann doch ein wenig Kompliziert :saint: werde ich mir wohl eine andere Lösung einfallen lassen müssen.

    Ok, dann will ich mal ritterlich sein...

    Im Anhang findest du zwei Versionen. Eine die es via WMI macht, und eine die es via ProcessList macht - such dir eine aus!

    Ich denke mal, so hast du dir das gedacht...

    Edit: While- Schleife vergessen/eingebaut, damit sich das Script nicht selbst beendet.

  • Man kann das auch ganz simpel mit runwait lösen.

    Bei der Useranmeldung wird dann folgendes gemacht:

    - Alles verschwinden lassen, sprich kein nutzbarer desktop usw. keine Ahnung wie du das bislang realisierst

    - Dein Autoitscript wird gestartet

    - Das Autoitscript übernimmt den Start der Anwendung und zwar nicht mit run, sondern mit runwait, alternativ ginge natürlich auch run und eine Schleife mit processexists Prüfung auf die PID des gestarteten Prozesses, welche dir run ja zurückgibt und eindeutig ist

    - Solange die Anwendung nicht geschlossen wird macht dein Autoitscript nichts ausser darauf zu warten, dass die gestartete Anwendung geschlossen wird

    - Sollte sie geschlossen werden wartest du am besten erstmal x Sekunden, da es ja sein könnte, dass dies gewollt ist (z.b Userabmeldung oder Serverneustart), in diesam Fall wird dein Autoitscript dann früher oder später auch beendet und macht nix mehr, was ja gewollt ist

    - Andernfalls startet dein Script die Anwendung einfach neu und fängt wieder an darauf zu warten, dass sie beendet wird, alternativ kannst du den User natürlich auch abmelden

  • Man kann das auch ganz simpel mit runwait lösen.

    Ich denke mal, so geht das nicht, denn mit RunWait() würde er ja auf den Process warten, den er startet, aber das ist nicht der Process, den er überwachen will...

    Run("C:\sog\tools\bin\hhexew.exe -asstartcond -hhproj sogerp -hhfirm 01 hhpxProjWinFrame.exe -mskvar mini -nas -liz vstore","C:\sog\tools\bin\")

    RunWait("C:\sog\tools\bin\hhexew.exe -asstartcond -hhproj sogerp -hhfirm 01 hhpxProjWinFrame.exe -mskvar mini -nas -liz vstore","C:\sog\tools\bin\")

    Gefragt ist, ob der Process "'hhpxprojwinframe.exe'" von User xyz noch ausgeführt wird...

  • Stimmt hab ich übersehen. Kann man trotzdem so machen. Man nutzt run um die PID des Launchers "hhexew,exe" zu ermitteln, wartet bis der Launcher seine Arbeit erledigt hat und prüft dann mit processlist nach existierenden Prozessen der "hhpxprojwinframe.exe" processlist gibt soweit ich mich erinnere auch die PID der Prozesse zurück. Die korrekte Instanz sollte eine PID größer des unmittelbar zuvor gestarteten Launchers haben. Eine korrekte Zuordnung ist also recht zuverlässig möglich, sofern nicht nahezu zeitgleich mehrere Nutzer am System angemeldet werden. Es sollte aber auch möglich sein eine direkte Zuordnung von Benutzeraccount und Prozess / PID abzufragen, der Taskmanager listet den ausführenden Benutzer ja auch auf.

    EDIT:

    Alpines hat ja schon das dazu nötige Script gepostet in Beitrag #6

  • Alpines hat ja schon das dazu nötige Script gepostet in Beitrag #6

    Ja, genau... und ich habe ihm in Post #10 auch zwei Versionen geschrieben, eine via WMI, die andere via ProcessList & _WinAPI_GetProcessUser, die er ohne weitere Änderungen nutzen kann.

    Nachtrag:

    Die korrekte Instanz sollte eine PID größer des unmittelbar zuvor gestarteten Launchers haben.

    Das ist nicht richtig... denn die PID kann auch kleiner sein!

    Einmal editiert, zuletzt von Bitnugger (12. Februar 2019 um 10:38)

  • Ok, dann will ich mal ritterlich sein...

    Im Anhang findest du zwei Versionen. Eine die es via WMI macht, und eine die es via ProcessList macht - such dir eine aus!

    Ich denke mal, so hast du dir das gedacht...

    Edit: While- Schleife vergessen/eingebaut, damit sich das Script nicht selbst beendet.

    Danke noch mal für das Skript. Das Skript bleibt zwar offen, aber es loggt sich beim beenden nicht aus. Wo bekommt die schleife denn das Signal das die Anweisung zum ausloggen gegeben wird?

  • Das Skript bleibt zwar offen, aber ...

    Das passiert alles in der Funktion _CheckProcess(), die alle 3000 ms aufgerufen wird.

    Dort wird mit ProcessList() eine Liste aller Processe mit dem Namen "hhpxprojwinframe.exe" geholt. Wird ein Process mit diesem Namen gefunden, der vom aktuellen User ausgeführt wird, wird die Funktion mit Return verlassen und in ~3000 ms wieder aufgerufen, anderfalls wird die Funktion Shutdown($SD_LOGOFF) ausgeführt, die den User eigentlich ausloggen sollte...

    Es gibt drei relevante Möglichkeiten:

    1. Der Process "hhpxprojwinframe.exe" wurde gefunden und wird auch vom aktuellen User ausgeführt, dann wird die Funktion in 3000 ms wieder aufgerufen.
    2. Der Process "hhpxprojwinframe.exe" wurde gefunden, wird aber nicht vom aktuellen User ausgeführt - der User sollte ausgeloggt werden.
    3. Der Process "hhpxprojwinframe.exe" wurde nicht gefunden - der User sollte ausgeloggt werden.

    Baue mal die Funktion _CheckProcess() zum Testen so um:

    Einmal editiert, zuletzt von Bitnugger (12. Februar 2019 um 14:56)

  • Das passiert alles in der Funktion _CheckProcess(), die alle 3000 ms aufgerufen wird.

    Dort wird mit ProcessList() eine Liste aller Processe mit dem Namen "hhpxprojwinframe.exe" geholt. Wird ein Process mit diesem Namen gefunden, der vom aktuellen User ausgeführt wird, wird die Funktion mit Return verlassen und in ~3000 ms wieder aufgerufen, anderfalls wird die Funktion Shutdown($SD_LOGOFF) ausgeführt, die den User eigentlich ausloggen sollte...

    Es gibt drei relevante Möglichkeiten:

    1. Der Process "hhpxprojwinframe.exe" wurde gefunden und wird auch vom aktuellen User ausgeführt, dann wird die Funktion in 3000 ms wieder aufgerufen.
    2. Der Process "hhpxprojwinframe.exe" wurde gefunden, wird aber nicht vom aktuellen User ausgeführt - der User sollte ausgeloggt werden.
    3. Der Process "hhpxprojwinframe.exe" wurde nicht gefunden - der User sollte ausgeloggt werden.

    Baue mal die Funktion _CheckProcess() zum Testen so um:

    Mit der Umgebauten Variante bekomme ich zumindest die meldeung, das der den Prozess nicht mehr findet. ABER er loggt sich nicht aus. Warum auch immer Funktoniert der Befehl

    Code
    Shutdown($SD_LOGOFF)

    nicht anständig auf dem Server. Mache ich das ganze über CMD (Ich weiß ich mach es mir sehr einfach :P )

    Code
    local $cmd1 = "shutdown.exe -l"
    
    RunWait(@ComSpec & " /c " & $cmd1)

    Loggt er sich aus wie es sein soll :)


    Einzige was mich gerade ein wenig stört, ist das er jedes mal beim einloggen jetzt das Skript startet. Das ist zwar gewollt, aber das soll eigendlich der Server übernehmen. Jetzt gibt es ja die Zeile mit $g_bAutoStart ist die dafür zuständig? Wo schreibt er denn den wert hin bzw wo im system wird das hinterlegt?

    Einmal editiert, zuletzt von Springstil (13. Februar 2019 um 08:35)

  • Versuch es mal mit einem "Sleep(3000)" nach dem Shutdown-Kommando.

    Ich hatte ein ähnliches Problem einmal. Da beendete sich das Script zu schnell und daher wurde das Shutdown-Kommando erst gar nicht gestartet!

    Zur Nutzung dieses Forum's, ist ein Übersetzer für folgende Begriffe unerlässlich:

    "On-Bort, weier, verscheiden, schädliges, Butten steyling, näckstet, Parr, Porblem, scripe, Kompletenz, harken, manuel zu extramieren, geckukt, würglich, excell, acces oder Compilevorgeng"

  • Versuche es mal bitte so... und sage uns, welchen Wert $iShutdown dann hat.

    Code
        Local $iShutdown = Shutdown(BitOR($SD_FORCE, $SD_LOGOFF)) ; (0) = Logoff - 'hhpxprojwinframe.exe' wird momentan nicht vom User @UserName ausgeführt!
        MsgBox(64, '_CheckProcess()', '$iShutdown = ' & $iShutdown & @CRLF)

    Ich hatte ein ähnliches Problem einmal. Da beendete sich das Script zu schnell und daher wurde das Shutdown-Kommando erst gar nicht gestartet!

    Das Script wird ja nicht beendet, sondern springt nach 3000 ms immer wieder in die Funktion _CheckProcess() und solange der Process 'hhpxprojwinframe.exe' nicht gefunden wurde, wird immer wieder Shutdown() ausgeführt, der aber wohl offensichtlich so nicht funktioniert. Mit $SD_FORCE sollte es aber klappen...

    Einzige was mich gerade ein wenig stört, ist das er jedes mal beim einloggen jetzt das Skript startet.

    In Zeile 12 steht doch gut beschrieben, dass sich das Script nur dann automatisch startet, wenn $g_bAutoStart = True ist... wenn das Script selbst keinen Autostart machen soll, dann setze $g_bAutoStart = False, oder baue die Funktion komplett aus - das Script im Anhang, da habe ich sie mal für dich entfernt.

    Wo schreibt er denn den wert hin bzw wo im system wird das hinterlegt?

    Das steht in Zeile 31...

    FileCreateShortcut(@ScriptFullPath, $sShortcut)

    @ScriptFullPath ist das (kompilierte) Script selbst, $sShortcut die Verknüpfung, die im Autostart-Verzeichnis erzeugt wird, beide mit kpl. Pfad. Diese Variablen kannst du dir doch einfach mit ConsoleWrite oder MsBox anzeigen lassen... wo ist also das Problem?