# -*- 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())