Files
wehub-resource-sync 36b3af2e3d
PR Check / Code Quality: Format (push) Failing after 1s
PR Check / Code Quality: Lint (darwin) (push) Failing after 0s
PR Check / Code Quality: Lint (freebsd) (push) Failing after 1s
PR Check / Code Quality: Lint (windows) (push) Failing after 1s
PR Check / Code Quality: Lint (linux) (push) Failing after 1s
PR Check / Security: Vulnerability Scan (push) Failing after 0s
Update Documentation / update-docs (push) Failing after 2s
PR Check / Code Quality: Vendor (push) Failing after 1s
PR Check / Code Quality: Coverage (push) Failing after 0s
PR Check / Tests: Unit (macos-latest) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04) (push) Has been cancelled
PR Check / Tests: Unit (ubuntu-24.04-arm) (push) Has been cancelled
PR Check / Tests: Unit (windows-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:22:06 +08:00

84 lines
2.3 KiB
Go

//go:build windows
package proc
import (
"fmt"
"os"
"path/filepath"
"github.com/pranshuparmar/witr/pkg/model"
)
func ReadProcess(pid int) (model.Process, error) {
// PID 0 is the System Idle Process on Windows (and negative PIDs are never
// valid), so reject them rather than returning the idle pseudo-process —
// this matches the other platforms, where /proc/0 or `ps -p 0` fails.
if pid <= 0 {
return model.Process{}, fmt.Errorf("invalid pid %d", pid)
}
info, err := GetProcessDetailedInfo(pid)
if err != nil {
return model.Process{}, err
}
name := ""
if info.Exe != "" {
name = filepath.Base(info.Exe)
}
procSockets := GetSocketsForPID(pid)
serviceName := detectWindowsServiceSource(pid)
container := detectContainerFromCmdline(info.CommandLine)
gitRepo, gitBranch := detectGitInfo(info.Cwd)
// Resident memory (working set) and lifetime-average CPU%. CPU mirrors the
// figure shown in the verbose report (ResourceContext) so every output mode
// reports the same value.
rss, cpu, cpuTime, _ := windowsProcMetrics(pid)
return model.Process{
PID: pid,
PPID: info.PPID,
Command: name,
Cmdline: info.CommandLine,
Exe: info.Exe,
StartedAt: info.StartedAt,
User: readUser(pid),
CPUPercent: cpu,
MemoryRSS: rss,
MemoryPercent: windowsMemoryPercent(rss),
WorkingDir: info.Cwd,
GitRepo: gitRepo,
GitBranch: gitBranch,
Sockets: procSockets,
Health: windowsHealth(rss, cpuTime),
Forked: "unknown",
Env: info.Env,
Service: serviceName,
Container: container,
ExeDeleted: isWindowsBinaryDeleted(info.Exe),
}, nil
}
func isWindowsBinaryDeleted(path string) bool {
// A non-absolute path means we only recovered the bare image name from the
// process snapshot (the case for protected/system processes we couldn't
// open, e.g. vmmemWSL) — that's "couldn't read the real path", not a
// confirmed-deleted binary, so don't raise the deleted-binary warning.
if path == "" || !filepath.IsAbs(path) {
return false
}
_, err := os.Stat(path)
return os.IsNotExist(err)
}
// detectWindowsServiceSource returns the Windows service name that owns the PID, if any.
func detectWindowsServiceSource(pid int) string {
services, err := serviceMapForPIDs()
if err != nil {
return ""
}
return services[pid]
}