Files
ykxmz/windows/lanremote/autostart.py
T
xmz7891 b62ac865ea ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性
被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
2026-10-06 19:01:05 +08:00

109 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""开机自启(当前用户级,不需要管理员)。
写 HKCU\\...\\Run,不碰 HKLM —— 不需要 UAC,也不会影响别的用户。
"""
from __future__ import annotations
import os
import subprocess
import sys
from pathlib import Path
RUN_KEY = r"HKCU\Software\Microsoft\Windows\CurrentVersion\Run"
# 任务管理器「启动」标签页里显示的就是这个名字。
# 用 ykxmz 而不是冒充 "Windows xxx" —— 用的人应该看得出这是什么。
VALUE_NAME = "ykxmz"
# 早期版本用过的名字。开着自启的老用户升级后要把它清掉,别留两条。
LEGACY_VALUE_NAMES = ("LanRemoteAgent",)
_NO_WINDOW = getattr(subprocess, "CREATE_NO_WINDOW", 0)
def executable_path() -> str:
"""要写进注册表的可执行文件路径。"""
if getattr(sys, "frozen", False):
return str(Path(sys.executable).resolve())
# 源码模式:用 pythonw + run_agent.py,这样不会有黑窗
script = Path(__file__).resolve().parent.parent / "run_agent.py"
pythonw = Path(sys.executable).with_name("pythonw.exe")
exe = pythonw if pythonw.is_file() else Path(sys.executable)
return f'"{exe}" "{script}"'
def _run(args: list[str]) -> tuple[int, str]:
try:
proc = subprocess.run(args, capture_output=True, timeout=20,
creationflags=_NO_WINDOW,
encoding="mbcs", errors="replace")
return proc.returncode, ((proc.stdout or "") + (proc.stderr or "")).strip()
except Exception as exc: # noqa: BLE001
return -1, str(exc)
def command_line() -> str:
"""注册表里存的完整命令行。"""
if getattr(sys, "frozen", False):
return f'"{Path(sys.executable).resolve()}" --silent'
script = Path(__file__).resolve().parent.parent / "run_agent.py"
pythonw = Path(sys.executable).with_name("pythonw.exe")
exe = pythonw if pythonw.is_file() else Path(sys.executable)
return f'"{exe}" "{script}" --silent'
def is_enabled() -> bool:
code, out = _run(["reg", "query", RUN_KEY, "/v", VALUE_NAME])
return code == 0 and VALUE_NAME in out
def current_value() -> str:
code, out = _run(["reg", "query", RUN_KEY, "/v", VALUE_NAME])
if code != 0:
return ""
for line in out.splitlines():
if VALUE_NAME in line and "REG_SZ" in line:
return line.split("REG_SZ", 1)[-1].strip()
return ""
def cleanup_legacy() -> list:
"""清掉早期版本留下的自启项(换名字了,别留两条)。"""
removed = []
for name in LEGACY_VALUE_NAMES:
code, _out = _run(["reg", "delete", RUN_KEY, "/v", name, "/f"])
if code == 0:
removed.append(name)
return removed
def enable() -> str:
value = command_line()
code, out = _run(["reg", "add", RUN_KEY, "/v", VALUE_NAME,
"/t", "REG_SZ", "/d", value, "/f"])
if code != 0:
raise ValueError(f"写入开机自启失败: {out[:120]}")
gone = cleanup_legacy()
extra = f"(顺手清掉旧自启项 {', '.join(gone)})" if gone else ""
return f"已开启开机自启(静默模式){extra}\n{value}"
def disable() -> str:
code, out = _run(["reg", "delete", RUN_KEY, "/v", VALUE_NAME, "/f"])
if code != 0 and "找不到" not in out and "unable" not in out.lower():
# 本来就没开,也算成功
pass
return "已关闭开机自启"
def toggle(on: bool) -> str:
return enable() if on else disable()
def status() -> dict:
enabled = is_enabled()
return {
"enabled": enabled,
"command": current_value() if enabled else "",
"expected": command_line(),
}