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

Visual studio code 如何从VSCode扩展运行系统命令,visual-studio-code,vscode-extensions,Visual Studio Code,Vscode Extensions,我试图创建一个简单的VSCode扩展,以便在打开文件夹时运行一组命令。基本上,这些命令将设置我们的开发环境。我已经开始创建boilerplace并运行了VSCode提供的示例,但我不清楚如何运行系统命令。非常感谢您的帮助,或者为我提供一些关于此主题的文档 您的扩展环境可以访问node.js库,因此您可以使用或任何助手库来执行命令: const cp=require('child_process') cp.exec('pwd',(err、stdout、stderr)=>{ log('stdout:

我试图创建一个简单的VSCode扩展,以便在打开文件夹时运行一组命令。基本上,这些命令将设置我们的开发环境。我已经开始创建boilerplace并运行了VSCode提供的示例,但我不清楚如何运行系统命令。非常感谢您的帮助,或者为我提供一些关于此主题的文档

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

const cp=require('child_process')
cp.exec('pwd',(err、stdout、stderr)=>{
log('stdout:'+stdout);
log('stderr:'+stderr);
如果(错误){
log('error:'+err);
}
});

另一种选择是使用,如果您需要用户完全可以观察和控制流程,则使用是最好的选择

最大的缺点是:还没有提供一种方法来反省内部运行的流程

如果您确实希望在终端中运行该进程,目前安全运行该进程的唯一方法是使用两层方法,即启动包装进程,然后启动并观察实际进程(通过命令行args接收)

我们自制的包装纸 我们自己也试过

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

  • 在第二种方法中,我们使用
    bash-c
    (非交互式shell)简化并创建了终端,并使用一个文件查看器来获得结果。这种方法更简单,但在完成过程后,用户将无法使用终端窗口(因为它是非交互式的)。更不容易出错,并且不需要满足socket.io依赖关系

实施细节
  • 在我们的扩展中,我们使用一个在包装器进程内运行命令的函数,并等待一个包含结果的文件
  • 包装过程是。它将结果写入一个文件
  • 用法示例:
  • const cwd=';
    const命令=`node-e“console.log('hi!');“`;
    const{code}=wait TerminalWrapper.execinternal(cwd,命令,{}).waitForResult();
    if(代码){
    const processExecMsg=`${cwd}$${command}`;
    抛出新错误(`Process failed with exit code${code}(${processExecMsg})`);
    }
    
    第二种方法的最大缺点是我们现在需要
    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‘创建后立即发送文本’”);
    }));
    
    终端激活事件
    vscode.window.onDidChangeActiveTerminal(e=>{
    log(`activeterminalchanged,name=${e?e.name:'undefined'}`);
    });
    
    TerminalQuickPickItem
    函数selectTerminal():表格{
    接口终端QuickPickItem扩展vscode.QuickPickItem{
    终端:vscode.terminal;
    }
    常数端子=(


    (我所做的是创建一个基于承诺的实用程序函数,用child_进程运行所有shell命令

    从“子进程”导入*作为cp;
    const execShell=(cmd:string)=>
    新承诺((解决、拒绝)=>{
    cp.exec(cmd,(err,out)=>{
    如果(错误){
    退货拒绝(err);
    }
    返回解析(out);
    });
    });
    
    获取当前目录的步骤

    const currentDir=wait execShell('pwd');
    
    获取当前git分支名称的步骤

    const branchName=await execShell('git rev parse--abbrev ref HEAD');
    
    这就是我们应该这样做的方式?没有VSCode优美的API可以做到这一点?比如,如果用户突然关闭VSCode怎么办?这意味着我的扩展外部进程可能会永远运行?不,它是一个child_进程,在这种情况下,当VSCode进程终止时,任何子进程都会终止。@MatBee遗憾的是,child pro不是这样的CESS有效。请参阅:See@MattBierner它变得非常混乱,最终成为非常非跨平台的形式,正如您在自己链接的文档中所读到的那样,引用:“在非Windows平台上,[…]子进程可以在父进程退出后继续运行,无论它们是否分离。”有没有办法知道正在运行的终端是否繁忙?感谢终端API目前非常有限。它不允许您查询任何关于其状态的信息,除了是否打开、其PID、尺寸以及您在上面的屏幕截图中看到的其他信息。您甚至可以使用
    onDidWriteTerminalData获取输出
    event(不过,这可能永远不会成为所讨论的稳定API的一部分)。遗憾的是,除非像我上面介绍的那样将您的命令包装到observer应用程序中,否则无法知道终端内部是否正在运行或正在运行什么。