-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNativeProcessPolicy.cs
More file actions
168 lines (146 loc) · 5.78 KB
/
Copy pathNativeProcessPolicy.cs
File metadata and controls
168 lines (146 loc) · 5.78 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace CodexProcessKeeper;
internal sealed record NativePolicyResult(
bool Success,
string PriorityLabel,
bool EfficiencyModeOff,
int ErrorCode,
string Message);
internal static class NativeProcessPolicy
{
private const uint ProcessSetInformation = 0x0200;
private const uint ProcessQueryLimitedInformation = 0x1000;
private const uint HighPriorityClass = 0x00000080;
private const uint AboveNormalPriorityClass = 0x00008000;
private const uint NormalPriorityClass = 0x00000020;
private const uint BelowNormalPriorityClass = 0x00004000;
private const uint IdlePriorityClass = 0x00000040;
private const uint RealtimePriorityClass = 0x00000100;
private const int ProcessPowerThrottling = 4;
private const uint PowerThrottlingVersion = 1;
private const uint PowerThrottlingExecutionSpeed = 0x1;
private const uint PowerThrottlingIgnoreTimerResolution = 0x4;
[StructLayout(LayoutKind.Sequential)]
private struct PowerThrottlingState
{
internal uint Version;
internal uint ControlMask;
internal uint StateMask;
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern nint OpenProcess(uint desiredAccess, bool inheritHandle, int processId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(nint handle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetPriorityClass(nint processHandle, uint priorityClass);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern uint GetPriorityClass(nint processHandle);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetProcessInformation(
nint processHandle,
int informationClass,
ref PowerThrottlingState processInformation,
uint processInformationSize);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetProcessInformation(
nint processHandle,
int informationClass,
ref PowerThrottlingState processInformation,
uint processInformationSize);
internal static NativePolicyResult Apply(int processId)
{
nint processHandle = OpenProcess(
ProcessSetInformation | ProcessQueryLimitedInformation,
false,
processId);
if (processHandle == nint.Zero)
{
int errorCode = Marshal.GetLastWin32Error();
return Failure(errorCode, "无法打开进程");
}
try
{
if (!SetPriorityClass(processHandle, HighPriorityClass))
{
int errorCode = Marshal.GetLastWin32Error();
return Failure(errorCode, "无法设置高优先级");
}
PowerThrottlingState disabledState = new()
{
Version = PowerThrottlingVersion,
ControlMask = PowerThrottlingExecutionSpeed | PowerThrottlingIgnoreTimerResolution,
StateMask = 0
};
uint stateSize = (uint)Marshal.SizeOf<PowerThrottlingState>();
if (!SetProcessInformation(
processHandle,
ProcessPowerThrottling,
ref disabledState,
stateSize))
{
int errorCode = Marshal.GetLastWin32Error();
return Failure(errorCode, "无法关闭效率模式");
}
uint priorityClass = GetPriorityClass(processHandle);
if (priorityClass == 0)
{
int errorCode = Marshal.GetLastWin32Error();
return Failure(errorCode, "无法核验进程优先级");
}
PowerThrottlingState verifiedState = new() { Version = PowerThrottlingVersion };
if (!GetProcessInformation(
processHandle,
ProcessPowerThrottling,
ref verifiedState,
stateSize))
{
int errorCode = Marshal.GetLastWin32Error();
return Failure(errorCode, "无法核验效率模式");
}
bool priorityIsHigh = priorityClass == HighPriorityClass;
bool efficiencyModeOff =
(verifiedState.StateMask & PowerThrottlingExecutionSpeed) == 0;
bool success = priorityIsHigh && efficiencyModeOff;
return new NativePolicyResult(
success,
GetPriorityLabel(priorityClass),
efficiencyModeOff,
0,
success ? "正常" : "策略核验未通过");
}
finally
{
CloseHandle(processHandle);
}
}
private static NativePolicyResult Failure(int errorCode, string action)
{
string errorMessage = errorCode == 5
? "权限不足,请以管理员身份运行守护器"
: new Win32Exception(errorCode).Message;
return new NativePolicyResult(
false,
"未知",
false,
errorCode,
$"{action}:{errorMessage}");
}
private static string GetPriorityLabel(uint priorityClass)
{
return priorityClass switch
{
RealtimePriorityClass => "实时",
HighPriorityClass => "高",
AboveNormalPriorityClass => "高于正常",
NormalPriorityClass => "正常",
BelowNormalPriorityClass => "低于正常",
IdlePriorityClass => "低",
_ => $"0x{priorityClass:X}"
};
}
}