Tranxet · RoxetOS 兼容层 ROXETOS COMPAT // 免登录桌面
免登录桌面兼容层:放入应用即运行,完整支持 RoxetOS SDK。
从 v1 中提取出的独立兼容层:启动后无需登录,直接进入 RoxetOS 桌面;把 Python、HTML、Flask 应用放进 sys/ 目录,即可在桌面窗口(弹窗)中运行,并完整支持 RoxetOS SDK。
特性
- 免登录:自动创建本地
guest用户,打开即桌面,无登录页。 - 三种应用格式:文件夹应用(Flask / Python / H5)、直接丢单个
.py/.html文件到sys/、单文件 Flask 配同名xxx.flask.json。 - 桌面窗口运行:点击桌面图标即弹窗打开,支持拖拽、缩放、最小化、最大化。
- SDK 全功能:打开应用、窗口控制、桌面通知、原生弹窗、结果文件存储、多窗口协同。
- 完整内置应用:云盘、终端、应用商店、浏览器代理、设置、计算器、便签。
- 稳健的服务管理:Flask 服务启动后等待端口就绪才返回;进程按进程树清理,不残留僵尸进程。
快速开始
方式一:Windows 双击
start.bat方式二:PowerShell
.\start.ps1首次启动会自动创建 venv、安装 requirements.txt,然后打开浏览器:
http://127.0.0.1:8000方式三:手动启动(依赖已装好)
python server.py --host 0.0.0.0 --port 8000server.py 支持从任意目录启动(自动把自身目录加入模块搜索路径)。
目录结构
compat/
server.py # 启动入口(FastAPI + Uvicorn)
roxetos/ # 兼容层后端
frontend/ # 预构建桌面前端(含 /sdk/roxet-bridge.js)
sys/ # 应用目录:把 Py / HTML / Flask 应用放这里
data/ # 本地数据库(自动创建)
user/ # 用户数据:云盘、workspace、SDK 结果(自动创建)
start.ps1 / start.bat
requirements.txt
selftest.ps1 / ws_check.py # 自检在 sys/ 里放应用
1. 文件夹应用(推荐)
sys/MyApp/
manifest.json
main.py # Python 终端应用
app.py # 或 Flask 服务应用(manifest 声明 runtime: flask + port)
index.html # 或 H5 应用(没有 Python 入口时)
logo.png # 可选图标Flask 服务应用 manifest 示例:
{
"name": "MyApp",
"icon": "logo.png",
"runtime": "flask",
"port": 5010,
"start_path": "/",
"platforms": ["win32", "linux", "darwin"]
}2. 直接放单个文件(无需建文件夹)
sys/
hello.py # Python 终端应用,应用 id = hello
hello.html # H5 应用,应用 id = hello
hello.flask.json # (可选)hello.py 作为 Flask 服务应用时的配置
hello.manifest.json # (可选)名字、图标、platforms、terminal 等单个 .py 默认作为终端应用运行;若同名 xxx.flask.json / xxx.manifest.json 声明了 runtime: "flask" 和 port,则按 Flask 服务应用启动。单个 .html 直接作为 H5 应用。
manifest 字段
| 字段 | 说明 |
|---|---|
name | 桌面显示名称 |
icon | 图标:相对路径(如 logo.png)或宿主资源路径(如 /img/logo.png) |
runtime | flask / node / express / 留空 |
port | 服务应用端口(Flask/Node 必填) |
start_path | 打开时拼到服务 URL 后的路径,默认 / |
platforms | 支持平台列表,如 ["win32","linux","darwin"] |
terminal | Python 终端应用交互配置,见下 |
终端应用交互配置示例:
{
"terminal": {
"input": "terminal",
"echoInput": true
}
}input 可选:stdin(底部输入框)、terminal(直接在终端区输入)、key(按键模式,配合 controls 快捷按钮)。
SDK 能力
页面如何加载桥接脚本
H5 应用(由宿主同源提供)直接相对路径加载:
<script src="/sdk/roxet-bridge.js"></script>Flask 应用(独立端口)从宿主加载:
<script>
const hostFromQuery = new URLSearchParams(location.search).get("__roxet_host")
const bridgeOrigin = hostFromQuery || `${location.protocol}//${location.hostname}:8000`
const bridge = document.createElement("script")
bridge.src = `${bridgeOrigin}/sdk/roxet-bridge.js`
bridge.onload = () => {
const sdk = window.Roxet && window.Roxet.registerShellBridge ? window.Roxet.registerShellBridge() : null
// 在这里绑定按钮事件
}
document.head.appendChild(bridge)
</script>宿主默认运行在 8000 端口;若改用其他端口,访问应用时带 ?__roxet_host=http://<宿主地址>:<端口> 即可(示例代码会自动读取)。SDK 接口
| 能力 | 调用 | 说明 |
|---|---|---|
| 打开应用 | sdk.openApp(appId) | 打开系统/自定义应用 |
| 窗口控制 | sdk.focusWindow() / sdk.minimizeWindow() / sdk.closeWindow() | 聚焦/最小化/关闭当前窗口 |
| 桌面通知 | sdk.notify(message, type) | type:info / success / warning / error |
| 原生弹窗 | sdk.ui.alert() / sdk.ui.confirm() / sdk.ui.prompt() / sdk.ui.custom() | 宿主渲染的弹窗 |
| 结果存储 | sdk.storage.list/read/write/remove(appId, path) | 读写 user/guest/sys/<appId>/result/ |
| 协同 | sdk.sync.join({appId}) | channel.send / requestSnapshot / leave / onMessage |
最小 H5 示例:
<script src="/sdk/roxet-bridge.js"></script>
<script>
const sdk = window.Roxet?.registerShellBridge?.()
const appId = "MyApp"
document.getElementById("save").onclick = async () => {
await sdk.storage.write(appId, "state.json", JSON.stringify({ at: Date.now() }))
sdk.notify("保存成功", "success")
}
document.getElementById("dialog").onclick = async () => {
const ok = await sdk.ui.confirm({ title: "确认", message: "要继续吗?" })
sdk.notify(ok ? "已确认" : "已取消", "info")
}
</script>内置示例
sys/ 里已带 5 个示例,启动后桌面直接可见:
| 应用 | 类型 | 说明 |
|---|---|---|
| SDKDemo | Flask 文件夹应用(5010) | 演示全部 SDK 能力:原生弹窗、存储、协同 |
| JetAgent | H5 文件夹应用 | 静态 H5 页面 |
| Python 单文件示例 | hello_py.py 终端应用 | REPL 交互,演示 stdin 回显 |
| HTML 单文件示例 | hello_html.html H5 | 演示通知、弹窗、SDK 存储 |
| Flask 单文件示例 | flask_demo.py(5011) | 演示通知、弹窗、打开其他应用 |
常见问题
打开 Flask 应用提示“127.0.0.1 拒绝访问”
已内置“等待服务就绪”逻辑:打开窗口前会轮询应用端口,直到真正监听才返回。若仍失败,多半是端口被其他进程占用,检查:
Get-NetTCPConnection -LocalPort 5011 -State ListenFlask 页面按钮没反应
通常是 SDK 桥接脚本没加载成功。确认页面脚本来源是宿主地址(默认 http://<hostname>:8000/sdk/roxet-bridge.js),不是 Flask 自身端口;宿主换了端口时给应用 URL 加 ?__roxet_host=...。
协同(sync)连不上
桥接脚本会由宿主动态注入端口,协同 WebSocket 自动跟随宿主端口,无需手动改地址。
应用商店显示什么
商店客户端连接服务器 http://lingtun.com/store/apps.json,应用列表以服务器数据为准(“一期软件”按服务器实际清单展示)。界面不显示作者,商店成员含“林落泽”。预置应用不能从商店卸载(避免误删);安装外部软件需要联网。
自检
.\selftest.ps1 -PythonPath <python.exe> [-Port 8010]自检覆盖:免登录会话、sys 应用识别(文件夹 + 单文件)、桥接脚本端口注入、桌面首页与图标、SDK 存储读写、原生弹窗分类、Flask 服务拉起与页面访问、/ws/run Python 终端应用运行与输入回显、SDK 协同广播与快照。
配置
| 环境变量 | 默认值 | 说明 |
|---|---|---|
ROXETOS_HOST | 0.0.0.0 | 宿主监听地址 |
ROXETOS_PORT | 8000 | 宿主端口 |
ROXETOS_SESSION_SECRET | 内置开发密钥 | 会话签名密钥,生产环境请修改 |
命令行参数优先级更高:python server.py --host 127.0.0.1 --port 9000。