Visual studio code VS代码扩展:使用vscode.CustomExecution的所有已定义任务返回上次定义任务的结果 进入

Visual studio code VS代码扩展:使用vscode.CustomExecution的所有已定义任务返回上次定义任务的结果 进入,visual-studio-code,vscode-extensions,Visual Studio Code,Vscode Extensions,我创建了一个简单的VS代码扩展,它定义了多个任务: ExamplePseudoterminal1 Task 1, ExamplePseudoterminal1 Task 2, ExamplePseudoterminal1 Task 3 ExamplePseudoterminal2 Task 1, ExamplePseudoterminal2 Task 2, ExamplePseudoterminal2 Task 3 示例伪终端1任务任务接收一个参数,并将其打印到终端。 示例伪终端2任务任务接收

我创建了一个简单的VS代码扩展,它定义了多个任务:

ExamplePseudoterminal1 Task 1, ExamplePseudoterminal1 Task 2, ExamplePseudoterminal1 Task 3
ExamplePseudoterminal2 Task 1, ExamplePseudoterminal2 Task 2, ExamplePseudoterminal2 Task 3
示例伪终端1任务
任务接收一个参数
,并将其打印到终端。
示例伪终端2任务
任务接收一个参数
,并将
2*
打印到终端


问题 当我运行一个任务(
Terminal->runtask…->“MyTask”
)时,上面列出的所有任务都会显示出来。 但是,这些任务中的每个任务的结果都是最后添加的任务的结果(即
示例伪终端2任务3
->
6

我做错了什么

有什么我忘了的吗


示例代码 更改的文件:

src/extension.ts

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

    console.log('Congratulations, your extension "exampleext" is now active!');

    const use_type: string = "MyTask"
    const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(use_type, {
        provideTasks(token?: vscode.CancellationToken) {
            const output_taks: vscode.Task[] = [];

            const use_type: string = "MyTask"
            for (const entry of [1, 2, 3]){

                console.log(`Processing ${entry}`);

                const new_task_1: vscode.Task = new vscode.Task(
                    {type: use_type}, vscode.TaskScope.Workspace,
                    `ExamplePseudoterminal1 Task ${entry}`, use_type,
                    new vscode.CustomExecution(
                        async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
                            return new ExamplePseudoterminal1(entry);
                        }),
                    [""]
                );
                output_taks.push(new_task_1);

                const new_task_2: vscode.Task = new vscode.Task(
                    {type: use_type}, vscode.TaskScope.Workspace,
                    `ExamplePseudoterminal2 Task ${entry}`, use_type,
                    new vscode.CustomExecution(
                        async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
                            return new ExamplePseudoterminal2(entry);
                        }),
                    [""]
                );
                output_taks.push(new_task_2);

            }

            return output_taks;
        },
        resolveTask(task: vscode.Task, token?: vscode.CancellationToken) {
            return task;
        }
    });
    context.subscriptions.push(myTask_TaskProvider);
}

export function deactivate() {
}

class ExamplePseudoterminal1 implements vscode.Pseudoterminal {

    private readonly writeEmitter = new vscode.EventEmitter<string>();
    public onDidWrite: vscode.Event<string> = this.writeEmitter.event;

    private readonly closeEmitter = new vscode.EventEmitter<void>();
    public onDidClose?: vscode.Event<void> = this.closeEmitter.event;

    private value: number;

    public constructor(in_number: number) {
        this.value = in_number;
        console.log(`this.value: ${this.value}`);
    }

    public open(initialDimensions: vscode.TerminalDimensions | undefined) {
        console.log("open");

        this.writeEmitter.fire(`${this.value}`);

        this.closeEmitter.fire();
    }

    close(): void {
        console.log("close");
    }
}

class ExamplePseudoterminal2 implements vscode.Pseudoterminal {

    private readonly writeEmitter = new vscode.EventEmitter<string>();
    public onDidWrite: vscode.Event<string> = this.writeEmitter.event;

    private readonly closeEmitter = new vscode.EventEmitter<void>();
    public onDidClose?: vscode.Event<void> = this.closeEmitter.event;

    private value: number;

    public constructor(in_number: number) {
        this.value = in_number * 2;
        console.log(`this.value: ${this.value}`);
    }

    public open(initialDimensions: vscode.TerminalDimensions | undefined) {
        console.log("open");

        this.writeEmitter.fire(`${this.value}`);

        this.closeEmitter.fire();
    }

    close(): void {
        console.log("close");
    }
}
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

    console.log('Congratulations, your extension "exampleext" is now active!');

    const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(
        CustomBuildTaskProvider.TaskType, new CustomBuildTaskProvider()
    );

    context.subscriptions.push(myTask_TaskProvider)
}

export function deactivate() {
}


interface CustomBuildTaskDefinition extends vscode.TaskDefinition {
    number: number;
}

export class CustomBuildTaskProvider implements vscode.TaskProvider {
    static TaskType = 'custombuildscript';
    private tasks: vscode.Task[] | undefined;

    constructor() { }

    public async provideTasks(): Promise<vscode.Task[]> {
        return this.getTasks();
    }

    public resolveTask(_task: vscode.Task): vscode.Task | undefined {
        const type: string = _task.definition.type;
        if (type === CustomBuildTaskProvider.TaskType) {
            const definition: CustomBuildTaskDefinition = <any>_task.definition;
            return this.getTask(definition);
        }
        return undefined;
    }

    private getTasks(): vscode.Task[] {
        if (this.tasks !== undefined) {
            return this.tasks;
        }

        const in_values: number[] = [1, 2, 3];

        this.tasks = [];
        in_values.forEach(value => {
            const active_def: CustomBuildTaskDefinition = {
                type: CustomBuildTaskProvider.TaskType,
                number: value
            }
            this.tasks!.push(this.getTask(active_def));
        });
        return this.tasks;
    }

    private getTask(definition: CustomBuildTaskDefinition): vscode.Task {

        return new vscode.Task(
            definition,
            vscode.TaskScope.Workspace,
            `TestTask ${definition.number}`,
            definition.type, new vscode.CustomExecution(
                async (): Promise<vscode.Pseudoterminal> => {
                    return new ExamplePseudoterminal1(definition.number);
                }
            ),
            [""]
        );
    }
}


class ExamplePseudoterminal1 implements vscode.Pseudoterminal {

    private readonly writeEmitter = new vscode.EventEmitter<string>();
    public onDidWrite: vscode.Event<string> = this.writeEmitter.event;

    private readonly closeEmitter = new vscode.EventEmitter<void>();
    public onDidClose?: vscode.Event<void> = this.closeEmitter.event;

    private value: number;

    public constructor(in_number: number) {
        this.value = in_number;
        console.log(`this.value: ${this.value}`);
    }

    public open(initialDimensions: vscode.TerminalDimensions | undefined) {
        console.log("open");

        this.writeEmitter.fire(`${this.value}`);

        this.closeEmitter.fire();
    }

    close(): void {
        console.log("close");
    }
}

系统
  • VS代码版本:1.55.1
  • VS代码提交:08a217c4d27a02a5bcde898fd7981bda5b49391b
  • Node.js:12.18.3
  • 操作系统:macOS 11.2.3

基于中示例的解决方案。 这使用了
vscode.TaskProvider
的更完整定义。重要的部分似乎是:
接口CustomBuildTaskDefinition扩展了vscode.TaskDefinition
package.json
中完整的
taskDefinitions

src/extension.ts

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

    console.log('Congratulations, your extension "exampleext" is now active!');

    const use_type: string = "MyTask"
    const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(use_type, {
        provideTasks(token?: vscode.CancellationToken) {
            const output_taks: vscode.Task[] = [];

            const use_type: string = "MyTask"
            for (const entry of [1, 2, 3]){

                console.log(`Processing ${entry}`);

                const new_task_1: vscode.Task = new vscode.Task(
                    {type: use_type}, vscode.TaskScope.Workspace,
                    `ExamplePseudoterminal1 Task ${entry}`, use_type,
                    new vscode.CustomExecution(
                        async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
                            return new ExamplePseudoterminal1(entry);
                        }),
                    [""]
                );
                output_taks.push(new_task_1);

                const new_task_2: vscode.Task = new vscode.Task(
                    {type: use_type}, vscode.TaskScope.Workspace,
                    `ExamplePseudoterminal2 Task ${entry}`, use_type,
                    new vscode.CustomExecution(
                        async function(resolvedDefinition: vscode.TaskDefinition): Promise<vscode.Pseudoterminal> {
                            return new ExamplePseudoterminal2(entry);
                        }),
                    [""]
                );
                output_taks.push(new_task_2);

            }

            return output_taks;
        },
        resolveTask(task: vscode.Task, token?: vscode.CancellationToken) {
            return task;
        }
    });
    context.subscriptions.push(myTask_TaskProvider);
}

export function deactivate() {
}

class ExamplePseudoterminal1 implements vscode.Pseudoterminal {

    private readonly writeEmitter = new vscode.EventEmitter<string>();
    public onDidWrite: vscode.Event<string> = this.writeEmitter.event;

    private readonly closeEmitter = new vscode.EventEmitter<void>();
    public onDidClose?: vscode.Event<void> = this.closeEmitter.event;

    private value: number;

    public constructor(in_number: number) {
        this.value = in_number;
        console.log(`this.value: ${this.value}`);
    }

    public open(initialDimensions: vscode.TerminalDimensions | undefined) {
        console.log("open");

        this.writeEmitter.fire(`${this.value}`);

        this.closeEmitter.fire();
    }

    close(): void {
        console.log("close");
    }
}

class ExamplePseudoterminal2 implements vscode.Pseudoterminal {

    private readonly writeEmitter = new vscode.EventEmitter<string>();
    public onDidWrite: vscode.Event<string> = this.writeEmitter.event;

    private readonly closeEmitter = new vscode.EventEmitter<void>();
    public onDidClose?: vscode.Event<void> = this.closeEmitter.event;

    private value: number;

    public constructor(in_number: number) {
        this.value = in_number * 2;
        console.log(`this.value: ${this.value}`);
    }

    public open(initialDimensions: vscode.TerminalDimensions | undefined) {
        console.log("open");

        this.writeEmitter.fire(`${this.value}`);

        this.closeEmitter.fire();
    }

    close(): void {
        console.log("close");
    }
}
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {

    console.log('Congratulations, your extension "exampleext" is now active!');

    const myTask_TaskProvider: vscode.Disposable = vscode.tasks.registerTaskProvider(
        CustomBuildTaskProvider.TaskType, new CustomBuildTaskProvider()
    );

    context.subscriptions.push(myTask_TaskProvider)
}

export function deactivate() {
}


interface CustomBuildTaskDefinition extends vscode.TaskDefinition {
    number: number;
}

export class CustomBuildTaskProvider implements vscode.TaskProvider {
    static TaskType = 'custombuildscript';
    private tasks: vscode.Task[] | undefined;

    constructor() { }

    public async provideTasks(): Promise<vscode.Task[]> {
        return this.getTasks();
    }

    public resolveTask(_task: vscode.Task): vscode.Task | undefined {
        const type: string = _task.definition.type;
        if (type === CustomBuildTaskProvider.TaskType) {
            const definition: CustomBuildTaskDefinition = <any>_task.definition;
            return this.getTask(definition);
        }
        return undefined;
    }

    private getTasks(): vscode.Task[] {
        if (this.tasks !== undefined) {
            return this.tasks;
        }

        const in_values: number[] = [1, 2, 3];

        this.tasks = [];
        in_values.forEach(value => {
            const active_def: CustomBuildTaskDefinition = {
                type: CustomBuildTaskProvider.TaskType,
                number: value
            }
            this.tasks!.push(this.getTask(active_def));
        });
        return this.tasks;
    }

    private getTask(definition: CustomBuildTaskDefinition): vscode.Task {

        return new vscode.Task(
            definition,
            vscode.TaskScope.Workspace,
            `TestTask ${definition.number}`,
            definition.type, new vscode.CustomExecution(
                async (): Promise<vscode.Pseudoterminal> => {
                    return new ExamplePseudoterminal1(definition.number);
                }
            ),
            [""]
        );
    }
}


class ExamplePseudoterminal1 implements vscode.Pseudoterminal {

    private readonly writeEmitter = new vscode.EventEmitter<string>();
    public onDidWrite: vscode.Event<string> = this.writeEmitter.event;

    private readonly closeEmitter = new vscode.EventEmitter<void>();
    public onDidClose?: vscode.Event<void> = this.closeEmitter.event;

    private value: number;

    public constructor(in_number: number) {
        this.value = in_number;
        console.log(`this.value: ${this.value}`);
    }

    public open(initialDimensions: vscode.TerminalDimensions | undefined) {
        console.log("open");

        this.writeEmitter.fire(`${this.value}`);

        this.closeEmitter.fire();
    }

    close(): void {
        console.log("close");
    }
}
import*作为“vscode”中的vscode;
导出函数激活(上下文:vscode.ExtensionContext){
log('恭喜,您的扩展名“exampleext”现在处于活动状态!');
const myTask_TaskProvider:vscode.Disposable=vscode.tasks.registerTaskProvider(
CustomBuildTaskProvider.TaskType,新的CustomBuildTaskProvider()
);
context.subscriptions.push(myTask\u TaskProvider)
}
导出函数停用(){
}
接口CustomBuildTaskDefinition扩展了vscode.TaskDefinition{
编号:编号;
}
导出类CustomBuildTaskProvider实现vscode.TaskProvider{
静态任务类型='custombuildscript';
私有任务:vscode.Task[]|未定义;
构造函数(){}
公共异步providetask():承诺{
返回这个。getTasks();
}
公共resolveTask(_任务:vscode.task):vscode.task |未定义{
常量类型:字符串=_task.definition.type;
if(类型===CustomBuildTaskProvider.TaskType){
常量定义:CustomBuildTaskDefinition=\u task.definition;
返回此.getTask(定义);
}
返回未定义;
}
私有getTasks():vscode.Task[]{
if(this.tasks!==未定义){
返回此任务;
}
常量in_值:数字[]=[1,2,3];
this.tasks=[];
in_values.forEach(值=>{
常量活动定义:CustomBuildTaskDefinition={
类型:CustomBuildTaskProvider.TaskType,
数字:数值
}
this.tasks!.push(this.getTask(active_def));
});
返回此任务;
}
私有getTask(定义:CustomBuildTaskDefinition):vscode.Task{
返回新的vscode.Task(
定义,
vscode.TaskScope.Workspace,
`TestTask${definition.number}`,
definition.type,新的vscode.CustomExecution(
异步():承诺=>{
返回新的ExamplePseudoterminal1(definition.number);
}
),
[""]
);
}
}
类ExamplePseudoterminal1实现vscode.Pseudoterminal{
private readonly writeEmitter=new vscode.EventEmitter();
public onDidWrite:vscode.Event=this.writeEmitter.Event;
private readonly closeEmitter=new vscode.EventEmitter();
public onDidClose?:vscode.Event=this.closeEmitter.Event;
私人价值:数字;
公共构造函数(in_编号:number){
this.value=in_数;
log(`this.value:${this.value}`);
}
公开(初始尺寸:vscode.TerminalDimensions |未定义){
控制台日志(“打开”);
this.writeMitter.fire(`${this.value}`);
这个.closeEmitter.fire();
}
close():void{
控制台日志(“关闭”);
}
}
package-lock.json

{
  "name": "exampleext",
  "displayName": "ExampleExt",
  "description": "Example extension",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.46.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:workbench.action.tasks.runTask"
  ],
  "main": "./out/extension.js",
  "contributes": {
    "taskDefinitions": [
      {
        "type": "MyTask"
      }
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/glob": "^7.1.3",
    "@types/mocha": "^8.0.4",
    "@types/node": "^12.11.7",
    "@types/vscode": "^1.46.0",
    "@typescript-eslint/eslint-plugin": "^4.14.1",
    "@typescript-eslint/parser": "^4.14.1",
    "eslint": "^7.19.0",
    "glob": "^7.1.6",
    "mocha": "^8.2.1",
    "typescript": "^4.1.3",
    "vscode-test": "^1.5.0"
  }
}
{
  "name": "exampleext",
  "displayName": "ExampleExt",
  "description": "Example extension",
  "version": "0.0.1",
  "engines": {
    "vscode": "^1.46.0"
  },
  "categories": [
    "Other"
  ],
  "activationEvents": [
    "onCommand:workbench.action.tasks.runTask"
  ],
  "main": "./out/extension.js",
  "contributes": {
    "taskDefinitions": [
      {
        "type": "MyTask",
        << -- Complete (and matching) definition ----------- >>
        "required": ["number"],
        "properties": {
                    "number": {
                        "type": "number",
                        "description": "Input number"
                    }
                }
      << --------------------------------------------------- >>
      }
    ]
  },
  "scripts": {
    "vscode:prepublish": "npm run compile",
    "compile": "tsc -p ./",
    "watch": "tsc -watch -p ./",
    "pretest": "npm run compile && npm run lint",
    "lint": "eslint src --ext ts",
    "test": "node ./out/test/runTest.js"
  },
  "devDependencies": {
    "@types/glob": "^7.1.3",
    "@types/mocha": "^8.0.4",
    "@types/node": "^12.11.7",
    "@types/vscode": "^1.46.0",
    "@typescript-eslint/eslint-plugin": "^4.14.1",
    "@typescript-eslint/parser": "^4.14.1",
    "eslint": "^7.19.0",
    "glob": "^7.1.6",
    "mocha": "^8.2.1",
    "typescript": "^4.1.3",
    "vscode-test": "^1.5.0"
  }
}
{
“名称”:“exampleext”,
“displayName”:“ExampleExt”,
“说明”:“示例扩展”,
“版本”:“0.0.1”,
“发动机”:{
“vscode”:“^1.46.0”
},
“类别”:[
“其他”
],
“激活事件”:[
“onCommand:workbench.action.tasks.runTask”
],
“main”:“/out/extension.js”,
“贡献”:{
“任务定义”:[
{
“类型”:“我的任务”,
>
“必需”:[“编号”],
“财产”:{
“编号”:{
“类型”:“编号”,
“说明”:“输入编号”
}
}
>
}
]
},
“脚本”:{
“vscode:预发布”:“npm运行编译”,
“编译”:“tsc-p./”,
“手表”:“tsc-手表-p./”,
“预测试”:“npm运行编译和npm运行lint”,
“lint”:“eslint src--ext ts”,
“test”:“node./out/test/runTest.js”
},
“依赖性”:{
“@types/glob”:“^7.1.3”,
“@types/mocha”:“^8.0.4”,
“@types/node”:“^12.11.7”,
“@types/vscode”:“^1.46.0”,
“@typescript eslint/eslint插件”:“^4.14.1”,
“@typescript eslint/parser”:“^4.14.1”,
“eslint”:“^7.19.0”,
“全球”:“^7.1.6”,
“摩卡咖啡”:“^8.2.1”,
“类型脚本”:“^4.1.3”,
vscode测试“^1.5.0”
}
}