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.
213 lines
9.1 KiB
213 lines
9.1 KiB
/* |
|
* @Author: 李皓 hao_li_work@163.com |
|
* @Date: 2026-07-28 16:31:45 |
|
* @LastEditors: 李皓 hao_li_work@163.com |
|
* @LastEditTime: 2026-07-28 16:44:07 |
|
* @FilePath: \pc\preload.js |
|
* @Description: |
|
* @Version: 1.0.0 |
|
*/ |
|
const { contextBridge, ipcRenderer } = require('electron') |
|
const nodeNet = require('net') |
|
const dns = require('dns') |
|
|
|
function tryConnect(host, port, timeout) { |
|
return new Promise((resolve) => { |
|
const socket = new nodeNet.Socket() |
|
socket.setTimeout(timeout) |
|
socket.on('connect', () => { socket.destroy(); resolve(true) }) |
|
socket.on('error', () => { socket.destroy(); resolve(false) }) |
|
socket.on('timeout', () => { socket.destroy(); resolve(false) }) |
|
socket.connect(port, host) |
|
}) |
|
} |
|
|
|
const net = { |
|
async ping(host, timeout) { |
|
try { |
|
await dns.promises.resolve(host) |
|
} catch { |
|
return false |
|
} |
|
for (const port of [443, 80]) { |
|
if (await tryConnect(host, port, timeout)) return true |
|
} |
|
return false |
|
} |
|
} |
|
|
|
const appCallbacks = { |
|
onFileWrite: null, |
|
onFileRead: null, |
|
onFileDelete: null, |
|
onPageModeChanged: null |
|
} |
|
|
|
ipcRenderer.on('app-file-write-callback', (_event, token, filePath, success, err) => { |
|
if (typeof appCallbacks.onFileWrite === 'function') appCallbacks.onFileWrite(token, filePath, success, err) |
|
}) |
|
ipcRenderer.on('app-file-read-callback', (_event, token, filePath, content) => { |
|
if (typeof appCallbacks.onFileRead === 'function') appCallbacks.onFileRead(token, filePath, content) |
|
}) |
|
ipcRenderer.on('app-file-delete-callback', (_event, token, filePath, success) => { |
|
if (typeof appCallbacks.onFileDelete === 'function') appCallbacks.onFileDelete(token, filePath, success) |
|
}) |
|
ipcRenderer.on('app-page-mode', (_event, mode) => { |
|
if (typeof appCallbacks.onPageModeChanged === 'function') appCallbacks.onPageModeChanged(mode) |
|
}) |
|
|
|
const app = { |
|
clearCache() { return ipcRenderer.sendSync('app-clear-cache-sync') }, |
|
versionCode() { return ipcRenderer.sendSync('app-version-code-sync') }, |
|
setCache(key, value) { return ipcRenderer.sendSync('set-cache-sync', key, value) }, |
|
getCache(key) { return ipcRenderer.sendSync('get-cache-sync', key) }, |
|
offlinePage() { ipcRenderer.send('app-offline-page') }, |
|
onlinePage() { ipcRenderer.send('app-online-page') }, |
|
fileList(dir) { return ipcRenderer.sendSync('app-file-list-sync', dir) }, |
|
fileWriteString(filePath, content, token) { ipcRenderer.send('app-file-write-string', filePath, content, token) }, |
|
fileReadString(filePath, token) { ipcRenderer.send('app-file-read-string', filePath, token) }, |
|
fileDelete(filePath, token) { ipcRenderer.send('app-file-delete', filePath, token) }, |
|
get onFileWrite() { return appCallbacks.onFileWrite }, |
|
set onFileWrite(fn) { appCallbacks.onFileWrite = fn }, |
|
get onFileRead() { return appCallbacks.onFileRead }, |
|
set onFileRead(fn) { appCallbacks.onFileRead = fn }, |
|
get onFileDelete() { return appCallbacks.onFileDelete }, |
|
set onFileDelete(fn) { appCallbacks.onFileDelete = fn }, |
|
get onPageModeChanged() { return appCallbacks.onPageModeChanged }, |
|
set onPageModeChanged(fn) { appCallbacks.onPageModeChanged = fn } |
|
} |
|
|
|
const sensorCallbacks = { |
|
onSensorAttached: null, |
|
onSensorDetached: null, |
|
onOperationCallback: null |
|
} |
|
|
|
ipcRenderer.on('sensor-attached', (_event, data) => { |
|
if (typeof sensorCallbacks.onSensorAttached === 'function') sensorCallbacks.onSensorAttached(data.id, data.name) |
|
}) |
|
ipcRenderer.on('sensor-detached', (_event, data) => { |
|
if (typeof sensorCallbacks.onSensorDetached === 'function') sensorCallbacks.onSensorDetached(data.id, data.name) |
|
}) |
|
ipcRenderer.on('sensor-operation-callback', (_event, id, opId, result) => { |
|
if (typeof sensorCallbacks.onOperationCallback === 'function') sensorCallbacks.onOperationCallback(id, opId, result) |
|
}) |
|
|
|
const sensor = { |
|
initAll() { return ipcRenderer.sendSync('sensor-init-all-sync') }, |
|
flush() { return ipcRenderer.sendSync('sensor-flush-sync') }, |
|
sensorList() { return ipcRenderer.sendSync('sensor-list-sync') }, |
|
init(id) { return ipcRenderer.sendSync('sensor-init-sync', id) }, |
|
open(id) { return ipcRenderer.sendSync('sensor-open-sync', id) }, |
|
close(id) { return ipcRenderer.sendSync('sensor-close-sync', id) }, |
|
operation(id, opId, args) { return ipcRenderer.sendSync('sensor-operation-sync', id, opId, args) }, |
|
operationAsync(id, opId, args) { ipcRenderer.send('sensor-operation-async', id, opId, args) }, |
|
get onSensorAttached() { return sensorCallbacks.onSensorAttached }, |
|
set onSensorAttached(fn) { sensorCallbacks.onSensorAttached = fn }, |
|
get onSensorDetached() { return sensorCallbacks.onSensorDetached }, |
|
set onSensorDetached(fn) { sensorCallbacks.onSensorDetached = fn }, |
|
get onOperationCallback() { return sensorCallbacks.onOperationCallback }, |
|
set onOperationCallback(fn) { sensorCallbacks.onOperationCallback = fn } |
|
} |
|
|
|
const appSensorCallbacks = { onValueCallback: null } |
|
const appSensor = { |
|
version: '1.0.0', |
|
name: 'appSensor', |
|
open() { return ipcRenderer.sendSync('app-sensor-open-sync') }, |
|
close() { return ipcRenderer.sendSync('app-sensor-close-sync') }, |
|
isOpen() { return ipcRenderer.sendSync('app-sensor-is-open-sync') }, |
|
get onValueCallback() { return appSensorCallbacks.onValueCallback }, |
|
set onValueCallback(fn) { appSensorCallbacks.onValueCallback = fn } |
|
} |
|
|
|
ipcRenderer.on('sensor-data', (_event, data) => { |
|
if (typeof appSensorCallbacks.onValueCallback === 'function') appSensorCallbacks.onValueCallback(data) |
|
}) |
|
|
|
const appLocationCallbacks = { |
|
onOpened: null, |
|
onLocationChanged: null |
|
} |
|
|
|
ipcRenderer.on('app-location-opened', (_event, status) => { |
|
if (typeof appLocationCallbacks.onOpened === 'function') appLocationCallbacks.onOpened(status) |
|
}) |
|
ipcRenderer.on('app-location-changed', (_event, location) => { |
|
if (typeof appLocationCallbacks.onLocationChanged === 'function') appLocationCallbacks.onLocationChanged(location) |
|
}) |
|
|
|
const appLocation = { |
|
isSupport() { return ipcRenderer.sendSync('app-location-is-support-sync') }, |
|
isOpen() { return ipcRenderer.sendSync('app-location-is-open-sync') }, |
|
open() { ipcRenderer.send('app-location-open') }, |
|
close() { ipcRenderer.send('app-location-close') }, |
|
get onOpened() { return appLocationCallbacks.onOpened }, |
|
set onOpened(fn) { appLocationCallbacks.onOpened = fn }, |
|
get onLocationChanged() { return appLocationCallbacks.onLocationChanged }, |
|
set onLocationChanged(fn) { appLocationCallbacks.onLocationChanged = fn } |
|
} |
|
|
|
const usbSerialCallbacks = { |
|
onDeviceAttached: null, |
|
onDeviceDetached: null, |
|
onDeviceDiscovered: null, |
|
onDeviceProbeResult: null, |
|
onDeviceOpened: null, |
|
onDeviceState: null, |
|
onDeviceData: null |
|
} |
|
|
|
for (const [eventName, cbName] of [ |
|
['usb-callback-device-attached', 'onDeviceAttached'], |
|
['usb-callback-device-detached', 'onDeviceDetached'], |
|
['usb-callback-device-discovered', 'onDeviceDiscovered'], |
|
['usb-callback-device-probe-result', 'onDeviceProbeResult'], |
|
['usb-callback-device-opened', 'onDeviceOpened'], |
|
['usb-callback-device-state', 'onDeviceState'], |
|
['usb-callback-device-data', 'onDeviceData'] |
|
]) { |
|
ipcRenderer.on(eventName, (_event, jsonStr) => { |
|
const cb = usbSerialCallbacks[cbName] |
|
if (typeof cb === 'function') cb(jsonStr) |
|
}) |
|
} |
|
|
|
const usbSerial = { |
|
get onDeviceAttached() { return usbSerialCallbacks.onDeviceAttached }, |
|
set onDeviceAttached(fn) { usbSerialCallbacks.onDeviceAttached = fn }, |
|
get onDeviceDetached() { return usbSerialCallbacks.onDeviceDetached }, |
|
set onDeviceDetached(fn) { usbSerialCallbacks.onDeviceDetached = fn }, |
|
get onDeviceDiscovered() { return usbSerialCallbacks.onDeviceDiscovered }, |
|
set onDeviceDiscovered(fn) { usbSerialCallbacks.onDeviceDiscovered = fn }, |
|
get onDeviceProbeResult() { return usbSerialCallbacks.onDeviceProbeResult }, |
|
set onDeviceProbeResult(fn) { usbSerialCallbacks.onDeviceProbeResult = fn }, |
|
get onDeviceOpened() { return usbSerialCallbacks.onDeviceOpened }, |
|
set onDeviceOpened(fn) { usbSerialCallbacks.onDeviceOpened = fn }, |
|
get onDeviceState() { return usbSerialCallbacks.onDeviceState }, |
|
set onDeviceState(fn) { usbSerialCallbacks.onDeviceState = fn }, |
|
get onDeviceData() { return usbSerialCallbacks.onDeviceData }, |
|
set onDeviceData(fn) { usbSerialCallbacks.onDeviceData = fn }, |
|
startDiscovery() { ipcRenderer.send('usb-start-discovery') }, |
|
stopDiscovery() { ipcRenderer.send('usb-stop-discovery') }, |
|
getDiscoveredDevices() { return ipcRenderer.invoke('usb-get-discovered') }, |
|
deviceProbe(deviceName, portNumber, baudRate, hexCmd, timeoutMs) { |
|
ipcRenderer.send('usb-device-probe', { deviceName, portNumber, baudRate, hexCmd, timeoutMs }) |
|
}, |
|
deviceOpen(deviceName, portNumber, baudRate) { |
|
ipcRenderer.send('usb-device-open', { deviceName, portNumber, baudRate }) |
|
}, |
|
deviceClose(deviceName, portNumber) { |
|
ipcRenderer.send('usb-device-close', { deviceName, portNumber }) |
|
}, |
|
deviceWrite(deviceName, portNumber, hexData) { |
|
ipcRenderer.send('usb-device-write', { deviceName, portNumber, hexData }) |
|
} |
|
} |
|
|
|
contextBridge.exposeInMainWorld('app', app) |
|
contextBridge.exposeInMainWorld('net', net) |
|
contextBridge.exposeInMainWorld('sensor', sensor) |
|
contextBridge.exposeInMainWorld('appSensor', appSensor) |
|
contextBridge.exposeInMainWorld('appLocation', appLocation) |
|
contextBridge.exposeInMainWorld('usbSerial', usbSerial)
|
|
|