# How DeviceStatusProvider Collects Windows Host Metadata and Process Information in openclaw-windows-node

> Discover how DeviceStatusProvider in openclaw-windows-node collects Windows host metadata and process data using .NET, Win32, and WinRT for OS, CPU, memory, disk, and power state snapshots.

- Repository: [openclaw/openclaw-windows-node](https://github.com/openclaw/openclaw-windows-node)
- Tags: deep-dive
- Published: 2026-06-05

---

**The `DeviceStatusProvider` class in `openclaw-windows-node` gathers Windows host metadata and process information by combining .NET base class library APIs, Win32 P/Invoke, and WinRT battery contracts to produce serialized snapshots of OS, CPU, memory, disk, and power state.**

The `DeviceStatusProvider` is the Windows-specific implementation of the `IDeviceStatusProvider` contract in the [openclaw-windows-node](https://github.com/openclaw/openclaw-windows-node) repository. It lives in [`src/OpenClaw.Tray.WinUI/Services/DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/src/OpenClaw.Tray.WinUI/Services/DeviceStatusProvider.cs) and is designed to supply the OpenClaw tray UI with an on-board, self-contained diagnostics snapshot without relying on any external services. Every query method returns a plain C# anonymous type that the application serializes to JSON for local or remote reporting.

## Operating System and Host Identity

The `GetOsInfo` method ([`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs), lines 59–68) collects core platform data using standard .NET environment properties. It reads `Environment.OSVersion` to capture the Windows build, `RuntimeInformation.OSArchitecture` for the processor architecture, `Environment.MachineName` for the device name, and `Environment.TickCount64` to compute system uptime. Because these values are in-process memory lookups, the method completes synchronously and returns immediately.

## CPU Detection and Dynamic Utilization

### Processor Name and Core Count

The provider discovers the CPU model by reading the registry key `HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\ProcessorNameString`. The logical core count is taken from `Environment.ProcessorCount`. This logic lives in `GetCpuInfoAsync` at [`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs) lines 72–88.

### Background Sampling of CPU Load

To track host-level process load, the class maintains a background `System.Timers.Timer` that samples a `PerformanceCounter` targeting `Processor\% Processor Time\_Total`. The `StartCpuSampling` method ([`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs), lines 35–52) primes the counter with an initial read of `0`, then refreshes `_lastCpuUsage` every two seconds from the timer callback at lines 44–49. Callers who invoke `GetCpuInfoAsync` receive the most recent sampled value, which may be `null` during the first warm-up window.

## Memory Metrics via Win32 P/Invoke

Memory statistics are gathered through `GlobalMemoryStatusEx` from `kernel32.dll`, declared in the P/Invoke block inside [`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs) (lines 29–48). The `GetMemoryInfo` method (lines 94–112) populates a `MEMORYSTATUSEX` structure and derives the usage percentage from total and available physical memory. This approach avoids shelling out to external tools and keeps all memory calculations inside the process.

## Disk Enumeration and Capacity Metrics

The `GetDiskInfo` method ([`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs), lines 14–41) iterates over `DriveInfo.GetDrives()`, filters for ready fixed drives, and reads `TotalSize`, `AvailableFreeSpace`, `VolumeLabel`, and `DriveFormat`. Usage percent is calculated directly from total versus free space for each eligible volume.

## Battery State Through WinRT

Battery data is collected via the `Windows.Devices.Power.Battery` WinRT API. Inside `GetBatteryInfo` ([`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs), lines 44–95), the provider requests an aggregate battery report through `GetReport()`, capturing presence, charge capacity, status (`Charging`, `Discharging`, `NotPresent`), charge rate, and remaining capacity. From these fields it derives the charge percentage and, when the system is discharging, an estimated minutes-remaining value. This API path is only available on Windows 10 and later hosts.

## Lifecycle Management and Cleanup

The provider implements `IDisposable`. The `Dispose` method ([`DeviceStatusProvider.cs`](https://github.com/openclaw/openclaw-windows-node/blob/main/DeviceStatusProvider.cs), lines 110–127) drains the background timer, disposes the `PerformanceCounter`, and clears the timer reference to prevent race conditions during application shutdown.

## Usage Examples

The following pattern shows how to initialize the provider, start background sampling, query host metadata, and dispose of resources cleanly.

```csharp
// Startup: create the provider and begin CPU sampling
var logger = serviceProvider.GetRequiredService<IOpenClawLogger>();
var statusProvider = new DeviceStatusProvider(logger);
statusProvider.StartCpuSampling();

```

```csharp
// Querying snapshots (CPU may be null during warm-up)
var osInfo   = statusProvider.GetOsInfo();
var cpuInfo  = await statusProvider.GetCpuInfoAsync();
var memInfo  = statusProvider.GetMemoryInfo();
var diskInfo = statusProvider.GetDiskInfo();
var battInfo = statusProvider.GetBatteryInfo();

```

```csharp
// Shutdown: release the PerformanceCounter and timer
statusProvider.Dispose();

```

## Summary

- **`DeviceStatusProvider`** implements `IDeviceStatusProvider` entirely on-device, using no external services.
- **OS metadata** is sourced from `Environment` properties in `GetOsInfo`.
- **CPU name** comes from the registry, while **CPU usage** is sampled by a background `Timer` driving a `PerformanceCounter`.
- **Memory** is queried through the Win32 `GlobalMemoryStatusEx` P/Invoke path in `GetMemoryInfo`.
- **Disk layout** is enumerated with `DriveInfo.GetDrives()` inside `GetDiskInfo`.
- **Battery state** is read from the WinRT `Windows.Devices.Power.Battery` API in `GetBatteryInfo`.
- All errors are logged via `IOpenClawLogger` and returned as fallback objects to keep the tray UI stable.

## Frequently Asked Questions

### What API does DeviceStatusProvider use to sample CPU usage?

The provider creates a `PerformanceCounter` for `Processor\% Processor Time\_Total` and samples it every two seconds via a background `System.Timers.Timer`. The latest value is stored in `_lastCpuUsage` and returned asynchronously by `GetCpuInfoAsync`.

### How does DeviceStatusProvider read total and available memory?

It calls the Win32 `GlobalMemoryStatusEx` function through a P/Invoke declaration to `kernel32.dll`. The `GetMemoryInfo` method uses the returned `MEMORYSTATUSEX` structure to calculate total, available, and percentage-used physical memory.

### Does DeviceStatusProvider require an external service to collect data?

No. According to the openclaw-windows-node source code, all data collection happens locally on the Windows host through .NET BCL APIs, registry reads, Win32 P/Invoke, and WinRT contracts.

### What happens if the device has no battery or the registry query fails?

Errors are caught internally and forwarded to the injected `IOpenClawLogger`. The provider returns a safe fallback payload instead of throwing, ensuring the tray UI continues to function even when individual sensors are unavailable.