preload.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. // 使用 require 避免 ESM 问题
  2. const { contextBridge, ipcRenderer } = require('electron');
  3. // 暴露给渲染进程的 API
  4. contextBridge.exposeInMainWorld('electronAPI', {
  5. // 应用信息
  6. getAppVersion: () => ipcRenderer.invoke('get-app-version'),
  7. getPlatform: () => ipcRenderer.invoke('get-platform'),
  8. // 窗口控制
  9. minimizeWindow: () => ipcRenderer.send('window-minimize'),
  10. maximizeWindow: () => ipcRenderer.send('window-maximize'),
  11. closeWindow: () => ipcRenderer.send('window-close'),
  12. quitApp: () => ipcRenderer.send('app-quit'), // 真正退出应用
  13. isMaximized: () => ipcRenderer.invoke('window-is-maximized'),
  14. onMaximizedChange: (callback: (isMaximized: boolean) => void) => {
  15. ipcRenderer.on('window-maximized', (_event: unknown, isMaximized: boolean) => callback(isMaximized));
  16. },
  17. // 文件操作
  18. selectFile: (options?: { filters?: { name: string; extensions: string[] }[] }) =>
  19. ipcRenderer.invoke('select-file', options),
  20. selectFolder: () => ipcRenderer.invoke('select-folder'),
  21. // 通知
  22. showNotification: (title: string, body: string) =>
  23. ipcRenderer.send('show-notification', { title, body }),
  24. // 弹窗打开平台后台(独立窗口,不嵌入;实验用)
  25. openBackendExternal: (url: string, cookieData?: string, title?: string) =>
  26. ipcRenderer.invoke('open-backend-external', { url, cookieData, title }),
  27. // Webview Cookie 操作
  28. getWebviewCookies: (partition: string, url: string) =>
  29. ipcRenderer.invoke('get-webview-cookies', partition, url),
  30. clearWebviewCookies: (partition: string) =>
  31. ipcRenderer.invoke('clear-webview-cookies', partition),
  32. setWebviewCookies: (partition: string, cookies: Electron.CookiesSetDetails[]) =>
  33. ipcRenderer.invoke('set-webview-cookies', partition, cookies),
  34. // Webview 截图(用于 AI 分析)
  35. captureWebviewPage: (webContentsId: number) =>
  36. ipcRenderer.invoke('capture-webview-page', webContentsId),
  37. // Webview 自动操作
  38. webviewSendMouseClick: (webContentsId: number, x: number, y: number) =>
  39. ipcRenderer.invoke('webview-send-mouse-click', webContentsId, x, y),
  40. webviewSendTextInput: (webContentsId: number, text: string) =>
  41. ipcRenderer.invoke('webview-send-text-input', webContentsId, text),
  42. webviewGetElementPosition: (webContentsId: number, selector: string) =>
  43. ipcRenderer.invoke('webview-get-element-position', webContentsId, selector),
  44. webviewClickByText: (webContentsId: number, text: string) =>
  45. ipcRenderer.invoke('webview-click-by-text', webContentsId, text),
  46. // CDP 网络拦截
  47. enableNetworkIntercept: (webContentsId: number, patterns: Array<{match: string, key: string}>) =>
  48. ipcRenderer.invoke('enable-network-intercept', webContentsId, patterns),
  49. disableNetworkIntercept: (webContentsId: number) =>
  50. ipcRenderer.invoke('disable-network-intercept', webContentsId),
  51. updateNetworkPatterns: (webContentsId: number, patterns: Array<{match: string, key: string}>) =>
  52. ipcRenderer.invoke('update-network-patterns', webContentsId, patterns),
  53. onNetworkInterceptData: (callback: (data: { webContentsId: number; key: string; url: string; data: unknown }) => void) => {
  54. ipcRenderer.on('network-intercept-data', (_event: unknown, data: { webContentsId: number; key: string; url: string; data: unknown }) => callback(data));
  55. },
  56. removeNetworkInterceptListener: () => {
  57. ipcRenderer.removeAllListeners('network-intercept-data');
  58. },
  59. });
  60. // 类型声明
  61. declare global {
  62. interface Window {
  63. electronAPI: {
  64. getAppVersion: () => Promise<string>;
  65. getPlatform: () => Promise<string>;
  66. minimizeWindow: () => void;
  67. maximizeWindow: () => void;
  68. closeWindow: () => void;
  69. quitApp: () => void;
  70. isMaximized: () => Promise<boolean>;
  71. onMaximizedChange: (callback: (isMaximized: boolean) => void) => void;
  72. selectFile: (options?: { filters?: { name: string; extensions: string[] }[] }) => Promise<string | null>;
  73. selectFolder: () => Promise<string | null>;
  74. showNotification: (title: string, body: string) => void;
  75. getWebviewCookies: (partition: string, url: string) => Promise<Electron.Cookie[]>;
  76. clearWebviewCookies: (partition: string) => Promise<boolean>;
  77. setWebviewCookies: (partition: string, cookies: Electron.CookiesSetDetails[]) => Promise<boolean>;
  78. captureWebviewPage: (webContentsId: number) => Promise<string | null>;
  79. webviewSendMouseClick: (webContentsId: number, x: number, y: number) => Promise<boolean>;
  80. webviewSendTextInput: (webContentsId: number, text: string) => Promise<boolean>;
  81. webviewGetElementPosition: (webContentsId: number, selector: string) => Promise<{ x: number; y: number; width: number; height: number } | null>;
  82. webviewClickByText: (webContentsId: number, text: string) => Promise<boolean>;
  83. openBackendExternal: (url: string, cookieData?: string, title?: string) => Promise<{ ok: boolean }>;
  84. // CDP 网络拦截
  85. enableNetworkIntercept: (webContentsId: number, patterns: Array<{match: string, key: string}>) => Promise<boolean>;
  86. disableNetworkIntercept: (webContentsId: number) => Promise<boolean>;
  87. updateNetworkPatterns: (webContentsId: number, patterns: Array<{match: string, key: string}>) => Promise<boolean>;
  88. onNetworkInterceptData: (callback: (data: { webContentsId: number; key: string; url: string; data: unknown }) => void) => void;
  89. removeNetworkInterceptListener: () => void;
  90. };
  91. }
  92. }