@jellybrick/wql-process-monitor
v1.4.8
Published
Monitor Windows process creation/deletion events via WMI (WQL)
Downloads
145
Maintainers
Readme
About
Monitor Windows process creation/deletion events via WMI (WQL) in Node.js
Example
import { promises as WQL } from 'wql-process-monitor';
const processMonitor = await WQL.subscribe({
filterWindowsNoise: false
});
processMonitor.on("creation", ([process,pid,filepath]) => {
console.log(`creation: ${process}::${pid} ["${filepath}"]`);
});
processMonitor.on("deletion",([process,pid]) => {
console.log(`deletion: ${process}::${pid}`);
});
/*
Keep alive
You don't need this if you have something else to keep the event loop running.
This is just as an example so Node.js doesn't exit directly.
*/
setInterval(()=>{}, 1000 * 60 * 60);
Do something when a specific process is started :
const processMonitor = await WQL.subscribe({
creation: true,
deletion: false,
filter: ["firefox.exe"],
whitelist: true
});
processMonitor.on("creation", ([process,pid,filepath]) => {
console.log(`creation: ${process}::${pid} ["${filepath}"]`);
});
Installation
npm install wql-process-monitor
Prerequisite: C/C++ build tools (Visual Studio) and Python 3.x (node-gyp) in order to build node-ffi-napi.
API
Promises are available for all methods under the .promises obj.
//Example cjs
const WQL = require('wql-process-monitor');
WQL.createEventSink(); //sync
WQL.promises.createEventSink(); //promise
💡 Usage of promise instead of sync is recommended so that you will not block Node's event loop.
subscribe([obj option]) : AsyncEventEmitter
⚙️ Options:
creation | bool (default true)
Subscribe to the creation event
deletion | bool (default true)
Subscribe to the deletionn event
filterWindowsNoise | bool (default false)
Exclude events originating from System32 and SysWOW64 Windows folder as well as integrated OneDrive
FileCoAuth.exe
. Ex: cmd.exe, powershell.exe, svchost.exe, RuntimeBroker.exe, and others Windows processes.⚠️ NB: Using this will prevent you to catch any elevated process event. Unless you are also elevated. This is a permission issue (See #2). You can implement your own filter on top of the event emitter result instead.
filterUsualProgramLocations | bool (default false)
Exclude events originating from Program Files, Program Files (x86), AppData local and AppData Roaming.
⚠️ NB: Using this will prevent you to catch any elevated process event. Unless you are also elevated. This is a permission issue (See #2). You can implement your own filter on top of the event emitter result instead.
filter | array of string (default none)
Custom list of process to exclude. eg: ["firefox.exe","chrome.exe",...]
NB:
There are limits to the number of AND and OR keywords that can be used in WQL queries. Large numbers of WQL keywords used in a complex query can cause WMI to return the WBEM_E_QUOTA_VIOLATION error code as an HRESULT value. The limit of WQL keywords depends on how complex the query is
cf: https://docs.microsoft.com/en-us/windows/win32/wmisdk/querying-with-wql If you have a huge list consider implementing your own filter on top of the event emitter result instead.whitelist | bool (default false)
Use
filter
option as a whitelist.filterWindowsNoise
/filterUsualProgramLocations
can still be used. Previously mentioned limitation(s) still apply.
✔️ Return a non-blocking async event emitter (emittery):
.on("creation", ([process,pid,filepath]) => {})
.on("deletion", ([process,pid]) => {})
|Value|Description|Example| |-----|-----------|-------| |process|process name| firefox.exe| |pid|process identifier| 16804| |filepath|file location path (if available*)|C:\Program Files\Mozilla Firefox\firefox.exe|
*filepath is only available in "creation" (well it doesn't make sense to open a deleted process for its information ^^) and will sometimes be empty because of permission to access a process information and in the same fashion 32bits can not access 64 bits.
💡 Don't forget to keep the node.js event loop alive.
createEventSink(void) : void
Initialize the event sink. This is required to do before you can subscribe to any events. If the event sink is already initialized then nothing will be done.
💡 Since version >= 2.0 this is automatically done for you when you call subscribe()
.
Method was merely kept for backward compatibility.
⚠️ If your application (the caller thread) is initializing a COM library you need to set the thread model to COINIT_MULTITHREADED For this reason using this in Electron's main process isn't viable. If you really need to use Electron's main process; Here are some workarounds:
- spawn a node child process to execute this module
- use web workers
- use a hidden browser window and communicate between the main process and background window via Electron's IPC.
closeEventSink(void) : void
Properly close the event sink. There is no 'un-subscribe' thing to do prior to closing the sink. Just close it. It is recommended to properly close the event sink when you are done if you intend to re-open it later on. Most of the time you wouldn't have to bother with this but it's here in case you need it.