Process Monitor
Simple Windows C++ application that checks running processes every 30 seconds and sends one HTTP heartbeat with all matching processes.
What it does
- Enumerates running Windows processes via ToolHelp API
- Finds processes by partial name match
- Sends one JSON payload with all currently matched processes
- Builds with CMake without external runtime dependencies
Expected payload
The application sends HTTP POST with Content-Type: application/json.
{
"machine_name": "PC-01",
"status": "running",
"detected_at": "2026-03-27T12:34:56Z",
"processes": ["notepad.exe", "notepad++.exe"]
}
If api_token is set, request header Authorization: Bearer <token> is added.
If no process matches in a cycle, the application still sends a heartbeat, but without the processes field:
{
"machine_name": "PC-01",
"status": "running",
"detected_at": "2026-03-27T12:34:56Z"
}
Configuration
Edit process-monitor.conf.
api_url=http://10.0.0.147/hb/api
api_token=
machine_name=
interval_seconds=30
request_timeout_seconds=2
process_names=fortnite,chrome,discord,steam
Notes:
machine_nameis optional; if empty, Windows computer name is usedprocess_namesis a comma-separated list of substrings to search in executable namesinterval_secondscan be changed from the default30request_timeout_secondssets WinHTTP connect/send/receive timeout in seconds
Build
Developer Command Prompt for Visual Studio:
cmake -S . -B build
cmake --build build --config Release
Or with Ninja if you have a compiler environment ready:
cmake -S . -B build -G Ninja
cmake --build build
Run
When started manually, the executable runs in console mode:
.\build\Release\process-monitor.exe
Or specify custom config path:
.\build\Release\process-monitor.exe .\my-config.conf
To force console mode explicitly:
.\build\Release\process-monitor.exe --console .\my-config.conf
Windows Service
The executable can now run directly as a native Windows service through
StartServiceCtrlDispatcher. If started by the Service Control Manager, it
registers itself under the actual service name assigned in SCM and handles
stop/shutdown requests gracefully.
Important notes:
- Default config file is resolved relative to the executable directory, not the current working directory
- Log file is always written next to the executable as
process-monitor.log - Optional service argument after the executable path is treated as custom config path
Create the service with default config:
sc create ProcessMonitorService binPath= "D:\path\to\process-monitor.exe" start= auto
Create the service with custom config:
sc create ProcessMonitorService binPath= "\"D:\path\to\process-monitor.exe\" \"D:\path\to\custom.conf\"" start= auto
Start and stop:
sc start ProcessMonitorService
sc stop ProcessMonitorService
Or install it with the bundled script:
install-service.bat
The script expects process-monitor.exe and process-monitor.conf to be in the
same directory as install-service.bat.
Remove the service with:
uninstall-service.bat
Next useful improvements
- Add retry/backoff for failed API calls
- Add richer payload items if your API needs both matched pattern and actual process name
- Load config from JSON/YAML if richer metadata is needed