preload.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. const { contextBridge, ipcRenderer } = require('electron');
  2. const path = require('path');
  3. const os = require('os');
  4. const fs = require('fs');
  5. /**
  6. * 文件操作相关的预加载脚本
  7. */
  8. contextBridge.exposeInMainWorld('fileAPI', {
  9. /**
  10. * 使用 7z 压缩文件
  11. * @param {Object} opts 压缩选项
  12. * @returns {Promise} 压缩结果
  13. */
  14. compress: (opts) => ipcRenderer.invoke('compress-with-7z', opts),
  15. /**
  16. * 监听压缩进度
  17. * @param {Function} cb 回调函数,接收进度文本作为参数
  18. * @returns {Function} 用于移除监听器的函数
  19. */
  20. onProgress: (cb) => {
  21. const handler = (event, data) => cb(String(data));
  22. ipcRenderer.on('compress-progress', handler);
  23. return () => ipcRenderer.removeListener('compress-progress', handler);
  24. },
  25. /**
  26. * 监听压缩错误输出
  27. * @param {Function} cb 回调函数,接收错误文本作为参数
  28. * @returns {Function} 用于移除监听器的函数
  29. */
  30. onStderr: (cb) => {
  31. const handler = (event, data) => cb(String(data));
  32. ipcRenderer.on('compress-stderr', handler);
  33. return () => ipcRenderer.removeListener('compress-stderr', handler);
  34. },
  35. /**
  36. * 删除临时解压目录
  37. * @param {string} tmpDir 临时解压目录路径
  38. */
  39. deleteTempDir: (tmpDir) => {
  40. return fs.rmSync(tmpDir, { recursive: true, force: true });
  41. },
  42. /**
  43. * 创建临时文件夹
  44. * @param {string} prefix 临时文件夹前缀
  45. * @returns {string} 创建的临时文件夹路径
  46. */
  47. createTempDir: (prefix) => {
  48. const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), prefix || 'eep-'));
  49. const dirResourcePath = path.join(tmpDir, 'resource');
  50. if (!fs.existsSync(dirResourcePath)) {
  51. fs.mkdirSync(dirResourcePath);
  52. }
  53. const dirCoursewarePath = path.join(tmpDir, 'courseware');
  54. if (!fs.existsSync(dirCoursewarePath)) {
  55. fs.mkdirSync(dirCoursewarePath);
  56. }
  57. return tmpDir;
  58. },
  59. /**
  60. * 读取解压后的文件内容
  61. * @param {string} tmpDir 临时解压目录路径
  62. * @param {string} entryName 文件条目名称
  63. * @returns {Buffer} 文件内容
  64. */
  65. readZipFileSync: (tmpDir, entryName) => {
  66. const filePath = path.join(tmpDir, entryName);
  67. return fs.readFileSync(filePath);
  68. },
  69. /**
  70. * 下载文件
  71. * @param {string} url 文件 URL
  72. * @param {string} destPath 保存路径
  73. */
  74. downloadFile: (url, destPath) => {
  75. return ipcRenderer.invoke('download-file', { url, destPath });
  76. },
  77. /**
  78. * 监听下载进度
  79. * @param {Function} cb 回调,接收 { bytesReceived, contentLength, percentage } 作为参数
  80. * @returns {Function} 用于移除监听器的函数
  81. */
  82. onDownloadProgress: (cb) => {
  83. const handler = (event, data) => cb(data);
  84. ipcRenderer.on('download-progress', handler);
  85. return () => ipcRenderer.removeListener('download-progress', handler);
  86. },
  87. /**
  88. * 打开文件对话框
  89. * @param {Object} opts 对话框选项
  90. * @returns {Promise} 文件路径
  91. */
  92. openFileDialog: (opts) => ipcRenderer.invoke('dialog:openFiles', opts),
  93. /**
  94. * 检查文件路径是否存在
  95. * @param {string} filePath 文件路径
  96. * @returns {boolean} 是否存在
  97. */
  98. existsSync: (filePath) => fs.existsSync(filePath),
  99. /**
  100. * 创建目录(递归)
  101. * @param {string} dirPath 目录路径
  102. */
  103. mkdirSync: (dirPath) => {
  104. if (!fs.existsSync(dirPath)) {
  105. fs.mkdirSync(dirPath, { recursive: true });
  106. }
  107. },
  108. });
  109. /**
  110. * 应用更新相关的预加载脚本
  111. */
  112. contextBridge.exposeInMainWorld('updateAPI', {
  113. /**
  114. * 安装更新
  115. * @param {String} filePath 更新文件路径
  116. * @returns {Promise} 安装结果
  117. */
  118. installUpdate: (filePath) => {
  119. return ipcRenderer.send('install-update', filePath);
  120. },
  121. });