mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 21:14:21 +08:00
8c48b35c08
- 新增从 SecRandom 和 xlsx 导入学生名单功能 - 添加 IPC 通信模块用于与 SecRandom 交互 - 实现 xlsx 文件解析和姓名列选择功能 - 优化构建流程,添加 CI/CD 相关脚本 - 移除 snap 构建目标 - 更新 ESLint 配置忽略新增脚本文件
131 lines
3.6 KiB
JavaScript
131 lines
3.6 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* SecRandom IPC URL 发送脚本 (Node.js 版本)
|
||
*
|
||
* 用途
|
||
* - 向本机正在运行的 SecRandom 实例发送 URL(例如 SecRandom://settings)
|
||
* - 通过“命名 IPC 通道”连接(Windows 命名管道 / Linux socket),无需端口
|
||
*
|
||
* 前提
|
||
* - SecRandom 主程序已启动,并已启动 URL IPC 服务端
|
||
*
|
||
* 基本用法(Windows / Linux 通用)
|
||
* - 发送打开设置页:
|
||
* node secrandom_ipc_send_url.js "SecRandom://settings"
|
||
* - 发送切换页面:
|
||
* node secrandom_ipc_send_url.js "SecRandom://main/lottery"
|
||
*
|
||
* 参数说明
|
||
* - url:要发送的 URL(大小写不敏感)
|
||
* --ipc-name:目标通道名,默认 SecRandom.secrandom
|
||
* - Windows 对应:\\.\pipe\SecRandom.secrandom
|
||
* - Linux 对应:/tmp/SecRandom.secrandom.sock
|
||
*
|
||
* 返回与退出码
|
||
* - 输出:打印服务端响应 JSON
|
||
* - 退出码:
|
||
* - 0:success 为 true
|
||
* - 2:success 为 false(例如命令不支持/被拒绝/服务端返回失败)
|
||
* - 1:脚本运行异常(例如连接失败、序列化失败等)
|
||
*/
|
||
|
||
const net = require('net')
|
||
|
||
function parseArgs(argv) {
|
||
const out = { url: '', ipcName: 'SecRandom.secrandom', timeout: 5000 }
|
||
const args = Array.from(argv)
|
||
for (let i = 0; i < args.length; i++) {
|
||
const a = String(args[i] ?? '')
|
||
if (a === '--help' || a === '-h') return { help: true }
|
||
|
||
if (a === '--ipc-name') {
|
||
out.ipcName = String(args[i + 1] ?? '').trim() || out.ipcName
|
||
i++
|
||
continue
|
||
}
|
||
if (a.startsWith('--ipc-name=')) {
|
||
out.ipcName = a.slice('--ipc-name='.length).trim() || out.ipcName
|
||
continue
|
||
}
|
||
|
||
if (a === '--timeout') {
|
||
const n = Number.parseInt(String(args[i + 1] ?? ''), 10)
|
||
if (Number.isFinite(n) && n > 0) out.timeout = n
|
||
i++
|
||
continue
|
||
}
|
||
if (a.startsWith('--timeout=')) {
|
||
const n = Number.parseInt(a.slice('--timeout='.length), 10)
|
||
if (Number.isFinite(n) && n > 0) out.timeout = n
|
||
continue
|
||
}
|
||
|
||
if (!a.startsWith('-') && !out.url) {
|
||
out.url = a
|
||
}
|
||
}
|
||
return out
|
||
}
|
||
|
||
const parsed = parseArgs(process.argv.slice(2))
|
||
if (parsed.help || !parsed.url) {
|
||
console.log(
|
||
'Usage: node secrandom_ipc_send_url.js <url> [--ipc-name <name>] [--timeout <ms>]\n' +
|
||
'Example: node secrandom_ipc_send_url.js "SecRandom://settings"'
|
||
)
|
||
process.exit(parsed.help ? 0 : 1)
|
||
}
|
||
|
||
const { url, ipcName, timeout } = parsed
|
||
|
||
function getIpcAddress(ipcName) {
|
||
if (process.platform === 'win32') {
|
||
return `\\\\.\\pipe\\${ipcName}`
|
||
}
|
||
return `/tmp/${ipcName}.sock`
|
||
}
|
||
|
||
const ipcAddress = getIpcAddress(ipcName)
|
||
const message = JSON.stringify({ type: 'url', payload: { url } })
|
||
|
||
const client = net.createConnection(ipcAddress)
|
||
|
||
client.setTimeout(parseInt(timeout))
|
||
|
||
client.on('connect', () => {
|
||
client.write(message + '\n')
|
||
})
|
||
|
||
client.on('data', (data) => {
|
||
try {
|
||
const response = JSON.parse(data.toString())
|
||
console.log(JSON.stringify(response, null, 2))
|
||
process.exit(response.success ? 0 : 2)
|
||
} catch (error) {
|
||
console.error('Failed to parse response:', error)
|
||
process.exit(1)
|
||
}
|
||
})
|
||
|
||
client.on('timeout', () => {
|
||
console.error('Connection timeout')
|
||
client.destroy()
|
||
process.exit(1)
|
||
})
|
||
|
||
client.on('error', (error) => {
|
||
if (error.code === 'ENOENT') {
|
||
console.error(`IPC 通道不存在: ${ipcAddress}. 请确认 SecRandom 已运行且已启动 IPC 服务端。`)
|
||
} else {
|
||
console.error('IPC send failed:', error.message)
|
||
}
|
||
process.exit(1)
|
||
})
|
||
|
||
client.on('close', () => {
|
||
if (process.exitCode === undefined) {
|
||
console.error('Connection closed without response')
|
||
process.exit(1)
|
||
}
|
||
})
|