Files
driver-booster/internal/sysinfo/sysinfo.go
taqin 3e432fbb50 Initial commit: Driver Booster Pro - Go + WebView2 desktop app
Windows system utility with driver scanning, Windows Update integration,
and system info collection. Beautiful dark-themed UI via embedded WebView2.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 20:42:34 +07:00

157 lines
4.2 KiB
Go

package sysinfo
import (
"fmt"
"os/exec"
"runtime"
"strings"
"syscall"
"unsafe"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGlobalMemoryEx = kernel32.NewProc("GlobalMemoryStatusEx")
procGetDiskFreeSpaceA = kernel32.NewProc("GetDiskFreeSpaceExA")
procGetComputerNameW = kernel32.NewProc("GetComputerNameW")
ntdll = syscall.NewLazyDLL("ntdll.dll")
procRtlGetVersion = ntdll.NewProc("RtlGetVersion")
)
type Info struct {
ComputerName string `json:"computerName"`
OSName string `json:"osName"`
OSVersion string `json:"osVersion"`
OSBuild string `json:"osBuild"`
Architecture string `json:"architecture"`
CPUName string `json:"cpuName"`
CPUCores int `json:"cpuCores"`
TotalRAM string `json:"totalRam"`
UsedRAM string `json:"usedRam"`
FreeRAM string `json:"freeRam"`
RAMPercent int `json:"ramPercent"`
DiskTotal string `json:"diskTotal"`
DiskFree string `json:"diskFree"`
DiskUsed string `json:"diskUsed"`
DiskPercent int `json:"diskPercent"`
}
type memoryStatusEx struct {
Length uint32
MemoryLoad uint32
TotalPhys uint64
AvailPhys uint64
TotalPageFile uint64
AvailPageFile uint64
TotalVirtual uint64
AvailVirtual uint64
AvailExtendedVirtual uint64
}
type osVersionInfoExW struct {
OSVersionInfoSize uint32
MajorVersion uint32
MinorVersion uint32
BuildNumber uint32
PlatformId uint32
CSDVersion [128]uint16
}
type Collector struct{}
func NewCollector() *Collector {
return &Collector{}
}
func (c *Collector) Collect() Info {
info := Info{
Architecture: runtime.GOARCH,
CPUCores: runtime.NumCPU(),
}
info.ComputerName = getComputerName()
info.CPUName = getCPUName()
// OS version via RtlGetVersion (accurate, not subject to compatibility shims)
var osvi osVersionInfoExW
osvi.OSVersionInfoSize = uint32(unsafe.Sizeof(osvi))
procRtlGetVersion.Call(uintptr(unsafe.Pointer(&osvi)))
info.OSVersion = fmt.Sprintf("%d.%d", osvi.MajorVersion, osvi.MinorVersion)
info.OSBuild = fmt.Sprintf("%d", osvi.BuildNumber)
info.OSName = getWindowsProductName()
// Memory
var mem memoryStatusEx
mem.Length = uint32(unsafe.Sizeof(mem))
procGlobalMemoryEx.Call(uintptr(unsafe.Pointer(&mem)))
info.TotalRAM = formatBytes(mem.TotalPhys)
info.FreeRAM = formatBytes(mem.AvailPhys)
info.UsedRAM = formatBytes(mem.TotalPhys - mem.AvailPhys)
info.RAMPercent = int(mem.MemoryLoad)
// Disk (C: drive)
var freeBytesAvailable, totalBytes, totalFreeBytes uint64
cDrive, _ := syscall.BytePtrFromString("C:\\")
procGetDiskFreeSpaceA.Call(
uintptr(unsafe.Pointer(cDrive)),
uintptr(unsafe.Pointer(&freeBytesAvailable)),
uintptr(unsafe.Pointer(&totalBytes)),
uintptr(unsafe.Pointer(&totalFreeBytes)),
)
info.DiskTotal = formatBytes(totalBytes)
info.DiskFree = formatBytes(totalFreeBytes)
info.DiskUsed = formatBytes(totalBytes - totalFreeBytes)
if totalBytes > 0 {
info.DiskPercent = int(((totalBytes - totalFreeBytes) * 100) / totalBytes)
}
return info
}
func getComputerName() string {
var size uint32 = 256
buf := make([]uint16, size)
procGetComputerNameW.Call(uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&size)))
return syscall.UTF16ToString(buf[:size])
}
func getCPUName() string {
out, err := exec.Command("powershell", "-NoProfile", "-Command",
"(Get-CimInstance Win32_Processor).Name").Output()
if err != nil {
return "Unknown CPU"
}
return strings.TrimSpace(string(out))
}
func getWindowsProductName() string {
out, err := exec.Command("powershell", "-NoProfile", "-Command",
"(Get-CimInstance Win32_OperatingSystem).Caption").Output()
if err != nil {
return "Windows"
}
return strings.TrimSpace(string(out))
}
func formatBytes(b uint64) string {
const (
KB = 1024
MB = KB * 1024
GB = MB * 1024
TB = GB * 1024
)
switch {
case b >= TB:
return fmt.Sprintf("%.1f TB", float64(b)/float64(TB))
case b >= GB:
return fmt.Sprintf("%.1f GB", float64(b)/float64(GB))
case b >= MB:
return fmt.Sprintf("%.1f MB", float64(b)/float64(MB))
case b >= KB:
return fmt.Sprintf("%.1f KB", float64(b)/float64(KB))
default:
return fmt.Sprintf("%d B", b)
}
}