From f9867dcf7a85a0158cdb767e6a770feec2c75850 Mon Sep 17 00:00:00 2001 From: Lucas Orth Date: Mon, 24 Aug 2026 12:13:59 +0200 Subject: [PATCH] Import aus Monorepo (frischer Start) --- .gitignore | 6 ++++ auto_recover.py | 67 +++++++++++++++++++++++++++++++++++++++++++++ build_exe.bat | 11 ++++++++ debug_window.py | 27 ++++++++++++++++++ find_window_info.py | 46 +++++++++++++++++++++++++++++++ 5 files changed, 157 insertions(+) create mode 100644 .gitignore create mode 100644 auto_recover.py create mode 100644 build_exe.bat create mode 100644 debug_window.py create mode 100644 find_window_info.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8bcff71 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +__pycache__/ +*.pyc +.venv/ +venv/ +config.json +.env diff --git a/auto_recover.py b/auto_recover.py new file mode 100644 index 0000000..43a3fa6 --- /dev/null +++ b/auto_recover.py @@ -0,0 +1,67 @@ +""" +AutoRecover - Drucker Fehler Handler +Erkennt das "Error"-Fenster (Java AWT) und klickt automatisch "Recover" (max. 3x). +""" + +import win32gui +import win32con +import ctypes +import time + +MAX_VERSUCHE = 3 +PRUEF_INTERVAL = 2 # Sekunden zwischen den Checks + +def click_recover_button(hwnd): + """ + Holt die Fensterposition und klickt auf den Recover-Button. + Der Button ist zentriert am unteren Rand des Fensters. + """ + # Fenster in den Vordergrund holen + win32gui.SetForegroundWindow(hwnd) + time.sleep(0.3) + + # Fensterposition und -größe ermitteln + left, top, right, bottom = win32gui.GetWindowRect(hwnd) + width = right - left + height = bottom - top + + # Recover-Button liegt ca. bei: horizontal zentriert, ~85% der Höhe + click_x = left + width // 2 + click_y = top + int(height * 0.85) + + # Mausklick simulieren + ctypes.windll.user32.SetCursorPos(click_x, click_y) + time.sleep(0.1) + ctypes.windll.user32.mouse_event(0x0002, 0, 0, 0, 0) # linke Taste runter + ctypes.windll.user32.mouse_event(0x0004, 0, 0, 0, 0) # linke Taste hoch + + print(f" → Klick auf Position ({click_x}, {click_y})") + +def main(): + versuche = 0 + print("AutoRecover läuft... (Strg+C zum Beenden)") + print(f"Maximal {MAX_VERSUCHE} Versuche.\n") + + while versuche < MAX_VERSUCHE: + hwnd = win32gui.FindWindow(None, "Error") + + if hwnd and win32gui.IsWindowVisible(hwnd): + versuche += 1 + print(f"[Versuch {versuche}/{MAX_VERSUCHE}] Fehlerfenster gefunden!") + + time.sleep(0.5) + click_recover_button(hwnd) + + if versuche >= MAX_VERSUCHE: + print(f"\nMaximale Versuche ({MAX_VERSUCHE}) erreicht. Programm beendet.") + break + + time.sleep(3) + else: + time.sleep(PRUEF_INTERVAL) + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print("\nProgramm manuell beendet.") diff --git a/build_exe.bat b/build_exe.bat new file mode 100644 index 0000000..b5dfce9 --- /dev/null +++ b/build_exe.bat @@ -0,0 +1,11 @@ +@echo off +echo PyInstaller wird installiert falls noetig... +pip install pyinstaller pywin32 --quiet + +echo. +echo Erstelle AutoRecover.exe ... +python -m PyInstaller --onefile --noconsole --name AutoRecover auto_recover.py + +echo. +echo Fertig! Die EXE liegt in: dist\AutoRecover.exe +pause diff --git a/debug_window.py b/debug_window.py new file mode 100644 index 0000000..6d36d53 --- /dev/null +++ b/debug_window.py @@ -0,0 +1,27 @@ +"""Debug: Zeigt alle Elemente im Error-Fenster""" +import win32gui + +def dump_window(hwnd, indent=0): + try: + class_name = win32gui.GetClassName(hwnd) + text = win32gui.GetWindowText(hwnd) + print(" " * indent + f'[{class_name}] "{text}" (hwnd={hwnd})') + except: + pass + + try: + def callback(child_hwnd, _): + dump_window(child_hwnd, indent + 4) + win32gui.EnumChildWindows(hwnd, callback, None) + except: + pass + +hwnd = win32gui.FindWindow(None, "Error") +if hwnd: + print(f"Fenster gefunden: hwnd={hwnd}\n") + dump_window(hwnd) +else: + print("Kein Fenster mit Titel 'Error' gefunden!") + print("Bitte Fehlerfenster öffnen und nochmal ausführen.") + +input("\nEnter zum Beenden...") diff --git a/find_window_info.py b/find_window_info.py new file mode 100644 index 0000000..0beca2a --- /dev/null +++ b/find_window_info.py @@ -0,0 +1,46 @@ +""" +Schritt 1: Fenster-Erkennung +Lass den Druckerfehler aufpoppen, dann starte dieses Skript. +Es zeigt alle sichtbaren Fenster und deren Buttons an. +""" + +import win32gui +import win32con +import win32api + +def get_child_controls(hwnd): + controls = [] + def callback(child_hwnd, _): + class_name = win32gui.GetClassName(child_hwnd) + text = win32gui.GetWindowText(child_hwnd) + if class_name == "Button" and text: + controls.append(f' Button: "{text}"') + elif text: + controls.append(f' {class_name}: "{text}"') + win32gui.EnumChildWindows(hwnd, callback, None) + return controls + +def list_windows(): + windows = [] + def callback(hwnd, _): + if win32gui.IsWindowVisible(hwnd): + title = win32gui.GetWindowText(hwnd) + if title: + controls = get_child_controls(hwnd) + windows.append((title, controls)) + win32gui.EnumWindows(callback, None) + return windows + +print("=" * 60) +print("Gefundene Fenster mit Buttons:") +print("=" * 60) + +for title, controls in list_windows(): + if controls: + print(f'\nFenster: "{title}"') + for c in controls: + print(c) + +print("\n" + "=" * 60) +print("Kopiere den Fenstertitel und Button-Namen für AutoRecover.") +input("\nEnter drücken zum Beenden...")