2

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 で同様の問題を抱えていましたが、単一のクエリの出力のみをキャプチャしたかったため、標準入力が null であることは問題ではありませんでした。

アップデート

私が次のことをすると...

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() の使用時に受け取る stdout "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.exe から wmic.stdout.on('data', fn) を介してプロンプトを受け取り、開いたままになります。ただし、コードを介して入力を送信することはできませんが、コマンド プロンプト ウィンドウに直接入力することはできます。入力したものはすべて正しく実行され、ノード スクリプトを介して出力されます。繰り返しますが、このパイプで動作するのは奇妙ですが、入力するのではなく、コードを介してコマンドを送信したいので、設定したものは役に立ちません。

4

3 に答える 3

3

対話的に使用したいがwmic、コンソールで入力された入力ではなく、アプリケーションからの入力によって駆動される。

どのアプリケーションでもこれを実現する通常の方法は、パイプから入力を与えることです。便利なことに、他のオプションを指定しない場合、NodeJS はデフォルトでパイプを作成するように見えstdioます。

問題はwmic、パイプから入力を受け取るときの動作が悪いことです。入力が完了するまで何もすることを拒否します。次に、すべての入力を処理し、それ以上の検索を停止します。 wmicは、パイプが閉じられるか、CTRL-Z を受け取ると、入力が完了したと見なします。

したがって、1 つのコマンドを発行し、出力を読み取ってから別のコマンドを発行することはできません。 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これは優れた解決策ではありません。

于 2013-09-03T22:51:14.343 に答える
2

後世に…

これは、ms-wmicパッケージを使用することで可能になりました。

これにより、CLI と直接やり取りする必要が完全に回避WMICされ、事前設定された API を介して処理できるようになります。


WMICただし、上記の例で使用しようとした特定のものも、windows-cpuパッケージによって処理されます。

于 2015-12-08T18:59:38.227 に答える