import {app, BrowserWindow, ipcMain, dialog} from 'electron'; import {exec, spawn} from 'child_process'; import path from 'path'; import {fileURLToPath} from 'url'; import fs from 'fs'; import axios from 'axios'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); function createWindow() { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js'), // 确保路径正确 contextIsolation: true, enableRemoteModule: false, nodeIntegration: false, } }); win.webContents.openDevTools(); // 打开开发者工具进行调试 win.loadURL('http://localhost:5173'); // 开发环境 // win.loadURL('http://36.110.106.156:81'); // 生产环境 console.log('Window created and URL loaded'); } app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow(); } }); // ------------- 进程通信 ------------- ipcMain.on('open-gazebo', (event, arg) => { console.log('Received open-gazebo event'); exec('gazebo', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); }); }); ipcMain.on('open-rviz', (event, arg) => { console.log('Received open-rviz event'); exec('rviz', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); }); }); ipcMain.on('close-gazebo', (event, arg) => { console.log('Received close-gazebo event'); exec('pkill -f gzserver & pkill -f gzclient', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); }); }); ipcMain.on('close-rviz', (event, arg) => { console.log('Received close-rviz event'); exec('pkill -f rviz', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); }); }); ipcMain.handle('dialog:open', async (event, options = {}) => { const result = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0], options); return result.canceled ? null : result.filePaths; }); ipcMain.on('docker-import', (event, sudoPassword, filePath, tag) => { const command = 'echo "' + sudoPassword + '" | sudo -S docker import ' + filePath + ' pji_nav:' + tag console.log('导入算法镜像文件:', command); exec(command, (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.error(`stderr: ${stderr}`); }); }); ipcMain.on('generate-world', (event, {rosbag_path}) => { // 使用 spawn 启动脚本 const serviceProcess = spawn('bash', ["/home/cicv/work/pji_desktop/world_generation/run_map2gazebo.sh"], { detached: true }); // 设置为后台进程 serviceProcess.unref(); // 监听输出 serviceProcess.stdout.on('data', (data) => { console.log(`第一个脚本的输出: ${data}`); // 根据第一个脚本的输出判断其是否准备好 if (data.toString().includes('Service map2gazebo started')) { startSecondScript(); } }); // 监听错误 serviceProcess.stderr.on('data', (data) => { console.error(`执行第一个脚本时出错: ${data}`); }); // 监听关闭 serviceProcess.on('close', (data) => { console.log(`第一个脚本已关闭: ${data}`); }); function startSecondScript() { // 启动第二个脚本 const script2 = exec('bash /home/cicv/work/pji_desktop/world_generation/play_rosbag.sh ' + rosbag_path, (error, stdout, stderr) => { if (error) { console.error(`执行第二个脚本时出错: ${error}`); event.sender.send('generate-world-result', { success: false, output: error }); return; } console.log(`第二个脚本的输出: ${stdout}`); event.sender.send('generate-world-result', { success: true, output: stdout }); }); script2.on('exit', (code) => { console.log(`第二个脚本已退出,退出码: ${code}`); }); } }); ipcMain.handle('download-file', async (event, { url, fileName, savePath }) => { try { const response = await axios.get(url, { responseType: 'stream' }); // console.log("url", url) // console.log("response", response) const filePath = path.join(savePath, fileName); // 写入文件 const writer = fs.createWriteStream(filePath); return new Promise((resolve, reject) => { response.data.pipe(writer); let error = null; writer.on('error', err => { error = err; writer.close(); reject(err); }); writer.on('close', () => { if (!error) { resolve({ success: true, filePath }); // 返回成功信息 } else { reject({ success: false, error: error.message }); // 返回错误信息 } }); }); } catch (error) { // console.error('下载文件出错:', error); throw error; } }); // 监听从渲染进程传来的删除文件请求 ipcMain.on('delete-file', (event, {fileName, savePath}) => { const filePath = path.join(savePath, fileName); // 检查文件是否存在 if (fs.existsSync(filePath)) { // 文件存在,尝试删除 fs.unlink(filePath, (err) => { if (err) { event.reply('delete-file-response', { success: false, message: err.message }); } else { event.reply('delete-file-response', { success: true, message: 'File deleted successfully' }); } }); } else { // 文件不存在 event.reply('delete-file-response', { success: false, message: 'File does not exist' }); } });