javascript - NodeJS、Windows、wmic 标准输入

标签 javascript windows node.js wmi 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 时也遇到了类似的问题,但他们只想捕获单个查询的输出,因此空标准输入对他们来说并不重要。

更新

如果我执行以下操作...

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');

这也有效,但是 wmic.exe 进程再次决定在返回 cpu 结果后退出。 :/

几乎

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

这有效。该进程正确启动,因此我通过 wmic.stdout.on('data', fn) 从 wmic.exe 收到提示,并且它保持打开状态。但是,我无法通过代码向其发送输入,但可以直接在命令提示符窗口中键入。我输入的任何内容都会通过 Node 脚本正确执行和输出。再次,奇怪的是它适用于这个管道,但不适用于我设置的任何管道,对我来说毫无用处,因为我想通过代码发送命令,而不是键入它们。

最佳答案

您想使用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 提供输入通过模拟击键。 Answers to this question建议几种方法:使用 SendKeys或发送 WM_KEYUP消息。这不是一个很好的解决方案。

关于javascript - NodeJS、Windows、wmic 标准输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18514031/

相关文章:

javascript - li clicked 函数使用 jquery

c++ - 为什么 utf-8 字符在 cmd.exe 中不显示?

python - 当程序启动时运行Python脚本

node.js - winston 记录对象

node.js - 使用 Nodejs 捕获事件 firebird 不起作用

node.js - node-mysql 重新抛出非 MySQL 错误

javascript - Json 对象每次返回时都会加倍

javascript - Y 轴上带有时间的 Chartjs 自定义图例

javascript - Access-control-allow-origin 无法在 POST 请求中使用 ajax

c++ - 如何使用 keybd_event 函数打印/按下 '@'?