Files
PROXY_GOD_MAC/proxy_chain_manager/windows_task.py
2026-05-23 22:09:43 -07:00

134 lines
4.1 KiB
Python

from __future__ import annotations
import subprocess
import sys
from pathlib import Path
import plistlib
from .paths import app_data_dir
TASK_NAME = "ProxyChainManagerAutoStart"
LAUNCH_AGENT_ID = "local.proxy-god.mac"
def _launch_agent_path() -> Path:
p = Path.home() / "Library" / "LaunchAgents"
p.mkdir(parents=True, exist_ok=True)
return p / f"{LAUNCH_AGENT_ID}.plist"
def _mac_program_arguments() -> list[str]:
root = Path(__file__).resolve().parent.parent
return [str(root / "scripts" / "run_proxy_god.sh")]
def _install_launch_agent() -> tuple[bool, str]:
plist_path = _launch_agent_path()
data = {
"Label": LAUNCH_AGENT_ID,
"ProgramArguments": _mac_program_arguments(),
"RunAtLoad": True,
"WorkingDirectory": str(Path(__file__).resolve().parent.parent),
"StandardOutPath": str(Path.home() / "Library" / "Logs" / "ProxyGod.out.log"),
"StandardErrorPath": str(Path.home() / "Library" / "Logs" / "ProxyGod.err.log"),
}
try:
plist_path.write_bytes(plistlib.dumps(data))
subprocess.run(["launchctl", "unload", str(plist_path)], capture_output=True, text=True, timeout=10)
r = subprocess.run(["launchctl", "load", str(plist_path)], capture_output=True, text=True, timeout=10)
out = (r.stdout or "") + (r.stderr or "")
return r.returncode == 0, out.strip() or "LaunchAgent installed"
except Exception as e:
return False, str(e)
def _uninstall_launch_agent() -> tuple[bool, str]:
plist_path = _launch_agent_path()
try:
subprocess.run(["launchctl", "unload", str(plist_path)], capture_output=True, text=True, timeout=10)
plist_path.unlink(missing_ok=True)
return True, "LaunchAgent removed"
except Exception as e:
return False, str(e)
def _write_launcher_cmd() -> Path:
"""Create a stable launcher script so Task Scheduler does not need fragile quoting."""
if getattr(sys, "frozen", False):
exe = Path(sys.executable).resolve()
body = f'@echo off\r\nstart "" /B "{exe}"\r\n'
else:
py = Path(sys.executable).resolve()
if py.name.lower() == "python.exe":
cand = py.with_name("pythonw.exe")
if cand.is_file():
py = cand
root = Path(__file__).resolve().parent.parent
run_py = (root / "run.py").resolve()
body = f'@echo off\r\n"{py}" "{run_py}"\r\n'
p = app_data_dir() / "launch_proxy_chain_manager.cmd"
p.write_text(body, encoding="utf-8")
return p
def install_logon_task() -> tuple[bool, str]:
if sys.platform == "darwin":
return _install_launch_agent()
launcher = _write_launcher_cmd()
tr = str(launcher)
try:
r = subprocess.run(
[
"schtasks",
"/Create",
"/F",
"/TN",
TASK_NAME,
"/TR",
tr,
"/SC",
"ONLOGON",
"/RL",
"LIMITED",
],
capture_output=True,
text=True,
timeout=60,
)
out = (r.stdout or "") + (r.stderr or "")
return r.returncode == 0, out.strip() or ("OK" if r.returncode == 0 else "Failed")
except Exception as e:
return False, str(e)
def uninstall_logon_task() -> tuple[bool, str]:
if sys.platform == "darwin":
return _uninstall_launch_agent()
try:
r = subprocess.run(
["schtasks", "/Delete", "/F", "/TN", TASK_NAME],
capture_output=True,
text=True,
timeout=60,
)
out = (r.stdout or "") + (r.stderr or "")
return r.returncode == 0, out.strip() or ("OK" if r.returncode == 0 else "Failed")
except Exception as e:
return False, str(e)
def task_exists() -> bool:
if sys.platform == "darwin":
return _launch_agent_path().is_file()
try:
r = subprocess.run(
["schtasks", "/Query", "/TN", TASK_NAME],
capture_output=True,
text=True,
timeout=30,
)
return r.returncode == 0
except Exception:
return False