-
Notifications
You must be signed in to change notification settings - Fork 96
Expand file tree
/
Copy pathprovider.ts
More file actions
104 lines (89 loc) · 4.3 KB
/
provider.ts
File metadata and controls
104 lines (89 loc) · 4.3 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
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
import { l10n } from 'vscode';
import * as wpc from '@vscode/windows-process-tree';
import { getOSType, OSType } from '../../common/platform';
import { PsProcessParser } from './psProcessParser';
import { IAttachItem, IAttachProcessProvider, ProcessListCommand } from './types';
import { WmicProcessParser } from './wmicProcessParser';
import { getEnvironmentVariables } from '../../common/python';
import { plainExec } from '../../common/process/rawProcessApis';
import { logProcess } from '../../common/process/logger';
export class AttachProcessProvider implements IAttachProcessProvider {
constructor() {}
public getAttachItems(): Promise<IAttachItem[]> {
return this._getInternalProcessEntries().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;
});
}
public async _getInternalProcessEntries(): Promise<IAttachItem[]> {
const osType = getOSType();
if (osType === OSType.Windows) {
try {
const processList = await new Promise<wpc.IProcessInfo[]>((resolve) => {
wpc.getAllProcesses((processes) => resolve(processes), wpc.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 {
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);
}
}
let processCmd: ProcessListCommand;
if (osType === OSType.OSX) {
processCmd = PsProcessParser.psDarwinCommand;
} else if (osType === OSType.Linux) {
processCmd = PsProcessParser.psLinuxCommand;
} else {
throw new Error(l10n.t("Operating system '{0}' not supported.", osType));
}
const customEnvVars = await getEnvironmentVariables();
const output = await plainExec(processCmd.command, processCmd.args, { throwOnStdErr: true }, customEnvVars);
logProcess(processCmd.command, processCmd.args, { throwOnStdErr: true });
return PsProcessParser.parseProcesses(output.stdout);
}
}