second refactoring draft
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"""Extracted from octo_updater.py. Keep this module focused on its named responsibility."""
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
def open_directory(path: str) -> None:
|
||||
if sys.platform == "win32":
|
||||
subprocess.Popen(["explorer.exe", path])
|
||||
else:
|
||||
opener = shutil.which("xdg-open")
|
||||
if not opener:
|
||||
raise RuntimeError("xdg-open is required to open directories")
|
||||
subprocess.Popen([opener, path])
|
||||
|
||||
def create_directory_link(link: str, target: str) -> None:
|
||||
if sys.platform == "win32":
|
||||
flags = getattr(subprocess, "CREATE_NO_WINDOW", 0)
|
||||
result = subprocess.run(["cmd", "/c", "mklink", "/J", link, target], capture_output=True, text=True, creationflags=flags)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(result.stderr.strip() or result.stdout.strip() or "mklink failed")
|
||||
return
|
||||
os.symlink(target, link, target_is_directory=True)
|
||||
|
||||
def enable_dpi_awareness() -> None:
|
||||
if sys.platform != "win32":
|
||||
return
|
||||
import ctypes
|
||||
try:
|
||||
user32 = ctypes.windll.user32
|
||||
fn = getattr(user32, "SetProcessDpiAwarenessContext", None)
|
||||
if fn:
|
||||
fn(ctypes.c_void_p(-4))
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
ctypes.windll.shcore.SetProcessDpiAwareness(2)
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
ctypes.windll.user32.SetProcessDPIAware()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def request_defender_exclusion(path: str) -> bool:
|
||||
"""Request a Windows Defender exclusion. Returns False off Windows."""
|
||||
if sys.platform != "win32":
|
||||
return False
|
||||
import ctypes
|
||||
escaped = path.replace("'", "''")
|
||||
command = f"Add-MpPreference -ExclusionPath '{escaped}'"
|
||||
result = ctypes.windll.shell32.ShellExecuteW(
|
||||
None, "runas", "powershell.exe",
|
||||
f'-NoProfile -WindowStyle Hidden -Command "{command}"', None, 0)
|
||||
return result > 32
|
||||
|
||||
|
||||
def launch_executable(executable: str, cwd: str) -> None:
|
||||
"""Launch the managed executable using native process semantics."""
|
||||
if sys.platform != "win32":
|
||||
raise RuntimeError("native Linux game launching is not configured")
|
||||
flags = (getattr(subprocess, "DETACHED_PROCESS", 0)
|
||||
| getattr(subprocess, "CREATE_BREAKAWAY_FROM_JOB", 0))
|
||||
try:
|
||||
subprocess.Popen([executable], cwd=cwd, creationflags=flags, close_fds=True)
|
||||
except OSError:
|
||||
flags &= ~getattr(subprocess, "CREATE_BREAKAWAY_FROM_JOB", 0)
|
||||
subprocess.Popen([executable], cwd=cwd, creationflags=flags, close_fds=True)
|
||||
|
||||
|
||||
def display_info() -> dict:
|
||||
"""Return primary display dimensions and refresh rate on Windows."""
|
||||
if sys.platform != "win32":
|
||||
raise RuntimeError("display information is not implemented for this platform")
|
||||
import ctypes
|
||||
class DEVMODE(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("dmDeviceName", ctypes.c_wchar * 32), ("dmSpecVersion", ctypes.c_ushort),
|
||||
("dmDriverVersion", ctypes.c_ushort), ("dmSize", ctypes.c_ushort),
|
||||
("dmDriverExtra", ctypes.c_ushort), ("dmFields", ctypes.c_ulong),
|
||||
("dmPositionX", ctypes.c_long), ("dmPositionY", ctypes.c_long),
|
||||
("dmDisplayOrientation", ctypes.c_ulong), ("dmDisplayFixedOutput", ctypes.c_ulong),
|
||||
("dmColor", ctypes.c_short), ("dmDuplex", ctypes.c_short),
|
||||
("dmYResolution", ctypes.c_short), ("dmTTOption", ctypes.c_short),
|
||||
("dmCollate", ctypes.c_short), ("dmFormName", ctypes.c_wchar * 32),
|
||||
("dmLogPixels", ctypes.c_ushort), ("dmBitsPerPel", ctypes.c_ulong),
|
||||
("dmPelsWidth", ctypes.c_ulong), ("dmPelsHeight", ctypes.c_ulong),
|
||||
("dmDisplayFlags", ctypes.c_ulong), ("dmDisplayFrequency", ctypes.c_ulong),
|
||||
]
|
||||
dm = DEVMODE()
|
||||
dm.dmSize = ctypes.sizeof(DEVMODE)
|
||||
ctypes.windll.user32.EnumDisplaySettingsW(None, -1, ctypes.byref(dm))
|
||||
return {"width": dm.dmPelsWidth, "height": dm.dmPelsHeight,
|
||||
"refresh_rate": dm.dmDisplayFrequency}
|
||||
Reference in New Issue
Block a user