Skip to content

Commit 74ad477

Browse files
Fixes retrieving process name on Azure Functions. Closes pnp#4229
1 parent d3a109a commit 74ad477

File tree

2 files changed

+83
-21
lines changed

2 files changed

+83
-21
lines changed

src/utils/pid.spec.ts

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('utils/pid', () => {
1818
afterEach(() => {
1919
sinonUtil.restore([
2020
os.platform,
21-
child_process.execSync,
21+
child_process.spawnSync,
2222
fs.existsSync,
2323
fs.readFileSync
2424
]);
@@ -33,18 +33,37 @@ describe('utils/pid', () => {
3333

3434
it('retrieves process name on Windows', () => {
3535
sinon.stub(os, 'platform').callsFake(() => 'win32');
36-
sinon.stub(child_process, 'execSync').callsFake(() => 'pwsh');
36+
sinon.stub(child_process, 'spawnSync').callsFake(() => {
37+
return {
38+
stdout: 'pwsh'
39+
} as any;
40+
});
3741

3842
assert.strictEqual(pid.getProcessName(123), 'pwsh');
3943
});
4044

4145
it('retrieves process name on macOS', () => {
4246
sinon.stub(os, 'platform').callsFake(() => 'darwin');
43-
sinon.stub(child_process, 'execSync').callsFake(() => '/bin/bash');
47+
sinon.stub(child_process, 'spawnSync').callsFake(() => {
48+
return {
49+
stdout: '/bin/bash'
50+
} as any;
51+
});
4452

4553
assert.strictEqual(pid.getProcessName(123), '/bin/bash');
4654
});
4755

56+
it('retrieves undefined on macOS when retrieving the process name failed', () => {
57+
sinon.stub(os, 'platform').callsFake(() => 'darwin');
58+
sinon.stub(child_process, 'spawnSync').callsFake(() => {
59+
return {
60+
error: 'An error has occurred'
61+
} as any;
62+
});
63+
64+
assert.strictEqual(pid.getProcessName(123), undefined);
65+
});
66+
4867
it('retrieves process name on Linux', () => {
4968
sinon.stub(os, 'platform').callsFake(() => 'linux');
5069
sinon.stub(fs, 'existsSync').callsFake(() => true);
@@ -66,16 +85,43 @@ describe('utils/pid', () => {
6685
assert.strictEqual(pid.getProcessName(123), undefined);
6786
});
6887

69-
it('returns undefined when retrieving process name fails', () => {
88+
it('returns undefined when retrieving process name on Windows fails', () => {
89+
sinon.stub(os, 'platform').callsFake(() => 'win32');
90+
sinon.stub(child_process, 'spawnSync').callsFake(() => {
91+
return {
92+
error: 'An error has occurred'
93+
} as any;
94+
});
95+
96+
assert.strictEqual(pid.getProcessName(123), undefined);
97+
});
98+
99+
it('returns undefined when extracting process name on Windows', () => {
70100
sinon.stub(os, 'platform').callsFake(() => 'win32');
71-
sinon.stub(child_process, 'execSync').throws();
101+
sinon.stub(child_process, 'spawnSync').callsFake(command => {
102+
if (command === 'wmic') {
103+
return {
104+
stdout: 'Caption\
105+
pwsh.exe\
106+
'
107+
};
108+
}
109+
110+
return {
111+
error: 'An error has occurred'
112+
} as any;
113+
});
72114

73115
assert.strictEqual(pid.getProcessName(123), undefined);
74116
});
75117

76118
it('stores retrieved process name in cache', () => {
77119
sinon.stub(os, 'platform').callsFake(() => 'win32');
78-
sinon.stub(child_process, 'execSync').callsFake(() => 'pwsh');
120+
sinon.stub(child_process, 'spawnSync').callsFake(() => {
121+
return {
122+
stdout: 'pwsh'
123+
} as any;
124+
});
79125

80126
pid.getProcessName(123);
81127

src/utils/pid.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import * as os from 'os';
1+
import { spawnSync } from 'child_process';
22
import * as fs from 'fs';
3-
import { execSync } from 'child_process';
3+
import * as os from 'os';
44
import { cache } from './cache';
55

66
function getProcessNameOnMacOs(pid: number): string | undefined {
7-
const stdout = execSync(`ps -o comm= ${pid}`, { encoding: 'utf8' });
8-
return stdout.trim();
7+
const res = spawnSync('ps', ['-o', 'comm=', pid.toString()], { encoding: 'utf8' });
8+
if (res.error || res.stderr) {
9+
return undefined;
10+
}
11+
else {
12+
return res.stdout.trim();
13+
}
914
}
1015

1116
function getProcessNameOnLinux(pid: number): string | undefined {
@@ -20,8 +25,24 @@ function getProcessNameOnLinux(pid: number): string | undefined {
2025
}
2126

2227
function getProcessNameOnWindows(pid: number): string | undefined {
23-
const stdout = execSync(`wmic PROCESS where ProcessId=${pid} get Caption | find /V "Caption"`, { encoding: 'utf8' });
24-
return stdout.trim();
28+
const findProcess = spawnSync('wmic', ['PROCESS', 'where', `ProcessId=${pid}`, 'get', 'Caption'], { encoding: 'utf8' });
29+
if (findProcess.error || findProcess.stderr) {
30+
return undefined;
31+
}
32+
else {
33+
const getPid = spawnSync('find', ['/V', '"Caption"'], {
34+
encoding: 'utf8',
35+
input: findProcess.stdout,
36+
// must include or passing quoted "Caption" will fail
37+
windowsVerbatimArguments: true
38+
});
39+
if (getPid.error || getPid.stderr) {
40+
return undefined;
41+
}
42+
else {
43+
return getPid.stdout.trim();
44+
}
45+
}
2546
}
2647

2748
export const pid = {
@@ -45,16 +66,11 @@ export const pid = {
4566
}
4667

4768
if (getPidName) {
48-
try {
49-
processName = getPidName(pid);
50-
if (processName) {
51-
cache.setValue(pid.toString(), processName);
52-
}
53-
return processName;
54-
}
55-
catch {
56-
return undefined;
69+
processName = getPidName(pid);
70+
if (processName) {
71+
cache.setValue(pid.toString(), processName);
5772
}
73+
return processName;
5874
}
5975

6076
return undefined;

0 commit comments

Comments
 (0)