NodeJS,Windows,Wmic标准输入

先生加油

我在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,使其进入断开模式。在下面的示例中,后面是几个命令。请注意,wmicCTRL-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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章