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

Mik*_*řík 6 powershell node.js

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

ps脚本.ps1

Write-Host "listening for Win32_VolumeChangeEvent";
Register-WmiEvent -Query "SELECT * FROM Win32_VolumeChangeEvent" -Action {Write-Host "something happened"} | Out-Null;
Run Code Online (Sandbox Code Playgroud)

我不是 powershell 方面的专家,但它应该只监听volumeChangeEvent并something happened在它触发时写入

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

节点脚本.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');
});
Run Code Online (Sandbox Code Playgroud)

它应该捕获孩子的标准输出上的任何内容并解析它。出于演示目的,它只是打印出带有前缀的 string DATA:

这是日志。nodescript 生成 psscript 并按DATA:我想要的方式打印其输出。问题是 psscript 关闭并且 nodejs 也退出,所以我永远不会收到事件。

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

psscript closed

C:\myproject>
Run Code Online (Sandbox Code Playgroud)

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

C:\myproject>node nodescript.js
listening for Win32_VolumeChangeEvent
PS C:\myproject> something happened
something happened
Run Code Online (Sandbox Code Playgroud)

nodescript 生成 psscript,它打印得listening for Win32_VolumeChangeEvent很好,但随后又打印了PS C:\myproject>(注意PS)。我猜想 powershell 脚本注册了事件侦听器,然后关闭(因此PS C:\myproject>),但 powershell 仍在运行(因此something happened)以及 node.js 。这让我感到困惑,因为我只是习惯了节点处理事件侦听器的方式(当附加任何侦听器时节点永远不会关闭)。不管怎样,powershell 脚本会继续监听和通知。这是两次打印,something happened因为我插拔了闪存驱动器。

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

感谢您的帮助

Sli*_*SFT 0

要保持Node运行 - 您只需while(true) {}在代码片段后面添加一条语句即可。

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