Skip to content

Commit 17a059e

Browse files
authored
fix(vscode): Migrated from ps-tree to using powershell to find child prcess (#8368)
Migrated from ps-tree to using powershell to find child prcess
1 parent 9a897c8 commit 17a059e

4 files changed

Lines changed: 97 additions & 14 deletions

File tree

apps/vs-code-designer/src/app/utils/codeless/startDesignTimeApi.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ import * as portfinder from 'portfinder';
4646
import * as vscode from 'vscode';
4747
import { Uri, window, workspace, type MessageItem } from 'vscode';
4848
import { findChildProcess } from '../../commands/pickFuncProcess';
49-
import pstree from 'ps-tree';
5049
import find_process from 'find-process';
50+
import { getChildProcessesWithScript } from '../findChildProcess/findChildProcess';
5151

5252
export async function startDesignTimeApi(projectPath: string): Promise<void> {
5353
await callWithTelemetryAndErrorHandling('azureLogicAppsStandard.startDesignTimeApi', async (actionContext: IActionContext) => {
@@ -194,12 +194,8 @@ async function checkFuncProcessId(projectPath: string): Promise<boolean> {
194194
}
195195

196196
if (os.platform() === Platform.windows) {
197-
await new Promise<void>((resolve) => {
198-
pstree(process.pid, (_err: Error | null, children: Array<{ PID: string; COMMAND?: string; COMM?: string }>) => {
199-
correctId = children.some((p) => p.PID === childFuncPid && (p.COMMAND || p.COMM) === 'func.exe');
200-
resolve();
201-
});
202-
});
197+
const children = await getChildProcessesWithScript(process.pid);
198+
correctId = children.some((p) => p.processId.toString() === childFuncPid && p.name === 'func.exe');
203199
} else {
204200
await find_process('pid', process.pid).then((list) => {
205201
if (list.length > 0) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import * as cp from 'child_process';
2+
import * as path from 'path';
3+
import { ext } from '../../../extensionVariables';
4+
5+
interface ProcessInfo {
6+
processId: number;
7+
name: string;
8+
parentProcessId: number;
9+
}
10+
11+
async function runPowerShellScript(scriptPath: string, ...args: string[]): Promise<string> {
12+
return new Promise((resolve, reject) => {
13+
// Escape arguments for PowerShell
14+
const escapedArgs = args.map((arg) => `"${arg.replace(/"/g, '`"')}"`).join(' ');
15+
const command = `powershell.exe -NoProfile -NoLogo -ExecutionPolicy Bypass -File "${scriptPath}" ${escapedArgs}`;
16+
17+
ext.outputChannel.appendLog(`Executing PowerShell script: ${command}`);
18+
19+
const child = cp.exec(
20+
command,
21+
{
22+
timeout: 10000,
23+
encoding: 'utf8',
24+
maxBuffer: 1024 * 1024, // 1MB buffer
25+
},
26+
(error, stdout, stderr) => {
27+
if (error) {
28+
ext.outputChannel.appendLog(`PowerShell script error: ${error.message}`);
29+
if (stderr) {
30+
ext.outputChannel.appendLog(`PowerShell stderr: ${stderr}`);
31+
}
32+
reject(error);
33+
return;
34+
}
35+
36+
resolve(stdout.trim());
37+
}
38+
);
39+
40+
// Backup timeout
41+
setTimeout(() => {
42+
if (!child.killed) {
43+
child.kill('SIGKILL');
44+
reject(new Error('PowerShell script execution timed out'));
45+
}
46+
}, 12000);
47+
});
48+
}
49+
50+
export async function getChildProcessesWithScript(parentProcessId: number): Promise<ProcessInfo[]> {
51+
try {
52+
const scriptPath = path.join(__dirname, 'assets', 'scripts', 'get-child-processes.ps1');
53+
const output = await runPowerShellScript(scriptPath, parentProcessId.toString());
54+
55+
if (!output || output === '[]') {
56+
return [];
57+
}
58+
59+
const rawData = JSON.parse(output);
60+
const dataArray = Array.isArray(rawData) ? rawData : [rawData];
61+
62+
return dataArray.map((item: any) => ({
63+
processId: item.ProcessId,
64+
name: item.Name,
65+
parentProcessId: item.ParentProcessId,
66+
}));
67+
} catch (error) {
68+
throw new Error(`Failed to execute Powershell script to get the func child process: ${error.message}`);
69+
}
70+
}

apps/vs-code-designer/src/app/utils/startRuntimeApi.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ import * as vscode from 'vscode';
1414
import * as portfinder from 'portfinder';
1515
import * as os from 'os';
1616
import * as cp from 'child_process';
17-
import pstree from 'ps-tree';
1817
import find_process from 'find-process';
1918
import axios from 'axios';
2019
import { localize } from '../../localize';
2120
import { delay } from './delay';
2221
import { findChildProcess } from '../commands/pickFuncProcess';
2322
import { getFunctionsCommand } from './funcCoreTools/funcVersion';
23+
import { getChildProcessesWithScript } from './findChildProcess/findChildProcess';
2424

2525
export async function startRuntimeApi(projectPath: string): Promise<void> {
2626
await callWithTelemetryAndErrorHandling('azureLogicAppsStandard.startRuntimeProcess', async (context: IActionContext) => {
@@ -154,12 +154,8 @@ async function checkFuncProcessId(projectPath: string): Promise<boolean> {
154154
}
155155

156156
if (os.platform() === Platform.windows) {
157-
await new Promise<void>((resolve) => {
158-
pstree(process.pid, (_err: Error | null, children: Array<{ PID: string; COMMAND?: string; COMM?: string }>) => {
159-
correctId = children.some((p) => p.PID === childFuncPid && (p.COMMAND || p.COMM) === 'func.exe');
160-
resolve();
161-
});
162-
});
157+
const children = await getChildProcessesWithScript(process.pid);
158+
correctId = children.some((p) => p.processId.toString() === childFuncPid && p.name === 'func.exe');
163159
} else {
164160
await find_process('pid', process.pid).then((list) => {
165161
if (list.length > 0) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
$parentProcessId = $args[0]
2+
3+
try {
4+
function Get-ChildProcesses ($ParentProcessId) {
5+
$filter = "parentprocessid = '$($ParentProcessId)'"
6+
Get-CIMInstance -ClassName win32_process -filter $filter | Foreach-Object {
7+
$_
8+
if ($_.ParentProcessId -ne $_.ProcessId) {
9+
Get-ChildProcesses $_.ProcessId
10+
}
11+
}
12+
}
13+
$processes = Get-ChildProcesses $parentProcessId | Select ProcessId, Name, ParentProcessId
14+
if ($processes) {
15+
$processes | ConvertTo-Json -Depth 2
16+
} else {
17+
'[]'
18+
}
19+
} catch {
20+
'[]'
21+
}

0 commit comments

Comments
 (0)