NodeJS,Windows,wmic stdin

我在NodeJS中遇到了Windows程序WMIC.exe(用于查询Windows Management Instrumentation)的问题。

我可以产生一个wmic.exe进程,但它不会输出任何东西或接受任何input。 但是,如果我将stdin设置为null,它将正确运行,我会收到输出。

var spawn = require('child_process').spawn; var wmic = spawn('wmic', [], {stdio: ['ignore']}); wmic.stdout.on('data', function(data) { console.log('Data received:' + data); }); wmic.on('close', function(code) { console.log('Spawned process ended with code: ' + code); }); 

我想交互使用wmic.exe,它支持,保持打开,所以我不必为每个WMI查询重复启动它。 其他人也有与wmic.exe类似的问题,但他们只想捕获一个单一的查询输出,所以有一个null stdin无关紧要。

更新

如果我做以下…

 var spawn = require('child_process').spawn; var wmic = spawn('wmic', []); wmic.stdout.on('data', function(data) { console.log('Data received:' + data); }); wmic.stderr.on('data', function(data) { console.log('Error! - ' + data); }); wmic.on('close', function(code) { console.log('Spawned process ended with code: ' + code); }); wmic.stdin.end('cpu get caption /format:csv\n'); 

然后它实际上会响应一个结果,提示为下一个查询做好准备,但接下来结束这个过程,显然我不能在.end()之后使用.write()。 将它更改为.write(),进程完全不响应,我甚至没有从使用.end()时收到的stdout“wmic:root \ cli>”提示。

要么

 wmic.stdin.push(null); wmic.stdin.write('cpu/n'); // Ctrl-Z aka Windows EOF control code 

如果我使用上面的,而不是.end()调用,它也会工作。 但是,如果我不继续往这个地方扔不断的数据,这个过程就结束了。

甚至

 wmic.stdin.write('cpu'); wmic.stdin.write('\x1a'); 

这也可以,但是再一次,wmic.exe进程决定退出cpu结果后退出。 :/

几乎

 var wmic = spawn('wmic.exe', [], {stdio: [process.stdin, 'pipe', 'pipe']}); 

这工作。 该进程启动正确,所以我通过wmic.stdout.on('data',fn)从wmic.exe收到提示,并保持打开状态。 但是,我无法通过代码发送input,但可以直接在命令提示符窗口中input。 我input的任何内容都可以正确执行并通过节点脚本输出。 再一次,奇怪的是,它与这个pipe道工作,但我没有设置和无用的,因为我想通过代码发送命令,而不是键入它们。

Solutions Collecting From Web of "NodeJS,Windows,wmic stdin"

您希望交互式使用wmic ,但是由应用程序的输入驱动,而不是在控制台输入的输入。

实现这个任何应用程序的正常方法是从管道输入它的输入。 方便的是,如果你没有指定任何其他的stdio选项,NodeJS会默认创建一个管道。

问题是,当从管道接收输入时, wmic行为非常糟糕。 在输入完成之前,它拒绝做任何事情; 然后处理所有的输入,并停止寻找更多。 wmic认为管道关闭或接收到CTRL-Z时输入完成。

因此,你不能发出一个命令,读取输出,然后发出另一个命令。 wmic不会写输出,直到它认为它已经收到所有的命令,然后它将不再接受。

你可以在控制台上说明这个问题。 type con: | wmic type con: | wmic把键盘输入通过管道,所以wmic进入其破碎的模式。 在下面的例子中,后面跟着几个命令。 请注意,直到进入CTRL-Zwmic才会执行任何操作。

 C:\>type con: | wmic cpu get name useraccount list brief ^Z wmic:root\cli>cpu get name Name Pentium(R) Dual-Core CPU T4500 @ 2.30GHz wmic:root\cli> "/?" for help, QUIT to Exit. wmic:root\cli>useraccount list brief AccountType Caption Domain FullName Name 512 frog\Administrator frog Administrator wmic:root\cli> "/?" for help, QUIT to Exit. wmic:root\cli> C:\> 

你可能会想(看这个例子) wmic只是有一个很大的输出缓冲区。 但是,如果启用跟踪( /TRACE:ON作为第一个命令),则wmic会生成输出大小,但在输入完成前没有任何操作。

一个解决方案是不重定向标准输入,就像你最后的例子,所以输入来自键盘。 (注意,当Windows控制台应用程序接收到来自键盘的输入时,它不会通过管道进入,因此最后一个示例不使用管道,这就是为什么行为不同的原因。

然后,您可以通过模拟击键向wmic提供输入。 这个问题的答案提出了一些方法:使用SendKeys或通过发送WM_KEYUP消息。 这不是一个好的解决方案。

为了后世…

这现在可以通过使用ms-wmic包:

这完全绕过了不得不直接与CLI进行交互,并允许您通过预设的API处理WMIC


但是在上面的示例中,您尝试使用WMIC的具体内容也是由windows-cpu包处理的:

这就是我为什么工作:

 var spawn = require('child_process').spawn; var wmic = spawn('wmic', []); wmic.stdout.on('data', function(data) { console.log('Data received: [[' + data + ']]'); }); wmic.stderr.on('data', function(data) { console.log('Error! - ' + data); }); wmic.on('close', function(code) { console.log('Spawned process ended with code: ' + code); }); wmic.stdin.end( 'cpu get caption /format:csv' );