helper.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. package smart
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "runtime"
  6. "strings"
  7. "imuslab.com/arozos/mod/info/logger"
  8. )
  9. func execCommand(executable string, args ...string) string {
  10. shell := exec.Command(executable, args...) // Run command
  11. output, err := shell.CombinedOutput() // Response from cmdline
  12. if err != nil && string(output) == "" { // If done w/ errors then
  13. logger.PrintAndLog("Smart", fmt.Sprint(err), nil)
  14. return ""
  15. }
  16. return string(output)
  17. }
  18. // wmicClassName maps classic `wmic` aliases to CIM / Win32 class names.
  19. func wmicClassName(wmicName string) string {
  20. if len(wmicName) > 6 && wmicName[0:6] == "Win32_" {
  21. return wmicName
  22. }
  23. switch strings.ToLower(wmicName) {
  24. case "cpu":
  25. return "Win32_Processor"
  26. case "os":
  27. return "Win32_OperatingSystem"
  28. case "computersystem":
  29. return "Win32_ComputerSystem"
  30. case "diskdrive":
  31. return "Win32_DiskDrive"
  32. case "nic":
  33. return "Win32_NetworkAdapter"
  34. case "logicaldisk":
  35. return "Win32_LogicalDisk"
  36. case "memorychip":
  37. return "Win32_PhysicalMemory"
  38. default:
  39. return "Win32_" + wmicName
  40. }
  41. }
  42. // cimGetinfo reads a WMI property via PowerShell Get-CimInstance.
  43. // Modern Windows 11 no longer ships `wmic.exe` by default.
  44. func cimGetinfo(wmicName string, itemName string) []string {
  45. className := wmicClassName(wmicName)
  46. psClass := strings.ReplaceAll(className, "'", "''")
  47. psItem := strings.ReplaceAll(itemName, "'", "''")
  48. script := fmt.Sprintf(
  49. "Get-CimInstance -ClassName '%s' | ForEach-Object { $p = $_.PSObject.Properties['%s']; if ($null -ne $p -and $null -ne $p.Value) { [string]$p.Value } }",
  50. psClass, psItem,
  51. )
  52. cmd := exec.Command("powershell.exe",
  53. "-NoProfile",
  54. "-NonInteractive",
  55. "-WindowStyle", "Hidden",
  56. "-ExecutionPolicy", "Bypass",
  57. "-Command", script,
  58. )
  59. out, err := cmd.CombinedOutput()
  60. if err != nil {
  61. return nil
  62. }
  63. var info []string
  64. for _, line := range strings.Split(string(out), "\n") {
  65. line = strings.TrimSpace(strings.ReplaceAll(line, "\r", ""))
  66. if line != "" {
  67. info = append(info, line)
  68. }
  69. }
  70. return info
  71. }
  72. func legacyWmicGetinfo(wmicName string, itemName string) []string {
  73. var info []string
  74. cmd := exec.Command("wmic", wmicName, "list", "full", "/format:list")
  75. if wmicName == "os" {
  76. cmd = exec.Command("wmic", wmicName, "get", "*", "/format:list")
  77. }
  78. if len(wmicName) > 6 && wmicName[0:6] == "Win32_" {
  79. cmd = exec.Command("wmic", "path", wmicName, "get", "*", "/format:list")
  80. }
  81. out, _ := cmd.CombinedOutput()
  82. for _, strConfig := range strings.Split(string(out), "\n") {
  83. if strings.Contains(strConfig, "=") {
  84. parts := strings.SplitN(strConfig, "=", 2)
  85. if parts[0] == itemName {
  86. info = append(info, strings.Replace(parts[1], "\r", "", -1))
  87. }
  88. }
  89. }
  90. return info
  91. }
  92. func wmicGetinfo(wmicName string, itemName string) []string {
  93. if runtime.GOOS == "windows" {
  94. if info := cimGetinfo(wmicName, itemName); len(info) > 0 {
  95. return info
  96. }
  97. if info := legacyWmicGetinfo(wmicName, itemName); len(info) > 0 {
  98. return info
  99. }
  100. }
  101. return []string{"Undefined"}
  102. }