首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NodeJS,Windows,wmic

NodeJS,Windows,wmic
EN

Stack Overflow用户
提问于 2013-08-29 14:41:05
回答 3查看 4K关注 0票数 2

我在WMIC.exe程序中遇到了问题(用于查询NodeJS内部的管理工具)。

我可以生成一个wmic.exe进程,但它不会输出任何内容或接受任何输入。但是,如果我将stdin设置为null,它将正确运行并接收输出。

代码语言:javascript
复制
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对他们来说并不重要。

更新

如果我做下面的事..。

代码语言:javascript
复制
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()之后使用.end()。相反,将其更改为.write(),进程根本不会响应,甚至在使用.end()时收到stdout "wmic:root\cli>“的提示。

代码语言:javascript
复制
wmic.stdin.push(null);
wmic.stdin.write('cpu/n'); // Ctrl-Z aka Windows EOF control code

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

甚至

代码语言:javascript
复制
wmic.stdin.write('cpu');
wmic.stdin.write('\x1a');

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

几乎

代码语言:javascript
复制
var wmic = spawn('wmic.exe', [], {stdio: [process.stdin, 'pipe', 'pipe']});

这个很管用。进程正确启动,因此我通过wmic.exe (‘data’,fn)接收来自wmic.stdout.on的提示,并保持打开状态。但是,我无法通过代码向它发送输入,但可以直接输入命令提示符窗口。我输入的任何内容都是通过节点脚本正确执行和输出的。同样奇怪的是,它适用于这个管道,但我设置的任何命令对我来说都没有用,因为我想通过代码发送命令,而不是键入命令。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-03 22:51:14

您希望以交互方式使用wmic,但驱动的是来自应用程序的输入,而不是控制台上键入的输入。

对于任何应用程序来说,实现这一点的正常方法是从管道中输入输入。如果您不指定任何其他NodeJS选项,那么在默认情况下,NodeJS似乎会创建一个管道。

问题是,wmic在接收来自管道的输入时表现很差。它拒绝做任何事情,直到输入完成;然后它处理所有的输入并停止寻找更多的输入。wmic认为,当管道关闭或收到CTRL时,输入就完成了。

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

您可以在控制台上演示这个问题。type con: | wmic通过管道输入键盘,这样wmic就进入了坏模式。在下面的示例中,后面跟着几个命令。注意,wmic在输入CTRL-Z之前什么也不做。

代码语言:javascript
复制
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控制台应用程序从键盘接收输入时,它不是通过管道输入的。因此,最后一个例子是不使用管道,这就是is行为不同的原因。)

然后,您可以通过模拟击键来向wmic提供输入。对这个问题的回答建议了几种方法:要么使用SendKeys,要么通过发送WM_KEYUP消息。这不是一个很好的解决办法。

票数 3
EN

Stack Overflow用户

发布于 2015-12-08 18:59:38

为了子孙后代..。

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

这完全绕过了直接与CLI交互,并允许您通过预置API处理WMIC

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

票数 2
EN

Stack Overflow用户

发布于 2014-09-08 23:40:47

对我来说是这样的:

代码语言:javascript
复制
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' );
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18514031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档