Files
ykxmz/_build/package.py
T
xmz7891 b705216e4a ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞
- 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀?
鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException
- 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴?
鏈嶅姟鍣ㄧ
- 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級
- 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯
- 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺?
鏂囨。
- 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
2026-10-06 19:01:05 +08:00

222 lines
7.8 KiB
Python
Raw Permalink 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 -*-
"""统一打包:被控端 + 手表端(已内置诊断)+ 文档。
注意:遥控诊断原来是一个单独的 App,现在已合并进手表主程序
(主界面 ->「设备诊断」按钮),所以不再单独出 APK。
产物(都在 dist/):
ykxmz-Windows.zip 被控端(解压即用,内含工具箱)
LanRemote-Watch-1.3.0.apk 手表控制端(含设备诊断)
LanRemote-1.3.0-完整包.zip 以上全部 + 预览图 + 文档
被控端目录结构(解压后):
LanRemote-Agent/
├── (已移除) <- 双击这个,所有功能都在菜单里
├── ykxmz.exe
├── _internal/
├── xffhq.bat
├── wlzj.bat / .py
├── 使用说明.txt
└── 先看这个.txt
"""
from __future__ import annotations
import shutil
import sys
import zipfile
from pathlib import Path
VERSION = "1.4.0"
ROOT = Path(__file__).resolve().parent.parent
DIST = ROOT / "dist"
EXE_DIR = ROOT / "dist_exe" / "ykxmz"
TOOLS = ROOT / "tools"
PREVIEW = ROOT / "dist_preview"
README = ROOT / "README.md"
TEST_REPORT = DIST / "测试报告.txt"
APK = DIST / f"LanRemote-Watch-{VERSION}.apk"
AGENT_ZIP = DIST / "ykxmz-Windows.zip"
BUNDLE = DIST / f"LanRemote-{VERSION}-完整包.zip"
# 会被放进被控端目录的工具(工具箱必须排第一)
TOOL_FILES = (
"fxfhq.bat",
"wlzj.bat",
"xffhq.bat",
)
QUICKSTART = f"""========================================================
局域网遥控 · 被控端(Windows) 版本 {VERSION}
========================================================
*** 不需要装 Python ***
这个目录里的 ykxmz.exe 是编译好的独立程序,
拷到任何一台 Windows 电脑上双击就能跑。
【装完之后怎么用】
1) 双击 ykxmz.exe
2) 弹出一个小窗口,让你输入 6 位数字(配对码)
自己定一个记得住的,比如 789113
下面有两个勾:
[x] 设置开机自启(开机后自动在后台运行)
[x] 顺便放行防火墙(需要管理员确认一次)
3) 点「确定,开始使用」
→ 会弹一次 Windows 的管理员确认(UAC),点「是」
→ 黑色终端窗口一闪,它在一键修复防火墙
→ 窗口全部消失,程序转入后台静默运行
4) 手表上打开 App → 点「自动搜索电脑」→ 点搜到的电脑
→ 输入你设的 6 位数字
5) 以后开机就直接在后台跑,屏幕上什么都没有;
手表打开 App 会自动连上,数字都不用再输。
【目录里这几个文件】
ykxmz.exe 主程序。双击就是上面第 1 步。
wlzj.bat 网络自检。连不上时跑它,看手表的包到底有没有到电脑。
xffhq.bat 一键修复防火墙。右键 →「以管理员身份运行」。
fxfhq.bat 同上,是程序自动生成的放行脚本,也可以右键提权运行。
先看这个.txt / 使用说明.txt 就是本文。
三个 .bat 都不需要装 Python。
【连不上?按这个顺序来】
1) 确认被控端在跑
任务管理器里能看到 ykxmz.exe
没有的话:ykxmz.exe --setup
2) 右键 xffhq.bat →「以管理员身份运行」,点「是」
3) 还不行 → 双击 wlzj.bat(网络自检)
它会监听 90 秒,看手表的请求有没有到达这台电脑:
收到连接 -> 网络是通的,问题在电脑这边
一直没动静 -> 包没到电脑,多半路由器开了「AP 隔离」
4) 手表上:首页「连不上?点这里诊断」
【命令行参数】(一般用不到)
ykxmz.exe --setup 重新打开设置窗口
ykxmz.exe --silent 直接静默运行
ykxmz.exe --add-device 10 静默运行 + 开放 10 分钟配对
ykxmz.exe --autostart on|off 开关开机自启
ykxmz.exe --status 看当前状态
ykxmz.exe --netcheck 90 网络自检(同 wlzj.bat)
ykxmz.exe --fix-firewall 提权修复防火墙
ykxmz.exe --reset-devices 清空已配对设备
【关于安全】
配对码是你自己设的,只存在这台电脑的 data\\settings.json 里。
一台设备都没配对过时配对是开着的(否则你设完码会连不上自己);
第一台配对成功后自动关闭。
配错 10 次锁 5 分钟(按来源 IP 分别计,别人锁不住你)。
屏幕共享时右下角会出现一条红色小提示 ——
这是故意的:有人在看你的屏幕时,屏幕前面的人应该知道。
"""
def clean_runtime_state() -> None:
"""打包前清掉运行时产生的东西,保持交付干净。"""
for name in ("data", "received"):
target = EXE_DIR / name
if target.exists():
shutil.rmtree(target, ignore_errors=True)
print(f" 已清理 {target.relative_to(ROOT)}")
for stale in ("fxfhq.bat",):
path = EXE_DIR / stale
if path.exists():
path.unlink()
print(f" 已清理 {stale}")
def install_tools() -> list[str]:
installed = []
for name in TOOL_FILES:
source = TOOLS / name
if source.is_file():
shutil.copy2(source, EXE_DIR / name)
installed.append(name)
else:
print(f" [警告] 缺少工具: {name}")
return installed
def zip_dir(source: Path, target: Path, arc_prefix: str = "") -> int:
files = [p for p in source.rglob("*") if p.is_file()]
with zipfile.ZipFile(target, "w", zipfile.ZIP_DEFLATED, compresslevel=6) as zf:
for path in files:
rel = path.relative_to(source)
arc = str(Path(arc_prefix) / rel) if arc_prefix else str(rel)
zf.write(path, arc)
print(f" {target.name} ({target.stat().st_size / 1048576:.1f} MB, {len(files)} 个文件)")
return len(files)
def main() -> int:
missing = []
if not EXE_DIR.is_dir():
missing.append(f"被控端产物目录 {EXE_DIR}(先运行 windows\\build_exe.ps1)")
if not APK.is_file():
missing.append(f"{APK.name}(先运行 android\\build_apk.ps1)")
if missing:
print("缺少产物:")
for item in missing:
print(f" - {item}")
return 1
DIST.mkdir(parents=True, exist_ok=True)
print("清理测试残留:")
clean_runtime_state()
print("\n安装工具到被控端目录:")
installed = install_tools()
for name in installed:
print(f" + {name}")
(EXE_DIR / "使用说明.txt").write_text(QUICKSTART, encoding="utf-8")
(EXE_DIR / "先看这个.txt").write_text(QUICKSTART, encoding="utf-8")
print(" + 使用说明.txt / 先看这个.txt")
print("\n打包被控端:")
count = zip_dir(EXE_DIR, AGENT_ZIP, arc_prefix="ykxmz")
print("\n打包完整交付:")
with zipfile.ZipFile(BUNDLE, "w", zipfile.ZIP_DEFLATED, compresslevel=6) as zf:
zf.writestr("先看这个.txt", QUICKSTART)
zf.write(APK, f"1-手表控制端/{APK.name}")
zf.write(AGENT_ZIP, f"2-电脑被控端/{AGENT_ZIP.name}")
if PREVIEW.is_dir():
for shot in sorted(PREVIEW.glob("*.png")):
zf.write(shot, f"3-界面预览/{shot.name}")
if README.is_file():
zf.write(README, "使用说明.md")
if TEST_REPORT.is_file():
zf.write(TEST_REPORT, "测试报告.txt")
print(f" {BUNDLE.name} ({BUNDLE.stat().st_size / 1048576:.1f} MB)")
print("\n" + "=" * 62)
print(f"交付内容(版本 {VERSION}):")
for path in (APK, AGENT_ZIP, BUNDLE):
print(f" {path.stat().st_size / 1048576:7.2f} MB {path.name}")
print(f"\n被控端包内含 {count} 个文件,工具箱等 {len(installed)} 个工具已就位。")
print("遥控诊断已合并进手表主程序,不再单独出包。")
return 0
if __name__ == "__main__":
sys.exit(main())