我正在使用Electron构建的内部工具来运行各种NodeJS和Shell脚本。
我想打开一个默认的MacOS Terminal窗口并运行命令。我知道并使用child_process
,spawn()
和fork()
之类的NodeJS exec()
函数用于其他目的,但是在某些情况下,我更喜欢打开桌面OS终端窗口,因为命令输出很复杂,包括escape codes,尾部日志,将由开发人员使用,这些开发人员可能希望在应用程序启动后控制终端。
我尝试将exec()
和spawn()
用作described here的open -a Terminal
和import {exec} from "child_process";
import os = require("os");
export function openTerminal(cmd: string) {
if (os.platform() !== 'darwin') throw new Error('Not supported');
const command = [
`osascript -e 'tell application "Terminal" to activate'`,
`-e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down'`,
`-e 'tell application "Terminal" to do script "${cmd}" in selected tab of the front window'`
].join(" ");
const child = exec(command, (error, stdout, stderr) => {
if (error) {
console.error(error);
alert("Unable to open Terminal window, see dev console for error.");
}
});
child.on("exit", (code) => console.log("Open terminal exit"));
}
,但是它根本没有打开终端窗口。
我目前有一个基于this article的解决方案,如下所示:
electron-packager
这可行,但存在一些问题:
最初,电子应用程序(由.text{
line-height: 1;
}
构建)不允许运行此命令,并且提示用户“此应用程序要控制您的计算机”。如果用户接受该对话框,则该命令和后续命令仍将无法打开“终端”窗口。他们必须进入OS安全性/辅助功能设置,解锁管理员权限,将应用程序设置为允许控制,关闭该应用程序,然后重新打开。然后它可能会起作用。
在工作条件下(请参见上文),要花费很长时间才能显示窗口。
如果终端已经打开(通常是这种情况),它经常(但并非总是)无法在新窗口中运行命令,而是它将复制一个现有选项卡并在原始选项卡中运行命令,如果该选项卡已经在运行命令,则可能不起作用。即使这样做确实不是很理想,也应该在新选项卡中而不是现有选项卡中运行命令。
是否可以通过Electron在MacOS中打开终端窗口来避免这些问题?