143 lines
3.3 KiB
Markdown
143 lines
3.3 KiB
Markdown
# 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`.
|
|
|
|
```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:
|
|
|
|
```json
|
|
{
|
|
"machine_name": "PC-01",
|
|
"status": "running",
|
|
"detected_at": "2026-03-27T12:34:56Z"
|
|
}
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Edit `process-monitor.conf`.
|
|
|
|
```ini
|
|
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_name` is optional; if empty, Windows computer name is used
|
|
- `process_names` is a comma-separated list of substrings to search in executable names
|
|
- `interval_seconds` can be changed from the default `30`
|
|
- `request_timeout_seconds` sets WinHTTP connect/send/receive timeout in seconds
|
|
|
|
## Build
|
|
|
|
Developer Command Prompt for Visual Studio:
|
|
|
|
```powershell
|
|
cmake -S . -B build
|
|
cmake --build build --config Release
|
|
```
|
|
|
|
Or with Ninja if you have a compiler environment ready:
|
|
|
|
```powershell
|
|
cmake -S . -B build -G Ninja
|
|
cmake --build build
|
|
```
|
|
|
|
## Run
|
|
|
|
When started manually, the executable runs in console mode:
|
|
|
|
```powershell
|
|
.\build\Release\process-monitor.exe
|
|
```
|
|
|
|
Or specify custom config path:
|
|
|
|
```powershell
|
|
.\build\Release\process-monitor.exe .\my-config.conf
|
|
```
|
|
|
|
To force console mode explicitly:
|
|
|
|
```powershell
|
|
.\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:
|
|
|
|
```cmd
|
|
sc create ProcessMonitorService binPath= "D:\path\to\process-monitor.exe" start= auto
|
|
```
|
|
|
|
Create the service with custom config:
|
|
|
|
```cmd
|
|
sc create ProcessMonitorService binPath= "\"D:\path\to\process-monitor.exe\" \"D:\path\to\custom.conf\"" start= auto
|
|
```
|
|
|
|
Start and stop:
|
|
|
|
```cmd
|
|
sc start ProcessMonitorService
|
|
sc stop ProcessMonitorService
|
|
```
|
|
|
|
Or install it with the bundled script:
|
|
|
|
```cmd
|
|
install-service.bat
|
|
```
|
|
|
|
Remove the service with:
|
|
|
|
```cmd
|
|
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
|