交叉配送终端开放
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" 终端应用程序至多是一个有根据的猜测。
然而,有多种方法可以考虑解决这个(审美)问题:
- 让用户决定他们想要什么终端应用程序。如果你的应用程序有一个配置文件,你可以用它来写入一个用户指定的值,并把它作为终端应用程序。理论上,他们可以指定一个不是终端应用程序的应用程序的路径,但那是他们的错。
- 编译已知终端应用程序的列表并检查它们是否已安装。例如,您可以制作一个(有序的)应用程序列表,您的应用程序应该搜索和如果找到 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" 命令对 bash 和 cmd 都有效.所以我在这里用它作为例子。
在 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" 终端应用程序至多是一个有根据的猜测。
然而,有多种方法可以考虑解决这个(审美)问题:
- 让用户决定他们想要什么终端应用程序。如果你的应用程序有一个配置文件,你可以用它来写入一个用户指定的值,并把它作为终端应用程序。理论上,他们可以指定一个不是终端应用程序的应用程序的路径,但那是他们的错。
- 编译已知终端应用程序的列表并检查它们是否已安装。例如,您可以制作一个(有序的)应用程序列表,您的应用程序应该搜索和如果找到 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" 命令对 bash 和 cmd 都有效.所以我在这里用它作为例子。