// main/window.js const { app, BrowserWindow, dialog, ipcMain } = require('electron') const path = require('path') const fs = require('fs') const { isProcessRunningWin } = require('./services/iosai') function safeLoadURL(win, url, onFail) { if (!win || win.isDestroyed()) return win.loadURL(url).catch(err => { console.warn('[loadURL fail]', err); onFail?.(err) }) } function createMainWindow({ updaterState }) { const win = new BrowserWindow({ width: 1920, height: 1080, title: `YOLO(AI助手ios) v${app.getVersion()}`, frame: true, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false, sandbox: true, webSecurity: true, backgroundThrottling: false, enableRemoteModule: false, offscreen: false, experimentalFeatures: true, autoplayPolicy: 'no-user-gesture-required', devTools: true, } }) win.setMenu(null) win.maximize() const isProd = app.isPackaged const targetURL = isProd ? 'https://iosai.yolozs.com' : 'http://192.168.1.128:8080' console.log('[page] target:', targetURL) const tryNavigate = (reason = '') => { const ts = Date.now() const go = () => safeLoadURL(win, `${targetURL}?t=${ts}`) if (updaterState.updateInProgress) { console.log(`[Nav] blocked (${reason}): updating...`) updaterState.pendingNavs.push(go) return } go() } // 等待页 const loadingFile = path.join(__dirname, '..', 'waiting.html') if (process.platform === 'win32') { if (fs.existsSync(loadingFile)) { win.loadFile(loadingFile).catch(() => win.loadURL('data:text/html,

正在等待 iproxy.exe 启动…

')) } else { win.loadURL('data:text/html,

正在等待 iproxy.exe 启动…

') } waitForProcessAndNavigate(win, targetURL, { exeName: 'iproxy.exe' }, tryNavigate) } else { tryNavigate('non-win-first') } // 选择文件对话框(放这也行,但我在 system.js 里也提供了封装) ipcMain.handle('select-apk-file', async () => { const r = await dialog.showOpenDialog({ title: '选择 APK 文件', filters: [{ name: 'APK', extensions: ['apk'] }], properties: ['openFile'] }) return r.canceled ? null : r.filePaths[0] }) ipcMain.handle('select-file', async () => { const r = await dialog.showOpenDialog({ title: '选择文件', properties: ['openFile'] }) return r.canceled ? null : r.filePaths[0] }) return win } function waitForProcessAndNavigate(win, targetURL, { intervalMs = 2000, timeoutMs = 999999, exeName = 'iproxy.exe' } = {}, tryNavigate) { let elapsed = 0 win.setProgressBar(2, { mode: 'indeterminate' }) const timer = setInterval(async () => { const ok = await isProcessRunningWin(exeName) if (ok) { clearInterval(timer) win.setProgressBar(-1) console.log(`[iproxy] running, go -> ${targetURL}`) tryNavigate('iproxy-ok') return } elapsed += intervalMs if (elapsed >= timeoutMs) { console.warn(`[iproxy] wait timeout ${timeoutMs / 1000}s`) win.setTitle('YOLO(AI助手ios) - 正在等待 iproxy.exe 启动…(可检查连接/杀软/权限)') } }, intervalMs) } module.exports = { createMainWindow, safeLoadURL }