main.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import {app, BrowserWindow, ipcMain, dialog} from 'electron';
  2. import {exec, spawn} from 'child_process';
  3. import path from 'path';
  4. import {fileURLToPath} from 'url';
  5. import fs from 'fs';
  6. import axios from 'axios';
  7. const __filename = fileURLToPath(import.meta.url);
  8. const __dirname = path.dirname(__filename);
  9. function createWindow() {
  10. const win = new BrowserWindow({
  11. width: 800,
  12. height: 600,
  13. webPreferences: {
  14. preload: path.join(__dirname, 'preload.js'), // 确保路径正确
  15. contextIsolation: true,
  16. enableRemoteModule: false,
  17. nodeIntegration: false,
  18. }
  19. });
  20. win.webContents.openDevTools(); // 打开开发者工具进行调试
  21. win.loadURL('http://localhost:5173'); // 开发环境
  22. // win.loadURL('http://36.110.106.156:81'); // 生产环境
  23. console.log('Window created and URL loaded');
  24. }
  25. app.whenReady().then(createWindow);
  26. app.on('window-all-closed', () => {
  27. if (process.platform !== 'darwin') {
  28. app.quit();
  29. }
  30. });
  31. app.on('activate', () => {
  32. if (BrowserWindow.getAllWindows().length === 0) {
  33. createWindow();
  34. }
  35. });
  36. // ------------- 进程通信 -------------
  37. ipcMain.on('open-gazebo', (event, arg) => {
  38. console.log('Received open-gazebo event');
  39. exec('gazebo', (error, stdout, stderr) => {
  40. if (error) {
  41. console.error(`exec error: ${error}`);
  42. return;
  43. }
  44. console.log(`stdout: ${stdout}`);
  45. console.error(`stderr: ${stderr}`);
  46. });
  47. });
  48. ipcMain.on('open-rviz', (event, arg) => {
  49. console.log('Received open-rviz event');
  50. exec('rviz', (error, stdout, stderr) => {
  51. if (error) {
  52. console.error(`exec error: ${error}`);
  53. return;
  54. }
  55. console.log(`stdout: ${stdout}`);
  56. console.error(`stderr: ${stderr}`);
  57. });
  58. });
  59. ipcMain.on('close-gazebo', (event, arg) => {
  60. console.log('Received close-gazebo event');
  61. exec('pkill -f gzserver & pkill -f gzclient', (error, stdout, stderr) => {
  62. if (error) {
  63. console.error(`exec error: ${error}`);
  64. return;
  65. }
  66. console.log(`stdout: ${stdout}`);
  67. console.error(`stderr: ${stderr}`);
  68. });
  69. });
  70. ipcMain.on('close-rviz', (event, arg) => {
  71. console.log('Received close-rviz event');
  72. exec('pkill -f rviz', (error, stdout, stderr) => {
  73. if (error) {
  74. console.error(`exec error: ${error}`);
  75. return;
  76. }
  77. console.log(`stdout: ${stdout}`);
  78. console.error(`stderr: ${stderr}`);
  79. });
  80. });
  81. ipcMain.handle('dialog:open', async (event, options = {}) => {
  82. const result = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow() || BrowserWindow.getAllWindows()[0], options);
  83. return result.canceled ? null : result.filePaths;
  84. });
  85. ipcMain.on('docker-import', (event, sudoPassword, filePath, tag) => {
  86. const command = 'echo "' + sudoPassword + '" | sudo -S docker import ' + filePath + ' pji_nav:' + tag
  87. console.log('导入算法镜像文件:', command);
  88. exec(command, (error, stdout, stderr) => {
  89. if (error) {
  90. console.error(`exec error: ${error}`);
  91. return;
  92. }
  93. console.log(`stdout: ${stdout}`);
  94. console.error(`stderr: ${stderr}`);
  95. });
  96. });
  97. ipcMain.on('generate-world', (event, rosbag_path) => {
  98. // 使用 spawn 启动脚本
  99. const serviceProcess = spawn('bash', ["/home/cicv/work/pji_desktop/run_map2gazebo.sh"], { detached: true });
  100. // 设置为后台进程
  101. serviceProcess.unref();
  102. // 监听输出
  103. serviceProcess.stdout.on('data', (data) => {
  104. console.log(`第一个脚本的输出: ${data}`);
  105. // 根据第一个脚本的输出判断其是否准备好
  106. if (data.toString().includes('Service map2gazebo started')) {
  107. startSecondScript();
  108. }
  109. });
  110. // 监听错误
  111. serviceProcess.stderr.on('data', (data) => {
  112. console.error(`执行第一个脚本时出错: ${data}`);
  113. });
  114. // 监听关闭
  115. serviceProcess.on('close', (data) => {
  116. console.log(`第二个脚本已关闭: ${data}`);
  117. });
  118. function startSecondScript() {
  119. // 启动第二个脚本
  120. const script2 = exec('bash /home/cicv/work/pji_desktop/play_rosbag.sh /home/cicv/work/pji_desktop/map_bag/map.bag', (error, stdout, stderr) => {
  121. if (error) {
  122. console.error(`执行第二个脚本时出错: ${error}`);
  123. return;
  124. }
  125. console.log(`第二个脚本的输出: ${stdout}`);
  126. });
  127. script2.on('exit', (code) => {
  128. console.log(`第二个脚本已退出,退出码: ${code}`);
  129. });
  130. }
  131. });
  132. ipcMain.handle('download-file', async (event, { url, fileName, savePath }) => {
  133. try {
  134. const response = await axios.get(url, { responseType: 'stream' });
  135. // console.log("url", url)
  136. // console.log("response", response)
  137. const filePath = path.join(savePath, fileName);
  138. // 写入文件
  139. const writer = fs.createWriteStream(filePath);
  140. return new Promise((resolve, reject) => {
  141. response.data.pipe(writer);
  142. let error = null;
  143. writer.on('error', err => {
  144. error = err;
  145. writer.close();
  146. reject(err);
  147. });
  148. writer.on('close', () => {
  149. if (!error) {
  150. resolve({ success: true, filePath }); // 返回成功信息
  151. } else {
  152. reject({ success: false, error: error.message }); // 返回错误信息
  153. }
  154. });
  155. });
  156. } catch (error) {
  157. // console.error('下载文件出错:', error);
  158. throw error;
  159. }
  160. });