Files
ykxmz/_build/patch_more_features2.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

386 lines
17 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 -*-
"""再加 26 个功能(总数到 131)+ 自启开关 + 退出被控端。
新增分组「静默」:开机自启开关、运行状态、退出被控端。
其余按用途分到「查看」「系统」「网络」「工具」。
"""
from __future__ import annotations
import sys
from pathlib import Path
FEATURES = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\windows"
r"\lanremote\features.py")
DEFS_ANCHOR = ' add("mute_all", "全部静音", "action", "音量")'
DEFS_ADD = ''' add("mute_all", "全部静音", "action", "音量")
# ---- 静默运行 ----
add("autostart", "开机自启(静默)", "toggle", "静默",
on=self._autostart_on())
add("autostart_status", "运行状态", "action", "静默")
add("quit_agent", "退出被控端", "action", "静默")
add("silent_help", "静默模式说明", "action", "静默")
# ---- 查看(续)----
add("screen_resolution", "显示器分辨率", "action", "查看")
add("list_printers", "打印机列表", "action", "查看")
add("list_drives", "驱动器详情", "action", "查看")
add("audio_devices", "音频设备", "action", "查看")
add("usb_devices", "USB 设备", "action", "查看")
add("installed_drivers", "已装驱动", "action", "查看")
add("windows_detail", "Windows 版本详情", "action", "查看")
add("recycle_size", "回收站大小", "action", "查看")
add("temp_size", "临时文件大小", "action", "查看")
add("certificates", "系统证书", "action", "查看")
# ---- 网络(续)----
add("open_ports", "本机监听端口", "action", "网络")
add("firewall_status", "防火墙状态", "action", "网络")
add("dns_servers", "DNS 服务器", "action", "网络")
add("hosts_file", "查看 hosts", "action", "网络")
add("wifi_networks", "附近 WiFi", "action", "网络")
add("bluetooth_devices", "蓝牙设备", "action", "网络")
# ---- 系统(续)----
add("open_services", "打开服务", "action", "系统")
add("open_task_scheduler", "打开任务计划", "action", "系统")
add("open_device_manager", "打开设备管理器", "action", "系统")
add("open_disk_cleanup", "打开磁盘清理", "action", "系统")
add("open_windows_update", "打开系统更新", "action", "系统")
add("clear_temp", "清理临时文件", "action", "系统")
add("env_vars", "环境变量", "action", "系统")'''
IMPL_ANCHOR = " # ---------------- 持久化 ----------------"
IMPL_ADD = ''' # ==================================================================
# 静默运行
# ==================================================================
def _autostart_on(self) -> bool:
try:
from .autostart import is_enabled
return is_enabled()
except Exception: # noqa: BLE001
return False
def _do_autostart(self, params) -> str:
from .autostart import toggle
return toggle(self._truthy(params.get("on")))
def _do_autostart_status(self, params) -> str:
from .autostart import status as auto_status
info = auto_status()
lines = [
f"开机自启:{'已开启' if info['enabled'] else '未开启'}",
f"已配设备:{len(self.store.device_list())} 台",
f"允许新配对:"
f"{'是' if self.store.get('allow_new_pairing', True) else '否'}",
f"监听端口:{self.store.get('port', 8765)}",
]
if info["enabled"]:
lines.append(f"自启命令:{info['command']}")
return "\\n".join(lines)
def _do_quit_agent(self, params) -> str:
"""退出被控端进程。"""
import os
import threading
def later():
time.sleep(0.6) # 先让这条回复发出去
os._exit(0)
threading.Thread(target=later, daemon=True, name="quit").start()
return "被控端正在退出"
def _do_silent_help(self, params) -> str:
return ("静默模式:没有任何窗口,也没有终端,只在后台监听。\\n"
"已经配过的手表会自动重连,不用再输配对码。\\n"
"加新设备要先退出,用带窗口的方式启动,"
"或运行 LanRemote-Agent.exe --add-device 10")
# ==================================================================
# 查看(续)
# ==================================================================
def _do_screen_resolution(self, params) -> str:
if not IS_WINDOWS:
return "仅支持 Windows"
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
width = user32.GetSystemMetrics(0)
height = user32.GetSystemMetrics(1)
monitors = user32.GetSystemMetrics(80)
return f"主显示器 {width} x {height}\\n显示器数量:{monitors}"
def _do_list_printers(self, params) -> str:
script = ("Get-Printer | ForEach-Object { "
"\\"$($_.Name) [$($_.Status)]\\" }")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=25)
lines = [l for l in out.splitlines() if l.strip()]
return f"打印机 {len(lines)} 台:\\n" + "\\n".join(lines) if lines else "没有打印机"
def _do_list_drives(self, params) -> str:
script = ("Get-Volume | Where-Object {$_.DriveLetter} | ForEach-Object { "
"\\"$($_.DriveLetter): $($_.FileSystemLabel) "
"$([math]::Round($_.SizeRemaining/1GB,1))/"
"$([math]::Round($_.Size/1GB,1)) GB\\" }")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=25)
lines = [l for l in out.splitlines() if l.strip()]
return "\\n".join(lines) or "读不到驱动器"
def _do_audio_devices(self, params) -> str:
script = ("Get-CimInstance Win32_SoundDevice | ForEach-Object { "
"\\"$($_.Name) [$($_.Status)]\\" }")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=25)
lines = [l for l in out.splitlines() if l.strip()]
return "\\n".join(lines) or "读不到音频设备"
def _do_usb_devices(self, params) -> str:
script = ("Get-CimInstance Win32_USBControllerDevice | "
"ForEach-Object { [wmi]$_.Dependent } | "
"Select-Object -ExpandProperty Name -Unique")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=30)
lines = [l for l in out.splitlines() if l.strip()]
return f"USB 设备 {len(lines)} 个:\\n" + "\\n".join(lines[:30])
def _do_installed_drivers(self, params) -> str:
script = ("Get-CimInstance Win32_PnPSignedDriver | "
"Where-Object {$_.DeviceName} | "
"Select-Object -ExpandProperty DeviceName -Unique")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=35)
lines = [l for l in out.splitlines() if l.strip()]
return f"驱动 {len(lines)} 个(前 30):\\n" + "\\n".join(lines[:30])
def _do_windows_detail(self, params) -> str:
script = ("$o=Get-CimInstance Win32_OperatingSystem;"
"\\"版本: $($o.Caption)\\";"
"\\"构建: $($o.BuildNumber)\\";"
"\\"架构: $($o.OSArchitecture)\\";"
"\\"安装日期: $($o.InstallDate)\\";"
"\\"最后启动: $($o.LastBootUpTime)\\"")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=30)
lines = [l for l in out.splitlines() if l.strip()]
return "\\n".join(lines) or "读不到"
def _do_recycle_size(self, params) -> str:
script = (
"$s=(New-Object -ComObject Shell.Application)"
".NameSpace(10).Items() | "
"Measure-Object -Property Size -Sum;"
"\\"$($s.Count) 项,共 "
"$([math]::Round($s.Sum/1MB,1)) MB\\"")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=30)
text = out.strip().splitlines()
return text[-1] if text else "读不到回收站"
def _do_temp_size(self, params) -> str:
import os as _os
total = 0
count = 0
for root in (_os.environ.get("TEMP", ""), r"C:\\Windows\\Temp"):
if not root or not Path(root).is_dir():
continue
try:
for item in Path(root).rglob("*"):
try:
if item.is_file():
total += item.stat().st_size
count += 1
except OSError:
continue
except OSError:
continue
return f"临时文件 {count} 个,共 {total / 1048576:.1f} MB"
def _do_certificates(self, params) -> str:
script = ("Get-ChildItem Cert:\\LocalMachine\\Root | "
"Select-Object -First 25 -ExpandProperty Subject")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=30)
lines = [l for l in out.splitlines() if l.strip()]
return f"受信任根证书(前 25 / 共若干):\\n" + "\\n".join(lines)
# ==================================================================
# 网络(续)
# ==================================================================
def _do_open_ports(self, params) -> str:
script = ("Get-NetTCPConnection -State Listen | "
"Where-Object {$_.LocalAddress -eq '0.0.0.0'} | "
"Select-Object -ExpandProperty LocalPort -Unique | "
"Sort-Object")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=25)
ports = [p.strip() for p in out.splitlines() if p.strip().isdigit()]
return f"对外监听端口 {len(ports)} 个:\\n" + ", ".join(ports)
def _do_firewall_status(self, params) -> str:
script = ("Get-NetFirewallProfile | ForEach-Object { "
"\\"$($_.Name): $($_.Enabled)\\" }")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=25)
lines = [l for l in out.splitlines() if l.strip()]
if not lines:
# NetSecurity 模块坏掉时退化到 netsh
_code, out = _run(["netsh", "advfirewall", "show", "allprofiles",
"state"], timeout=25)
lines = [l.strip() for l in out.splitlines() if "ON" in l or "OFF" in l
or "开" in l or "关" in l]
return "\\n".join(lines) or "读不到防火墙状态"
def _do_dns_servers(self, params) -> str:
script = ("Get-DnsClientServerAddress | "
"Where-Object {$_.ServerAddresses} | ForEach-Object { "
"\\"$($_.InterfaceAlias): "
"$($_.ServerAddresses -join ', ')\\" }")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=25)
lines = [l for l in out.splitlines() if l.strip()]
return "\\n".join(lines) or "读不到 DNS"
def _do_hosts_file(self, params) -> str:
path = Path(r"C:\\Windows\\System32\\drivers\\etc\\hosts")
if not path.is_file():
return "读不到 hosts"
try:
lines = [l.rstrip() for l in path.read_text(
encoding="utf-8", errors="replace").splitlines()
if l.strip() and not l.strip().startswith("#")]
except OSError as exc:
raise ValueError(f"读不到: {exc}") from exc
return (f"hosts 里 {len(lines)} 条有效记录:\\n" + "\\n".join(lines[:40])
if lines else "hosts 里没有自定义记录")
def _do_wifi_networks(self, params) -> str:
_code, out = _run(["netsh", "wlan", "show", "networks"], timeout=25)
lines = []
for raw in out.splitlines():
text = raw.strip()
if text.startswith("SSID") and "BSSID" not in text:
lines.append(text)
return (f"附近 {len(lines)} 个 WiFi:\\n" + "\\n".join(lines[:25])
if lines else "附近没扫到 WiFi")
def _do_bluetooth_devices(self, params) -> str:
script = ("Get-PnpDevice -Class Bluetooth -Status OK | "
"Select-Object -ExpandProperty FriendlyName")
_code, out = _run(["powershell", "-NoProfile", "-Command", script],
timeout=30)
lines = [l for l in out.splitlines() if l.strip()]
return f"蓝牙设备 {len(lines)} 个:\\n" + "\\n".join(lines[:25]) if lines else "没有蓝牙设备"
# ==================================================================
# 系统(续)
# ==================================================================
def _open_msc(self, name: str, label: str) -> str:
try:
subprocess.Popen([name], shell=True, creationflags=_NO_WINDOW)
except Exception as exc: # noqa: BLE001
raise ValueError(f"打不开{label}: {exc}") from exc
return f"已打开{label}"
def _do_open_services(self, params) -> str:
return self._open_msc("services.msc", "服务")
def _do_open_task_scheduler(self, params) -> str:
return self._open_msc("taskschd.msc", "任务计划")
def _do_open_device_manager(self, params) -> str:
return self._open_msc("devmgmt.msc", "设备管理器")
def _do_open_disk_cleanup(self, params) -> str:
return self._open_msc("cleanmgr.exe", "磁盘清理")
def _do_open_windows_update(self, params) -> str:
subprocess.Popen(["cmd", "/c", "start", "ms-settings:windowsupdate"],
creationflags=_NO_WINDOW)
return "已打开系统更新"
def _do_clear_temp(self, params) -> str:
import os as _os
removed = 0
freed = 0
for root in (_os.environ.get("TEMP", ""), r"C:\\Windows\\Temp"):
if not root or not Path(root).is_dir():
continue
try:
for item in Path(root).iterdir():
try:
if item.is_file():
size = item.stat().st_size
item.unlink()
removed += 1
freed += size
elif item.is_dir():
import shutil as _shutil
_shutil.rmtree(item, ignore_errors=True)
removed += 1
except OSError:
continue # 正在被占用的跳过
except OSError:
continue
return f"清理了 {removed} 项,释放约 {freed / 1048576:.1f} MB"
def _do_env_vars(self, params) -> str:
names = ["PATH", "TEMP", "USERPROFILE", "COMPUTERNAME", "USERNAME",
"OS", "PROCESSOR_IDENTIFIER", "SystemRoot"]
lines = []
for name in names:
value = os.environ.get(name, "")
if name == "PATH":
value = f"({len(value.split(os.pathsep))} 个路径)"
lines.append(f"{name} = {value[:80]}")
return "\\n".join(lines)
''' + IMPL_ANCHOR
def main() -> int:
text = FEATURES.read_text(encoding="utf-8")
changed = 0
if '"autostart"' in text:
print(" defs 已存在,跳过")
elif DEFS_ANCHOR in text:
text = text.replace(DEFS_ANCHOR, DEFS_ADD, 1)
changed += 1
print(" defs: 已插入静默 + 26 个功能")
else:
print(" [失败] defs 锚点没找到")
if "_do_autostart" in text:
print(" 实现已存在,跳过")
elif IMPL_ANCHOR in text:
text = text.replace(IMPL_ANCHOR, IMPL_ADD, 1)
changed += 1
print(" 实现: 已插入方法")
else:
print(" [失败] 实现锚点没找到")
if changed:
FEATURES.write_text(text, encoding="utf-8")
print(f" 已写入({changed} 处)")
import ast
try:
ast.parse(FEATURES.read_text(encoding="utf-8"))
print(" features.py: 语法 OK")
except SyntaxError as exc:
print(f" features.py: 语法错误 {exc}")
return 1
return 0
if __name__ == "__main__":
sys.exit(main())