-
Notifications
You must be signed in to change notification settings - Fork 1
/
wmi-query_windows.go
104 lines (91 loc) · 3.35 KB
/
wmi-query_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package main
import (
"fmt"
"log"
"os/exec"
"strings"
"syscall"
rl "github.com/gen2brain/raylib-go/raylib"
"github.com/yusufpapurcu/wmi"
)
type WmiMonitorID struct {
InstanceName string
}
type SimpleWmiMonitorBrightness struct {
InstanceName string
}
type WmiMonitorBrightness struct {
InstanceName string
CurrentBrightness int
}
func getMonitorInstanceName(deviceInstanceId string) (string, error) {
var monitors []WmiMonitorID
query := fmt.Sprintf(`SELECT InstanceName FROM WmiMonitorID WHERE InstanceName LIKE "DISPLAY\\%s\\%%"`, deviceInstanceId) // %% just mean a literal % ref. https://yourbasic.org/golang/fmt-printf-reference-cheat-sheet/
err := wmi.QueryNamespace(query, &monitors, "root\\wmi")
if err != nil {
return "", fmt.Errorf("error querying WMI: %v", err)
}
if len(monitors) != 1 {
return "", fmt.Errorf("cannot determine monitor")
}
return monitors[0].InstanceName, nil
}
// While WMIMonitorID may list all types of monitors, only WmiMonitorBrightness and WmiMonitorBrightnessMethods will the monitor it can control brightness via WMI.
// Usually this type of monitor is integrated laptop display
func isTypeWMIMonitor(monitorInstanceName string) (bool, error) {
var monitors []SimpleWmiMonitorBrightness
// DISPLAY\SHP1523\5&14db058f&2&UID512_0 needs to be changed to DISPLAY\\SHP1523\\5&14db058f&2&UID512_0
// pwsh> Get-WmiObject -Query "SELECT * FROM WmiMonitorBrightness" -Namespace root\wmi
query := fmt.Sprintf(`SELECT InstanceName FROM WmiMonitorBrightness WHERE InstanceName="%s"`, strings.ReplaceAll(monitorInstanceName, "\\", "\\\\"))
err := wmi.QueryNamespace(query, &monitors, "root\\wmi")
if err != nil {
return false, fmt.Errorf("error querying WMI: %v", err)
}
if len(monitors) == 1 {
return true, nil
} else {
return false, nil
}
}
// https://stackoverflow.com/a/62634211/7683365
// usually integrated laptop displays
type WMIMonitor struct {
name string
pos rl.Vector2
}
func (m WMIMonitor) getInstanceName() string {
return m.name
}
func (m WMIMonitor) getPosition() rl.Vector2 {
return m.pos
}
func (m WMIMonitor) getBrightness() (int, error) {
var monitors []WmiMonitorBrightness
// DISPLAY\SHP1523\5&14db058f&2&UID512_0 needs to be changed to DISPLAY\\SHP1523\\5&14db058f&2&UID512_0
query := fmt.Sprintf(`SELECT CurrentBrightness FROM WmiMonitorBrightness WHERE InstanceName="%s"`, strings.ReplaceAll(m.getInstanceName(), `\`, `\\`))
err := wmi.QueryNamespace(query, &monitors, "root\\wmi")
if err != nil {
return 0, fmt.Errorf("error querying WMI: %v", err)
}
if len(monitors) != 1 {
return 0, fmt.Errorf("monitor not found")
}
return monitors[0].CurrentBrightness, nil
}
// Ref.
// https://superuser.com/a/1781874
// I wanted to use this but I couldn't figure it out
// https://github.com/StackExchange/wmi/pull/45#issuecomment-590396746
func (m WMIMonitor) setBrightness(value int) {
// TODO wmic is deprecated, see https://stackoverflow.com/a/56350464
cmd := exec.Command("wmic", `/NAMESPACE:\\root\wmi`, "PATH", "WmiMonitorBrightnessMethods",
"WHERE", fmt.Sprintf("Active=TRUE AND InstanceName='%s'", strings.ReplaceAll(m.getInstanceName(), `\`, `\\`)),
"CALL", "WmiSetBrightness", fmt.Sprintf("Brightness=%d", value), "Timeout=0")
// don't flash the cmd prompt when running the cmd
cmd.SysProcAttr = &syscall.SysProcAttr{
HideWindow: true,
}
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}