如何从VSCode扩展运行系统命令

时间:2017-03-24 19:00:35

标签: visual-studio-code vscode-extensions

我正在尝试创建一个简单的VSCode扩展,以便在打开文件夹时运行一组命令。基本上这些命令将建立我们的开发环境。我已经开始创建锅炉并运行VSCode提供的示例,但我不清楚如何运行系统命令。感谢任何帮助或指出我有关此主题的一些文档。

3 个答案:

答案 0 :(得分:12)

您的扩展环境可以访问node.js库,因此您只需使用child_process或任何帮助程序库来执行命令:

const cp = require('child_process')
cp.exec('pwd', (err, stdout, stderr) => {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (err) {
        console.log('error: ' + err);
    }
});

答案 1 :(得分:5)

一种替代方法是使用Terminal API,如果您需要该过程对用户/用户完全可观察和控制的话,这是最佳选择。

最大的缺点:Terminal API尚未提供对内部运行的进程进行自省的方法。

如果您实际上想在终端中运行该进程,则目前暂时安全地执行此操作的唯一方法是使用两层方法,在此方法中,您将启动一个包装器过程,该包装器过程随后将启动并观察实际过程(通过命令行args输入)。

我们自制的TerminalWrapper

我们自己尝试过。

  • 在我们的第一种方法中,包装器使用了socket.io连接,该连接允许与扩展通信并由其控制。

  • 在第二种方法中,我们使用bash -c(非交互式外壳程序)简化并创建了终端,并使用文件监视程序来获取结果。这样比较容易,但是在完成该过程之后,用户将无法使用“终端”窗口(因为它是非交互式的)。

实施细节

  1. 在我们的扩展程序中,我们使用TerminalWrapper在包装程序内部运行命令,并等待包含结果的文件。
  2. 包装程序为here。它将结果写入文件。
  3. 用法示例here
const command = `node -e "console.log('hi!');"`;
const terminalWrapper = execInTerminal(cwd, command, moreOptions);
const result = await terminalWrapper.waitForResult();

第二种方法的最大缺点是,我们现在需要bash才能出现,但是(i)我们确实有一个依赖项检查器,如果您不这样做,它会警告您并说明如何获取它,以及(ii)使用统一的shell,使运行命令变得更加容易,因为我们现在有了相当强大的统一功能集,我们知道我们可以依靠,而不仅仅是能够使用通用的命令执行语法,并且(iii)甚至可以运行*.sh文件而不必担心。

简介:VSCode终端API

以下所有图像和摘录均直接从其官方样本库中复制粘贴:

创建一个终端并在其中运行命令

context.subscriptions.push(vscode.commands.registerCommand('terminalTest.createAndSend', () => {
    const terminal = vscode.window.createTerminal(`Ext Terminal #${NEXT_TERM_ID++}`);
    terminal.sendText("echo 'Sent text immediately after creating'");
}));

终端激活事件

vscode.window.onDidChangeActiveTerminal(e => {
    console.log(`Active terminal changed, name=${e ? e.name : 'undefined'}`);
});

TerminalQuickPickItem

function selectTerminal(): Thenable<vscode.Terminal | undefined> {
    interface TerminalQuickPickItem extends vscode.QuickPickItem {
        terminal: vscode.Terminal;
    }
    const terminals = <vscode.Terminal[]>(<any>vscode.window).terminals;
    const items: TerminalQuickPickItem[] = terminals.map(t => {
        return {
            label: `name: ${t.name}`,
            terminal: t
        };
    });
    return vscode.window.showQuickPick(items).then(item => {
        return item ? item.terminal : undefined;
    });
}

...还有更多!...

Terminal API Sample Commands

(VSCode团队及其辛勤工作的<3。)

答案 2 :(得分:0)

我所做的是创建一个基于Promise的实用程序函数,以使用child_process运行所有shell命令

import * as cp from 'child_process';

const execShell = (cmd: string) =>
    new Promise<string>((resolve, reject) => {
        cp.exec(cmd, (err, out) => {
            if (err) {
                return reject(err);
            }
            return resolve(out);
        });
    });

获取当前目录

const currentDir = await execShell('pwd');

获取当前的git分支名称

const branchName = await execShell('git rev-parse --abbrev-ref HEAD');