Node.js 如何打开本地应用

2023年 10月 13日 27.9k 0

最近在开发的过程中接到这样一个需求,需要通过代码,帮助用户启动本地的 Docker Desktop。

需求背景

我们做的是一个 electron 应用,在用户使用的过程中会依赖到 docker 。为了减少用户操作,我们需要在检测到 docker 没有启动的情况下,帮助用户唤起docker Desktop。

实现过程

不同的操作系统,唤起 Dcoker Desktop 的方式都不一样,Linux 用户通常不会安装 Docker Desktop ,所以,Linux 用户启动docker 的方式很简单,直接通过命令行 sudo systemctl start docker ,Mac 系统也有自己专门启动应用的指令 open -a Docker,最难搞的就是 Windows 系统……

不同的用户在安装 Docker 的时候会选择不同的安装位置,所以找到 Docker 的安装位置就很关键。

Docker 在安装的时候,会在系统的注册表中写入安装位置的相关信息,所以我们要获取到 Docker 安装地址,可以从查询系统注册表入手。

import { execSync } from 'child_process'
import path from 'path'

function findDockerDesktop() {
  try {
    // 应用名称
    const applicationName = 'Docker'
    // 查询注册表
    const command = `reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s /f "${applicationName}"`;

    // 执行查询命令
    const res = execSync(command);
    const stdout = res.toString()
    const match = stdout.match(/InstallLocations+REG_SZs+(.*)/)

    if (match && match[1]) {
      const dockerInstallerPath = path.resolve(match[1].trim(), 'Docker Desktop.exe')
      return dockerInstallerPath
    } else {
      throw new Error('未找到应用程序的安装位置');
    }
  } catch (error) {
    console.error(`查询应用程序安装位置时出错: ${(error as Error).message}`);
  }
}

这里通过 reg query 命令直接查询系统系统的注册表,查询的应用名称是 Docker

由于 execSync 返回的结果是一个 Buffer,所以我这里通过 toString 把他转成 utf8 字符串。查询结果如下:

列表中的 InstallLocation 对应的地址就是 Docker 的安装位置。我们通过正则将其查出来。

这一条就是我们想要的,但是这个只是 Docker 的安装目录,要启动 Docker 还要找到他的可执行文件,所以要在安装目录的地址上再拼上 Docker Desktop.exe

找到这个 Docker 的可执行文件之后,接下来就简单多了。

直接启动!

function setupDocker() {
  try {
    execSync(findDockerDesktop())
    console.log('Windows Docker Desktop started successfully!')
  } catch (error) {
    console.error((error as Error).toString())
  }
}

执行之后发现会报错……

'C:Program' is not recognized as an internal or external command,
operable program or batch file.
Error: Command failed: C:Program FilesDockerDockerDocker Desktop.exe
'C:Program' is not recognized as an internal or external command,      
operable program or batch file.

这个错误的原因是路径中的 C:Program Files,在执行这条命令的时候,终端把 File 及其之后的部分当成 C:Program 参数了,要解决这个问题也很简单,把这个命令用字符串再包一层就可以了。

function setupDocker() {
  try {
    execSync(`"${findDockerDesktop()}"`)
    console.log('Windows Docker Desktop started successfully!')
  } catch (error) {
    console.error(error.message)
  }
}

写到这里,基本就完成了整个功能的实现。如果要兼容 Mac 系统的话,可以再把最后的代码再小改一下。

function setupDocker() {
  try {
    if (process.platform === 'darwin') {
      execSync('open -a Docker')
      console.log('Mac Docker Desktop started successfully!')
    } else {
      execSync(`"${findDockerDesktop()}"`)
      console.log('Windows Docker Desktop started successfully!')
    }
  } catch (error) {
    console.error(error.message)
  }
}

这次真的写完了,哦对了,我是个前端er……

相关文章

服务器端口转发,带你了解服务器端口转发
服务器开放端口,服务器开放端口的步骤
产品推荐:7月受欢迎AI容器镜像来了,有Qwen系列大模型镜像
如何使用 WinGet 下载 Microsoft Store 应用
百度搜索:蓝易云 – 熟悉ubuntu apt-get命令详解
百度搜索:蓝易云 – 域名解析成功但ping不通解决方案

发布评论