光电挠度仪上位机
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

138 lines
4.5 KiB

import { spawn } from 'child_process'
import path from 'path'
import fs from 'fs'
import fsp from 'fs/promises'
import { fileURLToPath } from 'url'
import { app } from 'electron'
// ESM 下没有 __dirname,使用 import.meta.url 计算当前目录
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const isWin = process.platform === 'win32'
const adbBinary = isWin ? 'adb.exe' : 'adb'
// 解析 adb 可执行文件路径(开发/打包均可用)
function resolveAdbPath() {
const resources = process.resourcesPath || ''
const candidates = [
// 开发:项目根目录 resources/adbSDK/adb(.exe)(与 electron-builder extraResources 对应)
path.join(process.cwd(), 'resources', 'adbSDK', adbBinary),
// 开发:与本文件同级的 ../adbSDK/adb(.exe)
path.join(__dirname, '..', 'adbSDK', adbBinary),
// 开发:构建输出 out/adbSDK/adb(.exe)(如有)
path.join(process.cwd(), 'out', 'adbSDK', adbBinary),
// 生产:extraResources 复制到 resources/adbSDK
path.join(resources, 'adbSDK', adbBinary),
// 生产:若使用 asarUnpack,位于 app.asar.unpacked
path.join(resources, 'app.asar.unpacked', 'adbSDK', adbBinary)
]
for (const p of candidates) {
try {
if (fs.existsSync(p)) return p
} catch {}
}
throw new Error(
`adb executable not found. Tried:\n${candidates.join('\n')}\n` +
'Please ensure adbSDK exists in development (resources/adbSDK) and is listed in extraResources for production.'
)
}
const adbPath = resolveAdbPath()
const adbDir = path.dirname(adbPath)
function getAdbSerial(ip) {
if (!ip) throw new Error('ip required')
return ip.includes(':') ? ip : `${ip}:5555`
}
/**
* 运行 adb 命令的通用封装
*/
function runAdb(args, options = {}) {
return new Promise((resolve, reject) => {
// 先行校验,给出更明确的错误
if (!fs.existsSync(adbPath)) {
return reject(new Error(`adb not found at ${adbPath}`))
}
const child = spawn(adbPath, args, { cwd: adbDir, windowsHide: true, ...options })
let stdout = ''
let stderr = ''
child.stdout?.on('data', (d) => (stdout += d.toString()))
child.stderr?.on('data', (d) => (stderr += d.toString()))
child.on('error', (err) => reject(err))
child.on('close', (code) => {
if (code === 0) return resolve({ stdout: stdout.trim(), stderr: stderr.trim() })
const err = new Error(`adb exited with ${code}: ${stderr || stdout}`)
err.code = code
err.stdout = stdout
err.stderr = stderr
reject(err)
})
})
}
// 下面其余 API 保持不变(仅把 fs/promises 改为 fsp 引用)
async function connect(ip) {
if (!ip) throw new Error('ip required')
return runAdb(['connect', getAdbSerial(ip)])
}
async function disconnect(ip) {
if (ip) return runAdb(['disconnect', getAdbSerial(ip)])
return runAdb(['disconnect'])
}
async function pull(remotePath, destFilename, ip) {
const dest = path.join(adbDir, destFilename || path.basename(remotePath))
await fsp.mkdir(adbDir, { recursive: true })
const serialArgs = ip ? ['-s', getAdbSerial(ip)] : []
await runAdb([...serialArgs, 'pull', remotePath, dest])
return dest
}
async function push(localPath, remotePath, ip) {
const serialArgs = ip ? ['-s', getAdbSerial(ip)] : []
return runAdb([...serialArgs, 'push', localPath, remotePath])
}
async function readLocalOLE() {
const file = path.join(adbDir, 'OLE.ini')
const text = await fsp.readFile(file, 'utf8')
const lines = text.split(/\r?\n/).filter(Boolean)
return lines[0] ? lines[0] : null
}
async function writeFirstOLE(line1) {
const file = path.join(adbDir, 'OLE.ini')
let second = '1.000000'
try {
const text = await fsp.readFile(file, 'utf8')
const lines = text.split(/\r?\n/).filter(Boolean)
if (lines.length >= 2) second = lines[1]
} catch {}
const content = `${line1}\n${second}\n`
await fsp.writeFile(file, content, 'utf8')
return file
}
async function getParametersFromDevice(ip) {
if (ip) await connect(ip)
await pull('/data/OLE.ini', 'OLE.ini', ip)
return readLocalOLE()
}
async function setFirstParameter({ param, ip, toSystem = false }) {
if (param == null) throw new Error('param required')
const local = await writeFirstOLE(param)
if (ip) await connect(ip)
await push(local, '/data/', ip)
if (toSystem) {
await push(local, '/system/etc/', ip)
}
return { local }
}
export { adbPath, runAdb, connect, pull, push, readLocalOLE, writeFirstOLE, getParametersFromDevice, setFirstParameter, disconnect, getAdbSerial }