import os import sys from ctypes import c_long, c_longlong, windll import pythoncom import win32com.client class HardwareController: _instance = None _wyhkm = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(HardwareController, cls).__new__(cls) return cls._instance def _runtime_base_dir(self): if getattr(sys, "frozen", False): return os.path.dirname(sys.executable) return os.path.dirname(os.path.abspath(__file__)) def _resolve_resource_path(self, relative_path): if os.path.isabs(relative_path): return relative_path if os.path.exists(relative_path) else None candidates = [] if getattr(sys, "frozen", False): exe_dir = os.path.dirname(sys.executable) if exe_dir: candidates.append(os.path.join(exe_dir, relative_path)) meipass = getattr(sys, "_MEIPASS", "") if meipass: candidates.append(os.path.join(meipass, relative_path)) module_dir = os.path.dirname(os.path.abspath(__file__)) candidates.append(os.path.join(module_dir, relative_path)) candidates.append(os.path.abspath(relative_path)) seen = set() for candidate in candidates: candidate = os.path.abspath(candidate) if candidate in seen: continue seen.add(candidate) if os.path.exists(candidate): return candidate return None def _log(self, message): print(message) try: log_path = os.path.join(self._runtime_base_dir(), "hardware_control.log") with open(log_path, "a", encoding="utf-8") as f: f.write(message + "\n") except Exception: pass def __init__(self, dll_path="ddl/wyhkm.dll"): if self._wyhkm: return self.dll_path = self._resolve_resource_path(dll_path) if not self.dll_path: self._log(f">>> [hardware_control] DLL not found: {dll_path}") return try: hkmdll = windll.LoadLibrary(self.dll_path) hkmdll.DllInstall.argtypes = (c_long, c_longlong) if hkmdll.DllInstall(1, 2) < 0: self._log(">>> [hardware_control] DllInstall failed") return self._log(f">>> [hardware_control] DllInstall ok: {self.dll_path}") pythoncom.CoInitialize() try: self._wyhkm = win32com.client.Dispatch("wyp.hkm") except Exception as e: self._log(f">>> [hardware_control] COM Dispatch failed: {e}") return dev_id = self._wyhkm.SearchDevice(0x2612, 0x1701, 0) if dev_id == -1: self._log(">>> [hardware_control] Device not found (Index 0)") self._wyhkm = None return if not self._wyhkm.Open(dev_id, 0): self._log(">>> [hardware_control] Open device failed") self._wyhkm = None return self._wyhkm.SetMode(1, 1) self._wyhkm.SetMode(2, 1) self._wyhkm.SetKeyInterval(30, 50) self._wyhkm.SetMouseInterval(30, 50) self._log(f">>> [hardware_control] Device opened and initialized: {dev_id}") except Exception as e: self._log(f">>> [hardware_control] Init failed: {e}") self._wyhkm = None def is_available(self): if not self._wyhkm: return False try: return self._wyhkm.IsOpen(0) except Exception: return False def delay_rnd(self, min_ms, max_ms): if self.is_available(): try: self._wyhkm.DelayRnd(int(min_ms), int(max_ms)) except Exception: pass def key_down(self, key_str): if self.is_available(): try: self._wyhkm.KeyDown(str(key_str).upper()) except Exception: pass def key_up(self, key_str): if self.is_available(): try: self._wyhkm.KeyUp(str(key_str).upper()) except Exception: pass def key_press(self, key_str): if self.is_available(): try: self._wyhkm.KeyPress(str(key_str).upper()) except Exception: pass def keyDown(self, key_str): self.key_down(key_str) def keyUp(self, key_str): self.key_up(key_str) def press(self, key_str): self.key_press(key_str) def move_to(self, x, y): if self.is_available(): try: return bool(self._wyhkm.MoveTo(int(x), int(y))) except Exception as e: self._log(f">>> [hardware_control] MoveTo failed ({x}, {y}): {e}") return False def move_r(self, dx, dy): if self.is_available(): try: return bool(self._wyhkm.MoveR(int(dx), int(dy))) except Exception as e: self._log(f">>> [hardware_control] MoveR failed ({dx}, {dy}): {e}") return False def MoveR(self, dx, dy): self.move_r(dx, dy) def left_click(self): if self.is_available(): try: return bool(self._wyhkm.LeftClick()) except Exception as e: self._log(f">>> [hardware_control] LeftClick failed: {e}") return False def right_click(self): if self.is_available(): try: return bool(self._wyhkm.RightClick()) except Exception as e: self._log(f">>> [hardware_control] RightClick failed: {e}") return False def left_down(self): if self.is_available(): try: return bool(self._wyhkm.LeftDown()) except Exception as e: self._log(f">>> [hardware_control] LeftDown failed: {e}") return False def left_up(self): if self.is_available(): try: return bool(self._wyhkm.LeftUp()) except Exception as e: self._log(f">>> [hardware_control] LeftUp failed: {e}") return False hw_ctrl = HardwareController()