forked from microsoft/vscode-python-debugger
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprovider.ts
More file actions
133 lines (117 loc) · 5.8 KB
/
provider.ts
File metadata and controls
133 lines (117 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
import { l10n } from 'vscode';
import { getOSType, OSType } from '../../common/platform';
import { PsProcessParser } from './psProcessParser';
import { IAttachItem, IAttachProcessProvider, ProcessListCommand } from './types';
import { PowerShellProcessParser } from './powerShellProcessParser';
import { getEnvironmentVariables } from '../../common/python';
import { plainExec } from '../../common/process/rawProcessApis';
import { logProcess } from '../../common/process/logger';
import { WmicProcessParser } from './wmicProcessParser';
import { promisify } from 'util';
import * as wpc from '@vscode/windows-process-tree';
import { ProcessDataFlag } from '@vscode/windows-process-tree';
export class AttachProcessProvider implements IAttachProcessProvider {
constructor() {}
public getAttachItems(specCommand?: ProcessListCommand): Promise<IAttachItem[]> {
return this._getInternalProcessEntries(specCommand).then((processEntries) => {
processEntries.sort(
(
{ processName: aprocessName, commandLine: aCommandLine },
{ processName: bProcessName, commandLine: bCommandLine },
) => {
const compare = (aString: string, bString: string): number => {
// localeCompare is significantly slower than < and > (2000 ms vs 80 ms for 10,000 elements)
// We can change to localeCompare if this becomes an issue
const aLower = aString.toLowerCase();
const bLower = bString.toLowerCase();
if (aLower === bLower) {
return 0;
}
return aLower < bLower ? -1 : 1;
};
const aPython = aprocessName.startsWith('python');
const bPython = bProcessName.startsWith('python');
if (aPython || bPython) {
if (aPython && !bPython) {
return -1;
}
if (bPython && !aPython) {
return 1;
}
return aPython ? compare(aCommandLine!, bCommandLine!) : compare(bCommandLine!, aCommandLine!);
}
return compare(aprocessName, bProcessName);
},
);
return processEntries;
});
}
/**
* Get processes via wmic (fallback)
*/
private async _getProcessesViaWmic(): Promise<IAttachItem[]> {
const customEnvVars = await getEnvironmentVariables();
const output = await plainExec(
WmicProcessParser.wmicCommand.command,
WmicProcessParser.wmicCommand.args,
{ throwOnStdErr: true },
customEnvVars,
);
logProcess(WmicProcessParser.wmicCommand.command, WmicProcessParser.wmicCommand.args, { throwOnStdErr: true });
return WmicProcessParser.parseProcesses(output.stdout);
}
/**
* Get processes via Ps parser (Linux/macOS)
*/
private async _getProcessesViaPsParser(cmd: ProcessListCommand): Promise<IAttachItem[]> {
const customEnvVars = await getEnvironmentVariables();
const output = await plainExec(cmd.command, cmd.args, { throwOnStdErr: true }, customEnvVars);
logProcess(cmd.command, cmd.args, { throwOnStdErr: true });
return PsProcessParser.parseProcesses(output.stdout);
}
public async _getInternalProcessEntries(specCommand?: ProcessListCommand): Promise<IAttachItem[]> {
if (specCommand === undefined) {
const osType = getOSType();
if (osType === OSType.OSX) {
return this._getProcessesViaPsParser(PsProcessParser.psDarwinCommand);
} else if (osType === OSType.Linux) {
return this._getProcessesViaPsParser(PsProcessParser.psLinuxCommand);
} else if (osType === OSType.Windows) {
try {
const getAllProcesses = promisify(wpc.getAllProcesses) as (flags?: ProcessDataFlag) => Promise<wpc.IProcessInfo[]>;
const processList = await getAllProcesses(ProcessDataFlag.CommandLine);
return processList.map((p) => ({
label: p.name,
description: String(p.pid),
detail: p.commandLine || '',
id: String(p.pid),
processName: p.name,
commandLine: p.commandLine || '',
}));
} catch (error) {
console.error('Failed to get processes via windows-process-tree:', error);
// 降级到 wmic
return this._getProcessesViaWmic();
}
} else {
throw new Error(l10n.t("Operating system '{0}' not supported.", osType));
}
}
const processCmd = specCommand;
const customEnvVars = await getEnvironmentVariables();
const output = await plainExec(processCmd.command, processCmd.args, { throwOnStdErr: true }, customEnvVars);
logProcess(processCmd.command, processCmd.args, { throwOnStdErr: true });
if (processCmd === WmicProcessParser.wmicCommand) {
return WmicProcessParser.parseProcesses(output.stdout);
} else if (
processCmd === PowerShellProcessParser.powerShellCommand ||
processCmd === PowerShellProcessParser.powerShellWithoutCimCommand
) {
return PowerShellProcessParser.parseProcesses(output.stdout);
}
return PsProcessParser.parseProcesses(output.stdout);
}
}