import asyncio import os import subprocess import webbrowser import logging RIOT_CLIENT_PATHS = [ r"C:\Riot Games\Riot Client\RiotClientServices.exe", r"D:\Riot Games\Riot Client\RiotClientServices.exe" ] def find_install_path(exe_name: str) -> str | None: if "RiotClientServices" in exe_name: for path in RIOT_CLIENT_PATHS: if os.path.exists(path): return path # Try generic fallback try: import shutil return shutil.which(exe_name) except Exception: pass return None async def launch_application(exe_name: str): """ Launch an application in the background non-blocking. """ logging.info(f"Attempting to launch application: {exe_name}") try: # Offload to thread to prevent blocking await asyncio.to_thread(_launch_sync, exe_name) except Exception as e: logging.error(f"Failed to launch {exe_name}: {e}") def _launch_sync(exe_name: str): path = find_install_path(exe_name) if not path: logging.error(f"Executable {exe_name} not found.") return try: # We use CREATE_NO_WINDOW or default creation flags for background launch # Actually, we WANT the window to appear for the user, so we just use Popen. subprocess.Popen([path]) logging.info(f"Successfully launched {path}") except Exception as e: logging.error(f"Subprocess launch failed: {e}") async def open_url(url: str): """ Open a URL in the default browser in a non-blocking way. """ logging.info(f"Opening URL: {url}") try: await asyncio.to_thread(webbrowser.open, url) except Exception as e: logging.error(f"Failed to open URL {url}: {e}")