# electron 实现协议唤起功能

300 阅读1分钟

一、场景描述

在web端页面点击按钮,唤起pc程序并传入参数,即桌面端程序关联url

二、实现方式:

对于windows桌面应用来说,关联url协议是通过修改注册表来实现的

1. 注册表添加URL协议

1.1 打开注册表

打开cmd ,输入 regedit

1.2 注册表地址

计算机\HKEY_CURRENT_USER\Software\Classes

需要在此路径下创建URL字符串

myapp 
     Default                                  URL: myapp
     URL Protoxol      
  shell  
    open
      command
         Default                               程序安装路径
               

2.electron 实现url关联协议

    // 判断是否注册过协议并进行注册
   const args = [];
    if (!app.isPackaged) {
        args.push(path.resolve(process.argv[1]));
    }
    args.push('--');
    if(!app.isDefaultProtocolClient(PROTOCOL, process.execPath, args)){
        app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, args);
    }
    handleArgv(process.argv);
    
  app.on('second-instance', (event,argv,workingDirectory,additionalData) => {
        if (process.platform === 'win32') {
            handleArgv(argv);
            global.win.webContents.send('url-download',global.downArgs)
        }
    })   
    
 //  处理url参数   
function handleArgv(argv: any) {
    const prefix = `${PROTOCOL}:`;
    const offset = app.isPackaged ? 1 : 2;
    const url = argv.find((arg: any, i: any) => i >= offset && arg.startsWith(prefix));
    if (url) handleUrl(url);
}
function handleUrl(urlStr: any) {
    const urlObj = new URL(urlStr);
    const { searchParams } = urlObj;
    console.log(searchParams.get('fileid'));
    global.downArgs = {
        fileid: searchParams.get('fileid')
    }
}  
​
​
// electron 在主进程注册url协议之后还需考虑如何将参数传递到渲染进程
1. 当程序启动后唤起桌面应用
   在 app "second-instance" 钩子中使用 
   app.on('second-instance', (event,argv,workingDirectory,additionalData) => {
        if (process.platform === 'win32') {
            handleArgv(argv);
            global.win.webContents.send('url-download',global.downArgs)
        }
    })
  将参数透传给渲染进程,渲染进程接受参数进行下一步操作
2. 当程序未启动时, "second-instance",无法执行,可通过BrowserWindow"did-finish-load"来将参数传递给渲染进程
     win.webContents.on('did-finish-load', () => {
       global.win.webContents.send('url-download-init',global.downArgs)
     })
​