let result = await vscode.commands.executeCommand('workbench.action.tasks.build');
resolves immediately.
How can I await a build task with VS Code API?
let result = await vscode.commands.executeCommand('workbench.action.tasks.build');
resolves immediately.
How can I await a build task with VS Code API?
I figured it out! Tasks cannot be awaited from vscode.tasks.executeTask
, but we can await vscode.tasks.onDidEndTask
and check if ended task is our task.
async function executeBuildTask(task: vscode.Task) {
const execution = await vscode.tasks.executeTask(task);
return new Promise<void>(resolve => {
let disposable = vscode.tasks.onDidEndTask(e => {
if (e.execution.task.group === vscode.TaskGroup.Build) {
disposable.dispose();
resolve();
}
});
});
}
async function getBuildTasks() {
return new Promise<vscode.Task[]>(resolve => {
vscode.tasks.fetchTasks().then((tasks) => {
resolve(tasks.filter((task) => task.group === vscode.TaskGroup.Build));
});
});
}
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand('extension.helloWorld', async () => {
const buildTasks = await getBuildTasks();
await executeBuildTask(buildTasks[0]);
}));
}
Note that currently there is a bug #96643, which prevents us from doing a comparison of vscode.Task objects: if (e.execution.task === execution.task) { ... }
I think this depends on how the main command is executed in the extension.ts
Being new to JS/TS, I may be wrong here, but just trying to help:
make sure the vscode.command.registerCommand is not asyncronous, like below:
context.subscriptions.push(vscode.commands.registerCommand('extension.openSettings', () => {
return vscode.commands.executeCommand("workbench.action.openSettings", "settingsName");
}));
This would be compared to something async, like below:
context.subscriptions.push(vscode.commands.registerCommand('extension.removeHost', async (hostID) => {
const bigipHosts: Array<string> | undefined = vscode.workspace.getConfiguration().get('extension.hosts');
const newHosts = Hosts?.filter( item => item != hostID.label)
await vscode.workspace.getConfiguration().update('f5-fast.hosts', newBigipHosts, vscode.ConfigurationTarget.Global);
hostsTreeProvider.refresh();
}));
vscode.tasks.onDidEndTaskProcess
to also get the exit status
If you only want to run the next task if the previous worked out, you can also check the exit status with onDidEndTaskProcess
as in:
export async function activate(context: vscode.ExtensionContext) {
async function runTask(): Promise<number|undefined> {
// Define your command in a task.
const quotingStyle: vscode.ShellQuoting = vscode.ShellQuoting.Strong
let myTaskCommand: vscode.ShellQuotedString = {
value: '/usr/bin/ls,
quoting: quotingStyle,
}
const args = ['.']
let myTaskArgs: vscode.ShellQuotedString[] = args.map((arg) => {
return { value: arg, quoting: quotingStyle }
})
let myTaskOptions: vscode.ShellExecutionOptions = {
cwd: '/usr/lib',
}
let shellExec: vscode.ShellExecution = new vscode.ShellExecution(
myTaskCommand,
myTaskArgs,
myTaskOptions
)
const taskName = 'build'
let myTask: vscode.Task = new vscode.Task(
{ type: "shell", group: "build", label: taskName },
vscode.TaskScope.Workspace,
taskName,
"makefile",
shellExec
)
myTask.presentationOptions.clear = true
myTask.presentationOptions.showReuseMessage = true
// Run the command.
const execution = await vscode.tasks.executeTask(myTask)
return new Promise(resolve => {
const disposable = vscode.tasks.onDidEndTaskProcess(e => {
if (e.execution === execution) {
disposable.dispose()
resolve(e.exitCode)
}
})
})
}
context.subscriptions.push(
vscode.commands.registerCommand('myextid.helloWorld', async function () {
const exitCode = await runTask()
if (exitCode === 0) {
// Do something else.
}
})
)
}
Related: How to detect failure of task execution from a vscode extension?
Tested on vscode 1.91.1, Ubuntu 24.04.
© 2022 - 2025 — McMap. All rights reserved.
if (e.execution === execution)
should work now. – Hussein