You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Angular的Electron应用:数据存储与外部应用调用指导

问题描述

我是Electron新手,已按官方文档完成项目搭建,能正常启动和构建应用。目前有两个核心需求:

  1. 实现类似localStorage的数据存储功能
  2. 调用Photoshop打开指定文件

我试过angular-electron(已归档停更)和ngx-electronify(支持不足),当前通过IPC尝试实现外部应用调用,代码如下:

现有代码

main.js

app.on('ready', () => {
    mainWindow = new BrowserWindow({ width: 800, height: 600 });
    mainWindow.loadFile('index.html');

    // 监听渲染进程的IPC消息
    ipcMain.on('callMainFunction', (event, args) => {
        myFunctionInMainProcess();
    });
});

app.component.ts

callMainFunction() {
    // 向主进程发送IPC消息
    ipcRenderer.send('callMainFunction', { /* 按需传入额外数据 */ });
}

我的项目仓库:https://github.com/futurbotconsolidated/electron

希望得到Angular环境下的配置指导,Shell操作的使用方法,若有示例项目可分享更佳,感谢帮助!


解决方案

一、实现类似localStorage的数据存储

Electron中推荐使用以下两种更适合跨窗口、持久化场景的方案替代localStorage:

1. 使用electron-store(轻量键值对存储)

  • 安装依赖:
    npm install electron-store
    
  • 主进程初始化并通过IPC暴露操作:
    // main.js
    const Store = require('electron-store');
    const store = new Store();
    
    ipcMain.handle('store-set', (_, key, value) => {
      store.set(key, value);
      return true;
    });
    
    ipcMain.handle('store-get', (_, key) => {
      return store.get(key);
    });
    
    ipcMain.handle('store-delete', (_, key) => {
      store.delete(key);
      return true;
    });
    
  • Angular渲染进程调用:
    // app.component.ts
    import { ipcRenderer } from 'electron';
    
    async setStorage(key: string, value: any) {
      await ipcRenderer.invoke('store-set', key, value);
    }
    
    async getStorage(key: string) {
      return await ipcRenderer.invoke('store-get', key);
    }
    

2. 使用SQLite(复杂数据场景)

如果需要复杂查询操作,可使用sqlite3或typeorm结合SQLite,通过IPC封装CRUD逻辑即可,核心流程与上述一致。

二、调用Photoshop打开文件(Electron Shell操作)

Electron的shell模块专门用于桌面系统交互,打开外部应用可通过以下方式实现:

1. 主进程封装调用逻辑

// main.js
const { shell } = require('electron');
const path = require('path');

ipcMain.handle('open-with-photoshop', async (_, filePath) => {
  try {
    // 转换为绝对路径
    const absolutePath = path.resolve(filePath);
    
    // 方案1:用系统默认打开方式(若PS是该文件类型默认应用)
    await shell.openPath(absolutePath);

    // 方案2:强制指定Photoshop路径(适配Windows/macOS)
    // Windows示例:
    // const psPath = 'C:\\Program Files\\Adobe\\Adobe Photoshop 2024\\Photoshop.exe';
    // await shell.openExternal(`"${psPath}" "${absolutePath}"`);
    // macOS示例:
    // const psPath = '/Applications/Adobe Photoshop 2024/Photoshop.app';
    // await shell.openExternal(`open -a "${psPath}" "${absolutePath}"`);

    return { success: true };
  } catch (err) {
    return { success: false, error: err.message };
  }
});

2. Angular渲染进程触发调用

// app.component.ts
async openInPhotoshop(filePath: string) {
  const result = await ipcRenderer.invoke('open-with-photoshop', filePath);
  if (!result.success) {
    console.error('打开失败:', result.error);
    // 可添加用户错误提示逻辑
  }
}

三、Angular环境关键配置

  1. 配置BrowserWindow与预加载脚本:
    Electron 12+推荐开启上下文隔离,通过预加载脚本安全暴露API:
    // main.js
    mainWindow = new BrowserWindow({
      width: 800,
      height: 600,
      webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
        contextIsolation: true,
        nodeIntegration: false
      }
    });
    
  2. 预加载脚本(preload.js):
    安全桥接主进程与Angular渲染进程:
    // preload.js
    const { contextBridge, ipcRenderer } = require('electron');
    
    contextBridge.exposeInMainWorld('electronAPI', {
      storeSet: (key, value) => ipcRenderer.invoke('store-set', key, value),
      storeGet: (key) => ipcRenderer.invoke('store-get', key),
      openWithPhotoshop: (filePath) => ipcRenderer.invoke('open-with-photoshop', filePath)
    });
    
  3. Angular中使用暴露的API:
    声明全局类型避免TS报错,直接调用:
    // app.component.ts
    declare global {
      interface Window {
        electronAPI: {
          storeSet: (key: string, value: any) => Promise<boolean>,
          storeGet: (key: string) => Promise<any>,
          openWithPhotoshop: (filePath: string) => Promise<{ success: boolean, error?: string }>
        }
      }
    }
    
    // 调用示例
    async ngOnInit() {
      await window.electronAPI.storeSet('user', { name: 'test' });
      const user = await window.electronAPI.storeGet('user');
      console.log(user);
    }
    

四、示例项目参考

核心逻辑围绕「预加载脚本做API桥接 + IPC实现主/渲染进程通信 + electron-store处理存储 + shell调用外部应用」搭建,你可以基于上述代码片段组合成完整示例。


内容的提问来源于stack exchange,提问作者Abhey Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:22:32