交叉配送终端开放

Cross distribution terminal opening

在 electron 中,我正在注册一个打开终端的快捷方式:

globalShortcut.register('CommandOrControl+Alt+Shift+P', () => {
    spawn(os.platform() === 'linux' ? 'xterm' : 'cmd');
});

我注意到 xterm 与从 OS 菜单打开的终端没有相同的 "style",我发现后者是由桌面环境定制的(我有一个 Ubuntu Mate,它的终端是 mate-terminal 和一个 RedHat 7.5 konsole).

我读到 here nodejs 没有 API 来检测分布,因此根据分布知道 运行 哪个终端似乎不可行。

有什么方法可以打开正确的终端或将 xterm 设置为 OS 的样式吗?

Node.js 不提供检测发行版名称的方法,因为没有标准的方法从不同的 Linux 分布.

但是您可以使用库 sush 来完成 getos:

const getos = require('getos');

getos((err, os) => {
  if (err) return console.log(err);
  console.log(os.dist, os.codename)
})

TL;DR: 没有标准化的 API,您无法确定分发是否表示终端应用程序。

首先,XTerm、Mate's Terminal、Konsole等都是不同的应用。因为 Ubuntu Mate under the hood 报告为 Ubuntu,AFAIK,你甚至不能确定这是注册为 "the" 终端应用程序的应用程序。此外,几乎每个桌面环境都带有自己的终端应用程序,并且由于您可以并排安装多个终端应用程序,因此自动 select 一个 "appropriate" 终端应用程序至多是一个有根据的猜测。

然而,有多种方法可以考虑解决这个(审美)问题:

  1. 让用户决定他们想要什么终端应用程序。如果你的应用程序有一个配置文件,你可以用它来写入一个用户指定的值,并把它作为终端应用程序。理论上,他们可以指定一个不是终端应用程序的应用程序的路径,但那是他们的错。
  2. 编译已知终端应用程序的列表并检查它们是否已安装。例如,您可以制作一个(有序的)应用程序列表,您的应用程序应该搜索和如果找到 none 个,则回退到 XTerm(因为它安装在大多数桌面系统 运行 Linux 上)。要查看某个应用程序是否已安装并可在 Linux 上运行,您可以使用 which 命令。示例:
const { spawnSync } = require ("child_process");
const terms = [ "konsole", "mate-terminal", "gnome-terminal" /* ... */ ];
var terminal = null;

// In your startup method (e.g. before opening a BrowserWindow)
if (os.platform () === "linux") {
    for (term in terms) {
        which = spawnSync ("which", [term]);
        if (which.status !== null && which.status === 0) { // Command found
            terminal = term;
            break;
        }
    }
    if (terminal === null) terminal = "xterm";
} else {
    terminal = "cmd";
}

当然,您也可以使用 spawn 代替 spawnSync,但这会变得更加复杂。此外,这只会为您提供发现要安装的第一个应用程序,而不是 select 用于桌面环境的 "appropriate"。但我相信,如果您希望您的应用程序(某种程度上)无缝集成到 DE 中,那么这是朝着正确方向迈出的重要一步。

附带说明一下,您的代码没有考虑 MacOS,但也可以在 MacOS 上打开一个终端,在那里简称为 "Terminal"。

有一个包叫OpenTerm,它有可配置的功能,自动决定使用的终端,目前支持windows和linux,但不支持MacOs。

const { VTexec } = require('open-term')
VTexec('help') // Runs "help" command in determined terminal.

"help" 命令对 bashcmd 都有效.所以我在这里用它作为例子。