# OSU Public Wi-Fi Login 适用于 Windows 11 的 OSU Wi-Fi 后台守护程序。它会持续监控无线网络状态,并按配置自动修复连接。 这个重写版本选择了 Python,而不是 PowerShell 或 Rust,原因是: - `WiFi@OSU` Captive Portal 可以直接用 HTTP 表单提交流程处理,不依赖浏览器驱动 - 如果 portal 页面结构比较复杂,程序会自动回退到 Playwright 驱动已安装的 Microsoft Edge - Windows 下调用 `netsh`、修改注册表、接 WinSW 都很直接 - 后续想打包成单文件 `exe` 也比较方便 ## 功能 - 后台常驻运行,而不是一次性触发 - 可在 `WiFi@OSU` 和 `eduroam` 之间切换 - 支持 YAML 配置网络类型和检查/重试时间 - `WiFi@OSU` 模式下: - 启动时如果 Wi-Fi 还没连上,会主动尝试连接目标网络 - 可选启用随机 MAC - 可按周期刷新 MAC 并重连 - 自动打开 Captive Portal 并完成条款确认/登录 - `eduroam` 模式下: - 启动时如果 Wi-Fi 还没连上,会主动尝试连接目标网络 - 使用系统已保存的凭据 - 可恢复为硬件 MAC - 仅做断线检测和自动重连 - 支持 WinSW 包装为 Windows 服务 ## 项目结构 ```text main.py CLI 入口 osu_wifi_login/config.py YAML 配置加载 osu_wifi_login/windows.py netsh / 注册表 / 连通性检测 osu_wifi_login/portal.py HTTP Portal 登录 osu_wifi_login/service.py 常驻监控与恢复逻辑 config.example.yaml 配置示例 winsw/ WinSW 服务模板 ``` ## 环境要求 - Windows 11 x86-64 - Python 3.11+ - Microsoft Edge - [uv](https://docs.astral.sh/uv/) ## 安装 ```powershell uv sync ``` 仓库已经附带默认的 `config.yaml`,直接编辑即可;如果想恢复模板,也可以参考 `config.example.yaml`。 如果 `WiFi@OSU` portal 页面较复杂,运行时会使用 Playwright 调用本机已安装的 Edge,所以第一次改完依赖后需要先完成一次 `uv sync`。 ## 配置 默认配置文件是根目录下的 `config.yaml`。 最常用的项如下: ```yaml selected_network: wifi_osu wifi_interface_name: Wi-Fi allow_unsafe_mac_changes: false randomize_mac_on_start: false networks: wifi_osu: ssid: WiFi@OSU profile_name: WiFi@OSU requires_portal_login: true randomize_mac: false restore_hardware_mac: false auto_create_open_profile: true mac_refresh_hours: 6 eduroam: ssid: eduroam profile_name: eduroam requires_portal_login: false randomize_mac: false restore_hardware_mac: true auto_create_open_profile: false connectivity_checks: - url: http://example.com/ expected_status: 200 expected_text: Example Domain require_final_url_match: true allow_redirects: false ``` 说明: - `selected_network` 设为 `wifi_osu` 或 `eduroam` - `wifi_interface_name` 一般是 `Wi-Fi`,如果你的系统接口名不同,需要改成实际值 - `profile_name` 是 Windows 已保存的 WLAN 配置名,通常与 SSID 相同 - `auto_create_open_profile` 适合 `WiFi@OSU` 这类开放网络;如果本机还没有保存过 profile,程序会先自动创建一个基础 profile 再连接 - `connectivity_checks` 默认使用像 `example.com` 这样的普通页面,不再使用 Windows/Apple/Firefox 的系统探针地址,避免被 portal 白名单误判成“已联网” - `allow_unsafe_mac_changes` 默认关闭;关闭时不会写注册表改 `NetworkAddress` - `randomize_mac` 和 `restore_hardware_mac` 都只有在 `allow_unsafe_mac_changes: true` 时才会生效 - 某些无线网卡驱动在修改 MAC 时会直接蓝屏,建议默认保持关闭 - `connect_retry_cooldown_seconds` 控制“Wi-Fi 完全没连上时”主动重连的频率 - `disconnect_grace_seconds` 表示断线多久后开始强制恢复 - `connection_timeout_seconds` 会用于登录后等待网络放行,默认给 captive portal 留 60 秒 - `mac_refresh_hours` 只对 `WiFi@OSU` 生效 ## 运行 前台调试运行: ```powershell .\.venv\Scripts\python.exe main.py --config config.yaml ``` 只跑一次检查: ```powershell .\.venv\Scripts\python.exe main.py --config config.yaml --once ``` ## 服务逻辑 程序每轮会做这些事: 1. 检查当前是否连在目标 SSID 上 2. 如果 Wi-Fi 完全没连上,先直接尝试连接目标网络 3. 如果是 `WiFi@OSU`,刚连上后会主动探测 captive portal;检测到登录页就立刻登录 4. 检查是否真的能上网 5. 如果断线或异常持续超过阈值,则重启 Wi-Fi 网卡并重新连接 6. 如果你显式开启了高风险 MAC 改写,才会在启动时和刷新周期到达时改 MAC 并重连 ## 管理员权限 以下操作需要管理员权限: - 修改 `NetworkAddress` 注册表项 - 为 `WiFi@OSU` 随机化 MAC - 清除随机 MAC,恢复硬件 MAC - 重启无线网卡 其中 MAC 相关操作在部分驱动上可能导致蓝屏;现在默认关闭,只有在你明确打开 `allow_unsafe_mac_changes: true` 后才会执行。 ## 编译发布 推荐使用 PyInstaller 的 `onedir` 模式发布。这个模式会生成一个完整目录,里面包含 `exe`、Python 运行时、第三方依赖和 Playwright 驱动文件;目标机器仍需要安装 Microsoft Edge,但不需要安装 Python、uv 或项目依赖。 ```powershell uv sync uv run pyinstaller --noconfirm --clean --onedir --name osu-wifi-login main.py ``` 生成结果位于: ```text dist\osu-wifi-login\osu-wifi-login.exe ``` 把 `config.yaml` 放到同一个发布目录中: ```powershell Copy-Item config.yaml dist\osu-wifi-login\config.yaml ``` 发布目录最终至少应包含: ```text dist\osu-wifi-login\ osu-wifi-login.exe config.yaml _internal\ ``` 前台验证: ```powershell .\dist\osu-wifi-login\osu-wifi-login.exe --config .\dist\osu-wifi-login\config.yaml --once ``` 也可以生成真正的单文件 `exe`: ```powershell uv run pyinstaller --noconfirm --clean --onefile --name osu-wifi-login main.py ``` 不过不建议优先使用 `onefile`。Playwright 会在运行时解包和查找驱动文件,`onedir` 更稳定;`onefile` 虽然只有一个 `exe`,但启动更慢,也更容易遇到服务账户临时目录权限问题。无论使用哪种模式,Microsoft Edge 仍需要由系统提供,因为程序使用的是已安装 Edge 渠道。 ## WinSW 服务 仓库中已经提供: - [winsw/osu-wifi-login.xml](/C:/Users/yuanzhe/src/OSU-Public-Wi-Fi-Login/winsw/osu-wifi-login.xml) - [winsw/README.md](/C:/Users/yuanzhe/src/OSU-Public-Wi-Fi-Login/winsw/README.md) ### 使用编译后的 exe 1. 下载 WinSW x64 可执行文件 2. 将 WinSW 重命名为 `osu-wifi-login-service.exe` 3. 将 `osu-wifi-login-service.exe` 放入 `dist\osu-wifi-login\` 4. 在同一目录创建 `osu-wifi-login-service.xml` `dist\osu-wifi-login\osu-wifi-login-service.xml` 示例: ```xml osu-wifi-login OSU Wi-Fi Login Service Keeps WiFi@OSU or eduroam connected and logs into the captive portal when needed. %BASE%\osu-wifi-login.exe --config "%BASE%\config.yaml" %BASE% 1048576 8 30 sec ``` 以管理员 PowerShell 安装并启动: ```powershell Set-Location .\dist\osu-wifi-login .\osu-wifi-login-service.exe install .\osu-wifi-login-service.exe start ``` 查看状态、停止、卸载: ```powershell .\osu-wifi-login-service.exe status .\osu-wifi-login-service.exe stop .\osu-wifi-login-service.exe uninstall ``` ### 服务账户建议 默认不写 `` 时,WinSW 通常使用 `LocalSystem`。这个程序需要能访问 WLAN profile、启动 Edge 自动化并执行 `netsh`,更推荐使用你自己的 Windows 用户运行服务。 如果要指定服务账户,在 XML 中加入: ```xml . YOUR_WINDOWS_ACCOUNT YOUR_PASSWORD true ``` 如果你保持 `allow_unsafe_mac_changes: false`,通常不需要管理员权限来修改 MAC;但重启网卡和某些 `netsh` 操作仍可能需要提升权限。若服务日志提示权限不足,再改用管理员账户运行服务。 ## 当前注意事项 - `WiFi@OSU` 的 Captive Portal 表单字段仍然基于当前已知页面结构;如果学校改版,可能需要微调 YAML 或代码 - 现在默认不依赖 `msedgedriver`;复杂页面会自动回退到 Playwright + 已安装 Edge