我在NodeJS中遇到了Windows程序WMIC.exe(用于查询Windows Management Instrumentation)的问题。
我可以产生一个wmic.exe进程,但它不会输出任何内容或接受任何输入。但是,如果将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上也有类似的问题,但是他们只想捕获单个查询的输出,因此拥有空的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()时收到的标准输出“ 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');
这也可行,但是同样,在返回cpu结果之后,wmic.exe进程决定退出。:/
几乎
var wmic = spawn('wmic.exe', [], {stdio: [process.stdin, 'pipe', 'pipe']});
这行得通。该过程正确启动,因此我通过wmic.stdout.on('data',fn)从wmic.exe收到了提示,它保持打开状态。但是,我无法通过代码向其发送输入,但可以直接在命令提示符窗口中键入。我键入的任何内容都可以正确执行并通过节点脚本输出。再次,奇怪的是它与该管道一起工作,但是我设置的任何管道都不起作用,对我来说毫无用处,因为我想通过代码发送命令,而不是键入命令。
您希望以wmic
交互方式使用,但由应用程序的输入驱动,而不是在控制台上键入的输入驱动。
对于任何应用程序,实现此目标的正常方法是从管道中馈入输入。方便地,如果您未指定任何其他stdio
选项,则NodeJS似乎默认情况下会创建管道。
问题是,wmic
当它从管道接收输入时,行为会很差。在输入完成之前,它拒绝执行任何操作。然后,它将处理所有输入,并停止寻找更多内容。wmic
认为在关闭管道或收到CTRL-Z时输入已完成。
因此,您不能发出一个命令,不能读取输出,然后发出另一个命令。wmic
在认为自己已收到所有命令之后才写输出,然后它将不再接受。
您可以在控制台上说明此问题。type con: | wmic
将键盘输入通过管道输入wmic
,使其进入断开模式。在下面的示例中,后面是几个命令。请注意,wmic
在CTRL-Z
输入之前不执行任何操作。
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
消息。这不是一个很好的解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句