Python Script von der Nutzung des Prozessnamens auf pid ändern.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Schlawiner
User
Beiträge: 1
Registriert: Donnerstag 17. Juli 2025, 13:25

Hallo,

ich bin auf github auf ein Admin Skript gesossen, welches zwar einwandfrei funktioniert. Allerdings Probleme bereitet sobald man mehrere Gameserver auf dem Rootserver hat. Der Grund dafür ist, das dieses Script die Konsole via Prozessnamen aufrift, da aber alle Instanzen den gleichen Prozessnamen haben sind Konflikte vorprogrammiert. Anbei einen Link zum Script:

https://github.com/Volavi/Wreckfest-2-A ... me-ov-file


Die Kritische Funktion ist der Zugriff auf die Konsole

Code: Alles auswählen

    def locate_server_window(self):
        """Find and activate the Wreckfest 2 server window"""
        try:
            self.server_window = gw.getWindowsWithTitle('Wreckfest 2 | ')[0]
            if self.server_window:
                self.server_window.activate()
                time.sleep(1)
                if self.debug_settings.get('print_console_actions', False):
                    print(f"Found server window: {self.server_window.title}")
                    print(f"Window position: (left={self.server_window.left}, top={self.server_window.top})")
                    print(f"Window size: (width={self.server_window.width}, height={self.server_window.height})")
            else:
                raise Exception("Wreckfest 2 server window not found")
        except IndexError:
            print("Error: Could not find 'Wreckfest 2' server window")
            print("Please make sure your Wreckfest 2 server is running and visible")
            exit(1)
        except Exception as e:
            print(f"Error locating server window: {str(e)}")
            exit(1)
Hat jemand eine Idee wie man dies umbauen könnte das der Zugriff via Pid oder Pfad erfolgt ? Unter Autoit wäre dies wie folgt möglich

Code: Alles auswählen

Func _ConsoleSendCtrlC($PID, $iEvent = 0, $iMode = 0, $iLoop = 1, $iSlp = 10, $iDll = "kernel32.dll")
    ;Author: rover 2k12
    Local $aRet = DllCall($iDll, "bool", "AttachConsole", "dword", $PID)
    If @error Or $aRet[0] = 0 Then Return SetError(1, 0, -1)
    ;sets GetLastError to ERROR_GEN_FAILURE (31) if process does not exist
    ;sets GetLastError to ERROR_ACCESS_DENIED (5) if already attached to a console
    ;sets GetLastError to ERROR_INVALID_HANDLE (6) if process does not have a console

    $aRet = DllCall("Kernel32.dll", "hwnd", "GetConsoleWindow") ;must be attached to console to get hWnd
    If Not @error And IsHWnd($aRet[0]) Then
        $aRet = DllCall('user32.dll', 'int', 'IsHungAppWindow', 'hwnd', $aRet[0]);from Yashieds' WinAPIEx.au3
        If Not @error And $aRet[0] Then
            DllCall($iDll, "bool", "FreeConsole")
            Return SetError(2, 0, -1)
        EndIf
    Else
        Return SetError(3, 0, -1)
    EndIf
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Schlawiner: So ganz grundsätzlich gibt es das `ctypes`-Modul in der Standardbibliothek. Und extern zusätzlich `pywin32`.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
sparrow
User
Beiträge: 4536
Registriert: Freitag 17. April 2009, 10:28

@Schlawiner: Wo wird denn da der Prozessname verwendet?
Sirius3
User
Beiträge: 18266
Registriert: Sonntag 21. Oktober 2012, 17:20

Das Skript geht nach dem Fenster-Titel, nicht nach dem Prozessnamen. Und da die Funktion getWindowsWithTitle ja eine Liste aller Fenster mit dem passenden Titel liefert, ist es ja kein Problem, diese weiter zu filtern. Wenn es der Prozess sein soll, dann gibt es pywin32.GetProcessHandleFromHwnd
nezzcarth
User
Beiträge: 1754
Registriert: Samstag 16. April 2011, 12:47

Nebenbemerkung:
"OCR Integration: Reads server console output using Tesseract OCR"
Hilfe! :shock:

Statt das Skript zu verbessern vielleicht lieber den Hersteller davon überzeugen, dass der eine richtige Serversoftware anbietet, idealerweise (auch) für Linux. Dann hat man solche Probleme auch nicht. Ich verstehe, dass es vmtl. im Moment nicht anders geht. Aber solche Hacks mit GUI-Automatisierung und OCR in einer "Server"-Anwendung gehen für meine Begriffe eigentlich nicht klar.
Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mal den gezeigten Anfang der Autoit-Funktion in Python, um zu zeigen wie man DLL-Funktionen von Python aus aufrufen kann (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import ctypes
from ctypes.wintypes import BOOL, DWORD, HWND


def create_function(function, argument_types, result_type):
    function.argtypes = argument_types
    function.restype = result_type
    return function


kernel32 = ctypes.windll.kernel32
user32 = ctypes.cdll.user32
attach_console = create_function(kernel32.AttachConsole, [DWORD], BOOL)
free_console = create_function(kernel32.FreeConsole, [], BOOL)
get_console_window = create_function(kernel32.GetConsoleWindow, [], HWND)
is_hung_app_window = create_function(user32.IsHungAppWindow, [HWND], BOOL)


def console_send_ctrl_c(pid):
    if not attach_console(pid):
        raise RuntimeError(f"could not attach the console for PID {pid}")

    window_handle = get_console_window()
    if window_handle is None:
        raise RuntimeError(
            f"process with PID {pid} does not have a console window"
        )

    if is_hung_app_window(window_handle):
        free_console(window_handle)
        raise RuntimeError(f"console window for PID {pid} is hung")

    # ...
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten