【发布时间】:2017-06-20 11:06:24
【问题描述】:
在我的 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 var child = spawn('powershell.exe', ['-noexit', script]); 中使用了 -noexit 参数,这导致了这个日志。
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.stdout 和child.stdout.on('data', ...) 从不接收任何数据。正如您在第二个日志中看到的那样,没有DATA:。
所以我无法使用它
感谢您的帮助
【问题讨论】:
-
如果在脚本末尾添加
Wait-Event会发生什么?您也许可以使用它,或者它可能需要一个只等待事件的循环:while($true) { Wait-Event | Remove-Event }。
标签: node.js powershell