-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBatteryLevelHelper.cs
131 lines (111 loc) · 3.85 KB
/
BatteryLevelHelper.cs
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Text.RegularExpressions;
namespace XboxWirelessControllerBatteryLevels;
static partial class BatteryLevelHelper
{
[GeneratedRegex("BATTERY_LEVEL=(\\d+)=END")]
private static partial Regex BatteryLevelRegex();
private const string Script = """
$values = Get-CimInstance -Query 'Select * From Win32_PnPEntity Where Name = "Xbox Wireless Controller"' |`
Invoke-CimMethod -MethodName GetDeviceProperties -Arguments @{devicePropertyKeys = '{104EA319-6EE2-4701-BD47-8DDBF425BBE5} 2', '{83DA6326-97A6-4088-9453-A1923F573B29} 15'} |`
Select-Object -ExpandProperty DeviceProperties |`
ForEach-Object { if ($_.Data) { $_.Data } else { $false } }
for ($i = 0; $i -lt $values.Count; $i += 2) {
$batteryLevel = $values[$i]
$connected = $values[$i + 1]
if ($connected) {
Write-Output "BATTERY_LEVEL=$batteryLevel=END"
}
}
""";
internal static List<int> GetBatteryLevels()
{
var result = ExecuteScript(Script);
if (BatteryLevelRegex().Matches(result) is not MatchCollection matches)
{
return new List<int>();
}
var results = new List<int>();
foreach (var m in matches)
{
if (m is not Match match)
{
continue;
}
var batteryLevel = int.Parse(match.Groups[1].Value);
results.Add(batteryLevel);
}
results.Sort();
return results;
}
internal static string ExecuteScript(string script)
{
using var process = new Process();
process.StartInfo = new ProcessStartInfo
{
FileName = "powershell.exe",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
};
process.Start();
process.StandardInput.WriteLine(Script);
process.StandardInput.Flush();
process.StandardInput.Close();
process.WaitForExit();
var errors = process.StandardError.ReadToEnd();
if (!string.IsNullOrWhiteSpace(errors))
{
throw new Exception(errors);
}
var result = process.StandardOutput.ReadToEnd();
return result;
}
internal static Icon GetIcon(int batteryLevel)
{
return GetIcon(new List<int> { batteryLevel });
}
internal static Icon GetIcon(List<int> batteryLevels)
{
int size = 16;
var image = new Bitmap(size, size);
using var graphics = Graphics.FromImage(image);
graphics.FillRectangle(
Brushes.Black,
new RectangleF(0, 0, size, size)
);
int index = 0;
foreach (int batteryLevel in batteryLevels)
{
var color = batteryLevel switch
{
< 15 => Color.Red,
< 25 => Color.Orange,
< 40 => Color.Yellow,
_ => Color.Green
};
int w = size / batteryLevels.Count;
int h = size * batteryLevel / 100;
// One pixel gap between each battery level.
int w2 = w - 1;
// The last battery level never fills the entire icon, adjust the width so it always fits.
if (
index == batteryLevels.Count - 1
)
{
w2 = size - index * w;
}
graphics.FillRectangle(
new SolidBrush(color),
new RectangleF(index * w, size - h, w2, h)
);
index++;
}
return Icon.FromHandle(image.GetHicon());
}
}