在nodejs中执行长时间运行的PowerShell脚本

时间:2015-01-07 16:27:29

标签: node.js powershell

在我的nodejs项目中,我需要检测usb闪存驱动器何时插入/拔出。我选择使用powershell脚本并使用child_process exec或spawn运行它。

psscript.ps1

Write-Host "listening for Win32_VolumeChangeEvent";
Register-WmiEvent -Query "SELECT * FROM Win32_VolumeChangeEvent" -Action {Write-Host "something happened"} | Out-Null;

我不是PowerShell的专家,但它应该只听取volumeChangeEvent并在它触发时写something happened

Nodejs使用以下代码将其生成为子代

nodescript.js

var spawn = require('child_process').spawn;
var child = spawn('powershell.exe', ['psscript.ps1']);
child.stdout.on('data', function(data){
    console.log('DATA:', data.toString());
});
child.stdout.on('close', function(data){
    console.log('psscript closed');
});

它应该抓住孩子的标准输出并解析它。出于演示目的,它只使用前置字符串DATA:打印出来。

这是日志。 nodescript生成psscript并根据需要使用DATA:打印其输出。问题是psscript关闭,nodejs退出,所以我永远不会收到事件。

C:\myproject>node nodescript.js
DATA: listening for Win32_VolumeChangeEvent
DATA:

psscript closed

C:\myproject>

所以我一直在寻找一种方法来使PowerShell不关闭。我最终在spawn -noexit中使用了var child = spawn('powershell.exe', ['-noexit', script]);参数,这导致了这个日志。

C:\myproject>node nodescript.js
listening for Win32_VolumeChangeEvent
PS C:\myproject> something happened
something happened

nodescript生成psscript,打印listening for Win32_VolumeChangeEvent就好了,然后打印PS C:\myproject>(注意PS)。我想powershell脚本注册了事件监听器然后关闭(因此PS C:\myproject>)但powershell仍在运行(因此something happened)以及节点。这让我感到困惑,因为我只是习惯了节点处理事件监听器的方式(当连接任何监听器时,节点永远不会关闭)。无论如何,powershell脚本继续收听和通知。这是两次打印something happened,因为我插入了闪存驱动器。

这就是我想要的,但问题是产生-noexit的孩子接管我的nodejs控制台并使用powershell的输出污染它,而它永远不会将它输出到child.stdoutchild.stdout.on('data', ...)永远不会收到任何数据。正如您在第二个日志中看到的那样,没有DATA:。 所以我无法使用它

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

要保持节点正常运行,您只需在代码段后添加while(true) {}语句。

要让您的节点实例最终超时,您可以使用setTimeout并在超时到期时调用process.exit()