簡體   English   中英

NodeJS,Windows,Wmic標准輸入

[英]NodeJS, Windows, wmic stdin

我在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從管道接收輸入時表現不佳。 在輸入完成之前,它拒絕執行任何操作。 然后,它將處理所有輸入,並停止尋找更多內容。 當管道關閉或收到CTRL-Z時, wmic認為輸入已完成。

因此,您不能發出一個命令,不能讀取輸出,然后發出另一個命令。 在認為自己已收到所有命令之后, wmic才寫輸出,然后它將不再接受。

您可以在控制台上說明此問題。 type con: | wmic type con: | wmic通過管道放置鍵盤輸入,因此wmic進入其損壞模式。 在下面的示例中,后面是幾個命令。 注意,在輸入CTRL-Z之前, wmic不會執行任何操作。

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消息。 這不是一個很好的解決方案。

為了后代...

現在可以通過使用ms-wmic包來實現:

這完全避免了直接與CLI交互的麻煩,並允許您通過預設的API處理WMIC


但是,您在上面的示例中嘗試使用WMIC的特定操作也由windows-cpu軟件包處理:

那對我來說是這樣的:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM