Skip to content

Commit 45134fb

Browse files
committed
cluster: support windowsHide option for workers
Fixes: #17370
1 parent e9e9863 commit 45134fb

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

doc/api/cluster.md

+2
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,8 @@ changes:
722722
This can be a number, or a function that takes no arguments and returns a
723723
number. By default each worker gets its own port, incremented from the
724724
master's `process.debugPort`.
725+
* `windowsHide` {boolean} Hide the forked processes console window that would
726+
normally be created on Windows systems. **Default:** `false`
725727

726728
After calling `.setupMaster()` (or `.fork()`) this settings object will contain
727729
the settings, including the default values.

lib/internal/cluster/master.js

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ function createWorkerProcess(id, env) {
127127
return fork(cluster.settings.exec, cluster.settings.args, {
128128
env: workerEnv,
129129
silent: cluster.settings.silent,
130+
windowsHide: cluster.settings.windowsHide,
130131
execArgv: execArgv,
131132
stdio: cluster.settings.stdio,
132133
gid: cluster.settings.gid,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const child_process = require('child_process');
5+
6+
let patchedFork = child_process.fork;
7+
child_process.fork = (...args) => patchedFork.apply(this, args);
8+
const cluster = require('cluster');
9+
10+
if (!process.argv[2]) {
11+
const master = child_process.spawn(
12+
process.argv[0],
13+
[process.argv[1], '--cluster'],
14+
{ detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] });
15+
16+
const messageHandlers = {
17+
windowsHide: common.mustCall((msg) => {
18+
assert.strictEqual(msg.value, true);
19+
}),
20+
workerOnline: common.mustCall((msg) => {
21+
}),
22+
mainWindowHandle: common.mustCall((msg) => {
23+
assert.ok(/0\s*/.test(msg.value));
24+
}),
25+
workerExit: common.mustCall((msg) => {
26+
assert.strictEqual(msg.code, 0);
27+
assert.strictEqual(msg.signal, null);
28+
})
29+
};
30+
31+
master.on('message', (msg) => {
32+
const handler = messageHandlers[msg.type];
33+
assert.ok(handler);
34+
handler(msg);
35+
});
36+
37+
master.on('exit', common.mustCall((code, signal) => {
38+
assert.strictEqual(code, 0);
39+
assert.strictEqual(signal, null);
40+
}));
41+
42+
} else if (cluster.isMaster) {
43+
const originalFork = patchedFork;
44+
patchedFork = common.mustCall((...args) => {
45+
process.send({ type: 'windowsHide', value: args[2].windowsHide });
46+
return originalFork.apply(this, args);
47+
});
48+
49+
cluster.setupMaster({
50+
silient: true,
51+
windowsHide: true
52+
});
53+
54+
const worker = cluster.fork();
55+
worker.on('exit', (code, signal) => {
56+
process.send({ type: 'workerExit', code: code, signal: signal });
57+
});
58+
59+
worker.on('online', (msg) => {
60+
process.send({ type: 'workerOnline' });
61+
62+
let output = '0';
63+
if (process.platform === 'win32')
64+
output = child_process.execSync(
65+
'powershell -NoProfile -c ' +
66+
`"(Get-Process -Id ${worker.process.pid}).MainWindowHandle"`,
67+
{ windowsHide: true, encoding: 'utf8' });
68+
69+
process.send({ type: 'mainWindowHandle', value: output });
70+
worker.send('shutdown');
71+
});
72+
73+
} else {
74+
cluster.worker.on('message', (msg) => {
75+
cluster.worker.disconnect();
76+
});
77+
}

0 commit comments

Comments
 (0)