项目文件夹

文件
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

107 行
3.0 KiB
Go

//go:build windows
package proc
import (
"fmt"
"syscall"
"unsafe"
"github.com/pranshuparmar/witr/pkg/model"
)
var (
modpsapi = syscall.NewLazyDLL("psapi.dll")
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
procGetProcessIoCounters = modkernel32.NewProc("GetProcessIoCounters")
procGetProcessHandleCount = modkernel32.NewProc("GetProcessHandleCount")
)
// processMemoryCountersEx mirrors PROCESS_MEMORY_COUNTERS_EX. The CB field
// must be set to sizeof(struct) before GetProcessMemoryInfo so Windows can
// distinguish it from the non-EX variant.
type processMemoryCountersEx struct {
CB uint32
PageFaultCount uint32
PeakWorkingSetSize uintptr
WorkingSetSize uintptr
QuotaPeakPagedPoolUsage uintptr
QuotaPagedPoolUsage uintptr
QuotaPeakNonPagedPoolUsage uintptr
QuotaNonPagedPoolUsage uintptr
PagefileUsage uintptr
PeakPagefileUsage uintptr
PrivateUsage uintptr
}
type ioCounters struct {
ReadOperationCount uint64
WriteOperationCount uint64
OtherOperationCount uint64
ReadTransferCount uint64
WriteTransferCount uint64
OtherTransferCount uint64
}
// ReadExtendedInfo returns memory, I/O, thread, and handle counters for a
// PID. File descriptors and FD limit are zero-valued on Windows.
func ReadExtendedInfo(pid int) (model.MemoryInfo, model.IOStats, []string, int, uint64, int, error) {
var memInfo model.MemoryInfo
var ioStats model.IOStats
var threadCount int
var fdCount int
// Full access first, falling back to limited access for protected processes.
handle, err := syscall.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, false, uint32(pid))
if err != nil {
handle, err = syscall.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
if err != nil {
return memInfo, ioStats, nil, 0, 0, 0, fmt.Errorf("OpenProcess(%d): %w", pid, err)
}
}
defer syscall.CloseHandle(handle)
var pmc processMemoryCountersEx
pmc.CB = uint32(unsafe.Sizeof(pmc))
if ret, _, _ := procGetProcessMemoryInfo.Call(
uintptr(handle),
uintptr(unsafe.Pointer(&pmc)),
uintptr(pmc.CB),
); ret != 0 {
memInfo.RSS = uint64(pmc.WorkingSetSize)
memInfo.RSSMB = float64(memInfo.RSS) / (1024 * 1024)
memInfo.VMS = uint64(pmc.PrivateUsage)
memInfo.VMSMB = float64(memInfo.VMS) / (1024 * 1024)
}
var io ioCounters
if ret, _, _ := procGetProcessIoCounters.Call(
uintptr(handle),
uintptr(unsafe.Pointer(&io)),
); ret != 0 {
ioStats.ReadOps = io.ReadOperationCount
ioStats.ReadBytes = io.ReadTransferCount
ioStats.WriteOps = io.WriteOperationCount
ioStats.WriteBytes = io.WriteTransferCount
}
var hCount uint32
if ret, _, _ := procGetProcessHandleCount.Call(
uintptr(handle),
uintptr(unsafe.Pointer(&hCount)),
); ret != 0 {
fdCount = int(hCount)
}
if procs, err := enumerateProcesses(); err == nil {
for _, p := range procs {
if p.PID == pid {
threadCount = p.Threads
break
}
}
}
return memInfo, ioStats, nil, fdCount, 0, threadCount, nil
}