mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
child_process: add windowsHide option
This commit exposes the UV_PROCESS_WINDOWS_HIDE flag in Node as a windowsHide option to the child_process methods. The option is only applicable to Windows, and is ignored elsewhere. Fixes: https://github.com/nodejs/node/issues/15217 PR-URL: https://github.com/nodejs/node/pull/15380 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
8 files changed
+122
No files matched your search
@@ -127,6 +127,10 @@ exec('"my script.cmd" a b', (err, stdout, stderr) => {
|
||||
### child_process.exec(command[, options][, callback])
|
||||
<!-- YAML
|
||||
added: v0.1.90
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/15380
|
||||
description: The `windowsHide` option is supported now.
|
||||
-->
|
||||
|
||||
* `command` {string} The command to run, with space-separated arguments.
|
||||
@@ -145,6 +149,8 @@ added: v0.1.90
|
||||
* `killSignal` {string|integer} **Default:** `'SIGTERM'`
|
||||
* `uid` {number} Sets the user identity of the process (see setuid(2)).
|
||||
* `gid` {number} Sets the group identity of the process (see setgid(2)).
|
||||
* `windowsHide` {boolean} Hide the subprocess console window that would
|
||||
normally be created on Windows systems. **Default:** `false`.
|
||||
* `callback` {Function} called with the output when process terminates.
|
||||
* `error` {Error}
|
||||
* `stdout` {string|Buffer}
|
||||
@@ -238,6 +244,10 @@ lsExample();
|
||||
### child_process.execFile(file[, args][, options][, callback])
|
||||
<!-- YAML
|
||||
added: v0.1.91
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/15380
|
||||
description: The `windowsHide` option is supported now.
|
||||
-->
|
||||
|
||||
* `file` {string} The name or path of the executable file to run.
|
||||
@@ -253,6 +263,8 @@ added: v0.1.91
|
||||
* `killSignal` {string|integer} **Default:** `'SIGTERM'`
|
||||
* `uid` {number} Sets the user identity of the process (see setuid(2)).
|
||||
* `gid` {number} Sets the group identity of the process (see setgid(2)).
|
||||
* `windowsHide` {boolean} Hide the subprocess console window that would
|
||||
normally be created on Windows systems. **Default:** `false`.
|
||||
* `callback` {Function} Called with the output when process terminates.
|
||||
* `error` {Error}
|
||||
* `stdout` {string|Buffer}
|
||||
@@ -364,6 +376,9 @@ supported by `child_process.fork()` and will be ignored if set.
|
||||
<!-- YAML
|
||||
added: v0.1.90
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/15380
|
||||
description: The `windowsHide` option is supported now.
|
||||
- version: v6.4.0
|
||||
pr-url: https://github.com/nodejs/node/pull/7696
|
||||
description: The `argv0` option is supported now.
|
||||
@@ -390,6 +405,8 @@ changes:
|
||||
`'/bin/sh'` on UNIX, and `process.env.ComSpec` on Windows. A different
|
||||
shell can be specified as a string. See [Shell Requirements][] and
|
||||
[Default Windows Shell][]. **Default:** `false` (no shell).
|
||||
* `windowsHide` {boolean} Hide the subprocess console window that would
|
||||
normally be created on Windows systems. **Default:** `false`.
|
||||
* Returns: {ChildProcess}
|
||||
|
||||
The `child_process.spawn()` method spawns a new process using the given
|
||||
@@ -649,6 +666,9 @@ configuration at startup.
|
||||
<!-- YAML
|
||||
added: v0.11.12
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/15380
|
||||
description: The `windowsHide` option is supported now.
|
||||
- version: v8.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/10653
|
||||
description: The `input` option can now be a `Uint8Array`.
|
||||
@@ -678,6 +698,8 @@ changes:
|
||||
stderr. **Default:** `200*1024` If exceeded, the child process is terminated.
|
||||
See caveat at [`maxBuffer` and Unicode][].
|
||||
* `encoding` {string} The encoding used for all stdio inputs and outputs. **Default:** `'buffer'`
|
||||
* `windowsHide` {boolean} Hide the subprocess console window that would
|
||||
normally be created on Windows systems. **Default:** `false`.
|
||||
* Returns: {Buffer|string} The stdout from the command.
|
||||
|
||||
The `child_process.execFileSync()` method is generally identical to
|
||||
@@ -698,6 +720,9 @@ throw an [`Error`][] that will include the full result of the underlying
|
||||
<!-- YAML
|
||||
added: v0.11.12
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/15380
|
||||
description: The `windowsHide` option is supported now.
|
||||
- version: v8.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/10653
|
||||
description: The `input` option can now be a `Uint8Array`.
|
||||
@@ -727,6 +752,8 @@ changes:
|
||||
See caveat at [`maxBuffer` and Unicode][].
|
||||
* `encoding` {string} The encoding used for all stdio inputs and outputs.
|
||||
**Default:** `'buffer'`
|
||||
* `windowsHide` {boolean} Hide the subprocess console window that would
|
||||
normally be created on Windows systems. **Default:** `false`.
|
||||
* Returns: {Buffer|string} The stdout from the command.
|
||||
|
||||
The `child_process.execSync()` method is generally identical to
|
||||
@@ -749,6 +776,9 @@ execution.
|
||||
<!-- YAML
|
||||
added: v0.11.12
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/15380
|
||||
description: The `windowsHide` option is supported now.
|
||||
- version: v8.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/10653
|
||||
description: The `input` option can now be a `Uint8Array`.
|
||||
@@ -784,6 +814,8 @@ changes:
|
||||
`'/bin/sh'` on UNIX, and `process.env.ComSpec` on Windows. A different
|
||||
shell can be specified as a string. See [Shell Requirements][] and
|
||||
[Default Windows Shell][]. **Default:** `false` (no shell).
|
||||
* `windowsHide` {boolean} Hide the subprocess console window that would
|
||||
normally be created on Windows systems. **Default:** `false`.
|
||||
* Returns: {Object}
|
||||
* `pid` {number} Pid of the child process.
|
||||
* `output` {Array} Array of results from stdio output.
|
||||
|
||||
@@ -210,6 +210,7 @@ exports.execFile = function(file /*, args, options, callback*/) {
|
||||
gid: options.gid,
|
||||
uid: options.uid,
|
||||
shell: options.shell,
|
||||
windowsHide: !!options.windowsHide,
|
||||
windowsVerbatimArguments: !!options.windowsVerbatimArguments
|
||||
});
|
||||
|
||||
@@ -428,6 +429,12 @@ function normalizeSpawnArguments(file, args, options) {
|
||||
throw new TypeError('"argv0" must be a string');
|
||||
}
|
||||
|
||||
// Validate windowsHide, if present.
|
||||
if (options.windowsHide != null &&
|
||||
typeof options.windowsHide !== 'boolean') {
|
||||
throw new TypeError('"windowsHide" must be a boolean');
|
||||
}
|
||||
|
||||
// Validate windowsVerbatimArguments, if present.
|
||||
if (options.windowsVerbatimArguments != null &&
|
||||
typeof options.windowsVerbatimArguments !== 'boolean') {
|
||||
@@ -493,6 +500,7 @@ var spawn = exports.spawn = function(/*file, args, options*/) {
|
||||
file: opts.file,
|
||||
args: opts.args,
|
||||
cwd: options.cwd,
|
||||
windowsHide: !!options.windowsHide,
|
||||
windowsVerbatimArguments: !!options.windowsVerbatimArguments,
|
||||
detached: !!options.detached,
|
||||
envPairs: opts.envPairs,
|
||||
|
||||
@@ -286,6 +286,7 @@ class ModuleWrap;
|
||||
V(verify_error_string, "verifyError") \
|
||||
V(version_string, "version") \
|
||||
V(weight_string, "weight") \
|
||||
V(windows_hide_string, "windowsHide") \
|
||||
V(windows_verbatim_arguments_string, "windowsVerbatimArguments") \
|
||||
V(wrap_string, "wrap") \
|
||||
V(writable_string, "writable") \
|
||||
|
||||
@@ -211,6 +211,13 @@ class ProcessWrap : public HandleWrap {
|
||||
// options.stdio
|
||||
ParseStdioOptions(env, js_options, &options);
|
||||
|
||||
// options.windowsHide
|
||||
Local<String> windows_hide_key = env->windows_hide_string();
|
||||
|
||||
if (js_options->Get(windows_hide_key)->IsTrue()) {
|
||||
options.flags |= UV_PROCESS_WINDOWS_HIDE;
|
||||
}
|
||||
|
||||
// options.windows_verbatim_arguments
|
||||
Local<String> windows_verbatim_arguments_key =
|
||||
env->windows_verbatim_arguments_string();
|
||||
|
||||
@@ -777,6 +777,11 @@ int SyncProcessRunner::ParseOptions(Local<Value> js_value) {
|
||||
if (js_options->Get(env()->detached_string())->BooleanValue())
|
||||
uv_process_options_.flags |= UV_PROCESS_DETACHED;
|
||||
|
||||
Local<String> win_hide = env()->windows_hide_string();
|
||||
|
||||
if (js_options->Get(win_hide)->BooleanValue())
|
||||
uv_process_options_.flags |= UV_PROCESS_WINDOWS_HIDE;
|
||||
|
||||
Local<String> wba = env()->windows_verbatim_arguments_string();
|
||||
|
||||
if (js_options->Get(wba)->BooleanValue())
|
||||
|
||||
@@ -66,6 +66,7 @@ assert.strictEqual(env.stdout.toString().trim(), 'buzz');
|
||||
assert.strictEqual(opts.options.shell, shell);
|
||||
assert.strictEqual(opts.options.file, opts.file);
|
||||
assert.deepStrictEqual(opts.options.args, opts.args);
|
||||
assert.strictEqual(opts.options.windowsHide, undefined);
|
||||
assert.strictEqual(opts.options.windowsVerbatimArguments,
|
||||
windowsVerbatim);
|
||||
});
|
||||
|
||||
@@ -124,6 +124,22 @@ if (!common.isWindows) {
|
||||
fail('argv0', common.mustNotCall(), err);
|
||||
}
|
||||
|
||||
{
|
||||
// Validate the windowsHide option
|
||||
const err = /^TypeError: "windowsHide" must be a boolean$/;
|
||||
|
||||
pass('windowsHide', undefined);
|
||||
pass('windowsHide', null);
|
||||
pass('windowsHide', true);
|
||||
pass('windowsHide', false);
|
||||
fail('windowsHide', 0, err);
|
||||
fail('windowsHide', 1, err);
|
||||
fail('windowsHide', __dirname, err);
|
||||
fail('windowsHide', [], err);
|
||||
fail('windowsHide', {}, err);
|
||||
fail('windowsHide', common.mustNotCall(), err);
|
||||
}
|
||||
|
||||
{
|
||||
// Validate the windowsVerbatimArguments option
|
||||
const err = /^TypeError: "windowsVerbatimArguments" must be a boolean$/;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Flags: --expose_internals
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const cp = require('child_process');
|
||||
const internalCp = require('internal/child_process');
|
||||
const cmd = process.execPath;
|
||||
const args = ['-p', '42'];
|
||||
const options = { windowsHide: true };
|
||||
|
||||
// Since windowsHide isn't really observable, monkey patch spawn() and
|
||||
// spawnSync() to verify that the flag is being passed through correctly.
|
||||
const originalSpawn = internalCp.ChildProcess.prototype.spawn;
|
||||
const originalSpawnSync = internalCp.spawnSync;
|
||||
|
||||
internalCp.ChildProcess.prototype.spawn = common.mustCall(function(options) {
|
||||
assert.strictEqual(options.windowsHide, true);
|
||||
return originalSpawn.apply(this, arguments);
|
||||
}, 2);
|
||||
|
||||
internalCp.spawnSync = common.mustCall(function(options) {
|
||||
assert.strictEqual(options.options.windowsHide, true);
|
||||
return originalSpawnSync.apply(this, arguments);
|
||||
});
|
||||
|
||||
{
|
||||
const child = cp.spawnSync(cmd, args, options);
|
||||
|
||||
assert.strictEqual(child.status, 0);
|
||||
assert.strictEqual(child.signal, null);
|
||||
assert.strictEqual(child.stdout.toString().trim(), '42');
|
||||
assert.strictEqual(child.stderr.toString().trim(), '');
|
||||
}
|
||||
|
||||
{
|
||||
const child = cp.spawn(cmd, args, options);
|
||||
|
||||
child.on('exit', common.mustCall((code, signal) => {
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
const callback = common.mustCall((err, stdout, stderr) => {
|
||||
assert.ifError(err);
|
||||
assert.strictEqual(stdout.trim(), '42');
|
||||
assert.strictEqual(stderr.trim(), '');
|
||||
});
|
||||
|
||||
cp.execFile(cmd, args, options, callback);
|
||||
}
|
||||
Reference in new issue
Block a user