|
@@ -1,45 +1,34 @@
|
|
|
-const { app, BrowserWindow ,ipcMain} = require('electron')
|
|
|
|
|
|
|
+const { app, BrowserWindow, ipcMain } = require('electron')
|
|
|
const path = require('path')
|
|
const path = require('path')
|
|
|
const os = require('os')
|
|
const os = require('os')
|
|
|
const fs = require('fs')
|
|
const fs = require('fs')
|
|
|
-const config = require('../configs/config.js')
|
|
|
|
|
|
|
+
|
|
|
|
|
+const unpackedRoot = app.isPackaged
|
|
|
|
|
+ ? path.join(path.dirname(process.execPath), 'resources', 'app.asar.unpacked')
|
|
|
|
|
+ : path.join(__dirname, '..')
|
|
|
|
|
+const config = require(path.join(unpackedRoot, 'configs', 'config.js'))
|
|
|
const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged
|
|
const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged
|
|
|
|
|
|
|
|
-// 修复缓存权限问题:设置用户数据目录到有权限的位置
|
|
|
|
|
-// 必须在 app.whenReady() 之前调用
|
|
|
|
|
|
|
+const staticDir = path.join(unpackedRoot, 'static')
|
|
|
|
|
+if (!fs.existsSync(staticDir)) {
|
|
|
|
|
+ fs.mkdirSync(staticDir, { recursive: true })
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 修复缓存权限:userData 与缓存目录设到临时目录,避免安装目录只读导致 "Unable to move the cache (0x5)"
|
|
|
if (process.platform === 'win32') {
|
|
if (process.platform === 'win32') {
|
|
|
- try {
|
|
|
|
|
- // 设置缓存目录到用户临时目录,避免权限问题
|
|
|
|
|
- const userDataPath = path.join(os.tmpdir(), 'electron-react-vite-app')
|
|
|
|
|
-
|
|
|
|
|
- // 确保目录存在
|
|
|
|
|
- if (!fs.existsSync(userDataPath)) {
|
|
|
|
|
- fs.mkdirSync(userDataPath, { recursive: true })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 创建缓存子目录
|
|
|
|
|
- const cacheDir = path.join(userDataPath, 'cache')
|
|
|
|
|
- const gpuCacheDir = path.join(userDataPath, 'gpu-cache')
|
|
|
|
|
- if (!fs.existsSync(cacheDir)) {
|
|
|
|
|
- fs.mkdirSync(cacheDir, { recursive: true })
|
|
|
|
|
- }
|
|
|
|
|
- if (!fs.existsSync(gpuCacheDir)) {
|
|
|
|
|
- fs.mkdirSync(gpuCacheDir, { recursive: true })
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 设置用户数据路径(必须在 app.whenReady() 之前)
|
|
|
|
|
- app.setPath('userData', userDataPath)
|
|
|
|
|
-
|
|
|
|
|
- // 设置缓存目录到有权限的位置
|
|
|
|
|
- app.commandLine.appendSwitch('disk-cache-dir', cacheDir)
|
|
|
|
|
- app.commandLine.appendSwitch('gpu-disk-cache-dir', gpuCacheDir)
|
|
|
|
|
-
|
|
|
|
|
- console.log(`[OK] Cache directories set to: ${userDataPath}`)
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.warn('[WARN] Failed to set cache directories:', error.message)
|
|
|
|
|
- // 如果设置失败,尝试禁用 GPU 缓存作为备选方案
|
|
|
|
|
- app.commandLine.appendSwitch('disable-gpu-sandbox')
|
|
|
|
|
|
|
+ const userDataPath = path.join(os.tmpdir(), 'AndroidRemoteController')
|
|
|
|
|
+ if (!fs.existsSync(userDataPath)) {
|
|
|
|
|
+ fs.mkdirSync(userDataPath, { recursive: true })
|
|
|
}
|
|
}
|
|
|
|
|
+ const cacheDir = path.join(userDataPath, 'Cache')
|
|
|
|
|
+ const gpuCacheDir = path.join(userDataPath, 'GPUCache')
|
|
|
|
|
+ if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true })
|
|
|
|
|
+ if (!fs.existsSync(gpuCacheDir)) fs.mkdirSync(gpuCacheDir, { recursive: true })
|
|
|
|
|
+
|
|
|
|
|
+ app.setPath('userData', userDataPath)
|
|
|
|
|
+ app.commandLine.appendSwitch('disk-cache-dir', cacheDir)
|
|
|
|
|
+ app.commandLine.appendSwitch('gpu-disk-cache-dir', gpuCacheDir)
|
|
|
|
|
+ app.commandLine.appendSwitch('disable-gpu-shader-disk-cache')
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 保存主窗口引用,用于推送消息
|
|
// 保存主窗口引用,用于推送消息
|
|
@@ -71,7 +60,7 @@ function createWindow() {
|
|
|
mainWindow.webContents.openDevTools()
|
|
mainWindow.webContents.openDevTools()
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
- mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
|
|
|
|
|
|
|
+ mainWindow.loadFile(path.join(unpackedRoot, 'dist', 'index.html'))
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -83,7 +72,7 @@ const runningProcesses = new Map()
|
|
|
// Execute Node.js script
|
|
// Execute Node.js script
|
|
|
ipcMain.handle('run-nodejs-script', async (event, scriptName, ...parameters) => {
|
|
ipcMain.handle('run-nodejs-script', async (event, scriptName, ...parameters) => {
|
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
|
- const scriptPath = path.join(__dirname, '../nodejs', `${scriptName}.js`)
|
|
|
|
|
|
|
+ const scriptPath = path.join(unpackedRoot, 'nodejs', `${scriptName}.js`)
|
|
|
const processKey = `${scriptName}-${parameters.join('-')}`
|
|
const processKey = `${scriptName}-${parameters.join('-')}`
|
|
|
|
|
|
|
|
// 如果进程已运行,先停止它
|
|
// 如果进程已运行,先停止它
|
|
@@ -175,6 +164,24 @@ ipcMain.handle('kill-nodejs-script', async (event, scriptName, ...parameters) =>
|
|
|
return { killed: false }
|
|
return { killed: false }
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+/** 检查 scrcpy 是否仍在运行(读 pid 文件并用 process.kill(pid,0) 探测),用于用户直接关窗口时同步按钮状态 */
|
|
|
|
|
+ipcMain.handle('check-scrcpy-running', async () => {
|
|
|
|
|
+ const pidFile = path.join(unpackedRoot, 'static', 'scrcpy-pid.json')
|
|
|
|
|
+ if (!fs.existsSync(pidFile)) return { running: false }
|
|
|
|
|
+ let pid
|
|
|
|
|
+ try {
|
|
|
|
|
+ pid = JSON.parse(fs.readFileSync(pidFile, 'utf-8')).pid
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ return { running: false }
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ process.kill(pid, 0)
|
|
|
|
|
+ return { running: true }
|
|
|
|
|
+ } catch (_) {
|
|
|
|
|
+ return { running: false }
|
|
|
|
|
+ }
|
|
|
|
|
+})
|
|
|
|
|
+
|
|
|
// Execute Python script
|
|
// Execute Python script
|
|
|
ipcMain.handle('run-python-script', async (event, scriptName, ...parameters) => {
|
|
ipcMain.handle('run-python-script', async (event, scriptName, ...parameters) => {
|
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
@@ -187,7 +194,7 @@ ipcMain.handle('run-python-script', async (event, scriptName, ...parameters) =>
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- const scriptPath = path.join(__dirname, '../python/scripts', `${scriptName}.py`)
|
|
|
|
|
|
|
+ const scriptPath = path.join(unpackedRoot, 'python', 'scripts', `${scriptName}.py`)
|
|
|
|
|
|
|
|
if (!fs.existsSync(scriptPath)) {
|
|
if (!fs.existsSync(scriptPath)) {
|
|
|
reject({
|
|
reject({
|
|
@@ -239,7 +246,7 @@ ipcMain.handle('ipc-request', async (event, channel, data) => {
|
|
|
// 通过 IPC 调用 run-nodejs-script
|
|
// 通过 IPC 调用 run-nodejs-script
|
|
|
const { scriptName, ...parameters } = data
|
|
const { scriptName, ...parameters } = data
|
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
|
- const scriptPath = path.join(__dirname, '../nodejs', `${scriptName}.js`)
|
|
|
|
|
|
|
+ const scriptPath = path.join(unpackedRoot, 'nodejs', `${scriptName}.js`)
|
|
|
const processKey = `${scriptName}-${parameters.join('-')}`
|
|
const processKey = `${scriptName}-${parameters.join('-')}`
|
|
|
|
|
|
|
|
if (runningProcesses.has(processKey)) {
|
|
if (runningProcesses.has(processKey)) {
|