RedFlag/agent/internal/system/process_windows.go
Fimeg 67e26be2d9 projection: begin the exact-path public epoch
The public tree and its history contain only the listed paths. Earlier projection history remains preserved internally.

Source-Sha: 913fde029b935671833254797f0f20f1eb9fabba

Policy-Sha: 913fde029b935671833254797f0f20f1eb9fabba

Tree-Digest: 180ae530c1058a2a5c89837bdce2d323ae83e669e38590ca72e75b8d92b7262f
2026-09-08 21:59:33 -04:00

57 lines
1.3 KiB
Go

//go:build windows
// +build windows
package system
import (
"encoding/csv"
"os/exec"
"sort"
"strconv"
"strings"
)
// getTopProcesses on Windows uses `tasklist /FO CSV /NH` for a no-dependency
// snapshot. WMI would be more precise but requires PowerShell overhead.
func getTopProcesses(limit int) ([]TopProcess, error) {
cmd := exec.Command("tasklist", "/FO", "CSV", "/NH")
out, err := cmd.Output()
if err != nil {
return nil, err
}
reader := csv.NewReader(strings.NewReader(string(out)))
records, err := reader.ReadAll()
if err != nil {
return nil, err
}
var procs []TopProcess
for _, row := range records {
if len(row) < 5 {
continue
}
name := strings.Trim(row[0], "\"")
pid, _ := strconv.Atoi(strings.Trim(row[1], "\""))
// tasklist doesn't give CPU%; mem is in KB
memStr := strings.ReplaceAll(strings.Trim(row[4], "\""), ".", "")
memKB, _ := strconv.ParseUint(memStr, 10, 64)
memPercent := float64(memKB) / (1024 * 1024) * 100 // rough; real impl needs total mem
procs = append(procs, TopProcess{
Name: name,
PID: pid,
CPU: 0, // tasklist doesn't report CPU%
Mem: memPercent,
})
}
sort.Slice(procs, func(i, j int) bool {
return procs[i].Mem > procs[j].Mem // sort by mem since CPU unavailable
})
if limit > 0 && len(procs) > limit {
procs = procs[:limit]
}
return procs, nil
}