1.创建默认关联程序

(1)创建扩展名的程序关联
使用electron-builder打包软件,运行打包后的安装程序,安装完成后实现了软件与扩展名的关联。
package.json
ext:文件扩展名,可关联多个,如[“amsx”,“amsx1”]。
name:程序名,可任意值,建议取实际的程序名(name值)。
role:编辑器,固定值为"Editor"。
示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
 "scripts": {
    "start": "electron .",
    "dist": "electron-builder --win --x64"
  },
"build": {
    "fileAssociations": [
      {
        "ext": "amsx1",
        "name": "amod 软件",
        "role": "Editor"
      }
    ],
},

image.png

DefaultIcon:定义扩展名的图标,默认取关联程序图标。
image.png
(2)读取关联文件
main.js文件中通过 process.argv[1] 方法获取关联文件的路径。

2.注册程序信息

运行程序,自动写注册表。(用于扩展名关联的补充功能。)
main.js
(1)app.setAsDefaultProtocolClient(‘msx3’);
process.argv[1]:关联的程序路径。
image.png
(2)app.setAsDefaultProtocolClient(‘modsim1’, process.execPath);
process.argv[1]:关联的程序路径。
image.png
(3)app.setAsDefaultProtocolClient(‘modsim2’, process.execPath, [‘–open-file’]);
用于mac系统,监听’open-file’,windows系统不需要。
image.png
示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const { app, BrowserWindow , dialog} = require('electron')
# 在注册表中创建程序信息
app.setAsDefaultProtocolClient('modsim1', process.execPath);

function createWindow () {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
  dialog.showMessageBox({ type: 'info'title: 'argv[1]', message: process.argv[1], buttons: ['确认', '取消']}).then(response => {console.log(`点击的按钮: ${response.response}`); });

  // and load the index.html of the app.
  mainWindow.loadFile('index.html')

  // Open the DevTools.
  mainWindow.webContents.openDevTools()
}

electron 安装读取注册表的模块:electron-windows-registry模块
https://www.techphant.cn/blog/42860.html

3.打开文件浏览器选中文件

1
2
3
4
5
6
7
8
9
 //主进程:
ipcMain.on('open-project-folder', (e, data: {path:string}) => {
    const { exec } = require('child_process');
    exec(explorer.exe /select,"${data.path}"); // c:\\test.txt
});
//渲染进程:
window.ipcRenderer.send('open-project-folder', {
      path: CurrentProjectInfo.path // getDirectoryPath(CurrentProjectInfo.path)
    });

4.‘undefined’ 解决方法

Cannot invoke an object which is possibly ‘undefined’ 解决方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

错误 ‌**"Cannot invoke an object which is possibly 'undefined'"**‌ 是 TypeScript 编译器发出的警告,表示代码尝试调用一个可能未定义(`undefined`)的对象(如函数或方法),这可能导致运行时错误。该错误常见于类型系统无法确保对象在调用前已正确定义的场景。‌12

‌**常见原因与场景:**‌ 此错误通常出现在以下情况:

- ‌**可选属性或参数**‌:对象的属性或函数参数被定义为可选(例如使用 `?` 符号),但调用时未检查其存在性。
- ‌**异步或生命周期问题**‌:在组件生命周期(如 Vue 的 `beforeCreate` 阶段)中,某些对象尚未初始化,导致访问时为 `undefined`。
- ‌**匿名函数或回调传递**‌:如在ArkTS中通过 `@builder` 传递匿名函数时,若未正确定义参数类型,可能触发此错误。
- ‌**JSON解析或动态数据**‌:解析字符串后访问可能不存在的键值时,对象可能为 `undefined`。‌

‌**解决方法:**‌ 针对不同场景,可采用以下策略:

- ‌**使用可选链操作符(Optional Chaining)**‌:在调用前添加 `?.`,若对象为 `undefined` 则返回 `undefined` 而非抛错。例如,`obj?.method()` 或 `props.removeTodo?.()`。
- ‌**存在性检查**‌:通过 `if` 语句显式判断对象是否存在,再进行调用,如 `if (callback) { callback(); }`。
- ‌**类型断言**‌:若确定对象不会为 `undefined`,可使用非空断言操作符 `!`,如 `callback!()`,但需谨慎确保安全性。
- ‌**调整接口定义**‌:避免将必需方法设为可选属性,或通过默认值确保初始化。
- ‌**检查组件生命周期**‌:在框架(如 Vue)中,确保在对象已定义的生命周期钩子(如 `mounted`)中调用方法。‌13