admin管理员组文章数量:1429851
I've having a problem with the Windows program WMIC.exe (used for querying Windows Management Instrumentation), from within NodeJS.
I can spawn a wmic.exe process, but it'll not output anything or accept any input. However, if I set the stdin to null it'll run correctly and I'll receive output.
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);
});
I want to use wmic.exe interactively, which it supports, keeping it open so I don't have to repeatedly start it for each WMI query. Others have had similar problems with wmic.exe, but they only wanted to capture output for a single query, so having a null stdin doesn't matter to them.
Update
If I do the following...
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');
Then it'll actually respond with a result, prompt back ready for the next query but next ends the process and obviously I can't use .write() after .end(). Changing it to a .write() instead, process doesn't respond at all and I don't even get the prompt from stdout "wmic:root\cli>" that I receive when using .end().
Or
wmic.stdin.push(null);
wmic.stdin.write('cpu/n'); // Ctrl-Z aka Windows EOF control code
If I use the above, instead of the .end() call, it'll also work. But it seems that if I don't keep throwing constant data at it, the process ends.
Or even
wmic.stdin.write('cpu');
wmic.stdin.write('\x1a');
This works too, but yet again, the wmic.exe process decides to exit after the cpu results are returned. :/
Almost
var wmic = spawn('wmic.exe', [], {stdio: [process.stdin, 'pipe', 'pipe']});
This works. The process starts up correctly so I receive the prompt from wmic.exe through wmic.stdout.on('data', fn) and it stays open. However, I'm unable to send input to it via code but can type directly into the mand prompt window. Anything I type is correctly executed and output via the node script. Again, weird that it works with this pipe but not any I set and useless to me as I want to send mands via code, not typing them.
I've having a problem with the Windows program WMIC.exe (used for querying Windows Management Instrumentation), from within NodeJS.
I can spawn a wmic.exe process, but it'll not output anything or accept any input. However, if I set the stdin to null it'll run correctly and I'll receive output.
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);
});
I want to use wmic.exe interactively, which it supports, keeping it open so I don't have to repeatedly start it for each WMI query. Others have had similar problems with wmic.exe, but they only wanted to capture output for a single query, so having a null stdin doesn't matter to them.
Update
If I do the following...
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');
Then it'll actually respond with a result, prompt back ready for the next query but next ends the process and obviously I can't use .write() after .end(). Changing it to a .write() instead, process doesn't respond at all and I don't even get the prompt from stdout "wmic:root\cli>" that I receive when using .end().
Or
wmic.stdin.push(null);
wmic.stdin.write('cpu/n'); // Ctrl-Z aka Windows EOF control code
If I use the above, instead of the .end() call, it'll also work. But it seems that if I don't keep throwing constant data at it, the process ends.
Or even
wmic.stdin.write('cpu');
wmic.stdin.write('\x1a');
This works too, but yet again, the wmic.exe process decides to exit after the cpu results are returned. :/
Almost
var wmic = spawn('wmic.exe', [], {stdio: [process.stdin, 'pipe', 'pipe']});
This works. The process starts up correctly so I receive the prompt from wmic.exe through wmic.stdout.on('data', fn) and it stays open. However, I'm unable to send input to it via code but can type directly into the mand prompt window. Anything I type is correctly executed and output via the node script. Again, weird that it works with this pipe but not any I set and useless to me as I want to send mands via code, not typing them.
Share Improve this question edited Sep 2, 2013 at 15:11 Mister Dai asked Aug 29, 2013 at 14:41 Mister DaiMister Dai 8161 gold badge8 silver badges20 bronze badges 2-
1
This is quite a strange problem, I've done testing for about two hours and WMIC consistently treats
EOF
like a newline (which automatically closes streams). I also tested spawningcmd
(powershell
too) and runningwmic.exe
as a mand, and the result is the same. Will continue testing. – hexacyanide Commented Sep 2, 2013 at 20:50 - Agreed, I went down the route of spawning cmd and using that to fire up wmic.exe but same issue as always. I find it odd that process.stdin will get it going, definitely something odd going on. Thanks for taking a look ;) – Mister Dai Commented Sep 2, 2013 at 22:00
3 Answers
Reset to default 3 +100You want to use wmic
interactively, but driven by input from an application rather than input typed at the console.
The normal way to achieve this for any application is to feed it input from a pipe. Conveniently, NodeJS appears to create a pipe by default if you don't specify any other stdio
option.
The problem is that wmic
behaves badly when it is receiving input from a pipe. It refuses to do anything until the input is plete; it then processes all the input and stops looking for any more. wmic
thinks that the input is plete when the pipe is closed or it receives a CTRL-Z.
Hence you cannot issue one mand, read the output and then issue another mand. wmic
doesn't write output until it thinks it has received all the mands, and then it won't accept any more.
You can illustrate this problem at the console. type con: | wmic
puts keyboard input through a pipe so wmic
goes into its broken mode. In the example below this is followed by a couple of mands. Note that wmic
does nothing until CTRL-Z
is entered.
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:\>
You might think (looking at this example) that wmic
just has a large output buffer. However, if you turn on tracing (/TRACE:ON
as the first mand) wmic
produces reams of output, but nothing before the input is plete.
A solution is to not redirect the standard input, like your final example, so the input is ing from the keyboard. (N.B. when a Windows console application receives input from the keyboard it is not ing through a pipe. Hence your final example is not using a pipe, which is why is behaves differently.)
You can then supply input to wmic
by simulating keystrokes. Answers to this question suggest a couple of methods: either using SendKeys
or by sending WM_KEYUP
messages. This is not a great solution.
For posterity...
This is now possible by using the ms-wmic
package:
- https://www.npmjs./package/ms-wmic
This pletely bypasses having to directly interact with the CLI, and allows you to deal with WMIC
through a preset API.
But the specific thing you tried to use WMIC
for in your example above, is also handled by the windows-cpu
package:
- https://www.npmjs./package/windows-cpu
That's how it worked for me:
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' );
本文标签: JavaScriptNodeJSWindowswmic stdinStack Overflow
版权声明:本文标题:javascript - NodeJS, Windows, wmic stdin - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745088784a2641617.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论