ProjectArcade

Форк
0
165 строк · 5.9 Кб
1
using System;
2
using System.Collections.Generic;
3
using System.Linq;
4
using System.Text;
5
using System.Runtime.InteropServices;
6

7
namespace EmulatorLauncher.Common
8
{
9
    public class HighPerformancePowerScheme : IDisposable
10
    {
11
        PowerScheme _oldPowerSheme;
12

13
        public HighPerformancePowerScheme()
14
        {
15
            try
16
            {
17
                var powerSchemes = HighPerformancePowerScheme.GetPowerSchemes();
18

19
                var oldPowerScheme = powerSchemes.FirstOrDefault(s => s.IsActive);
20
                var newPowerScheme = powerSchemes.FirstOrDefault(s => s.Guid == new Guid("8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c"));
21

22
                if (newPowerScheme != null && oldPowerScheme != null && oldPowerScheme != newPowerScheme)
23
                {
24
                    SetActivePowerScheme(newPowerScheme.Guid);
25
                    _oldPowerSheme = oldPowerScheme;
26
                }
27
            }
28
            catch { }
29
        }
30

31
        public void Dispose()
32
        {
33
            if (_oldPowerSheme != null)
34
            {
35
                SetActivePowerScheme(_oldPowerSheme.Guid);                
36
                _oldPowerSheme = null;
37
            }
38
        }
39
        
40
        class PowerScheme
41
        {
42
            public Guid Guid { get; private set; }
43
            public string Name { get; private set; }
44
            public bool IsActive { get; private set; }
45

46
            public PowerScheme(string name, Guid guid) : this(name, guid, false) { }
47

48
            public PowerScheme(string name, Guid guid, bool isActive)
49
            {
50
                this.Name = name;
51
                this.Guid = guid;
52
                this.IsActive = isActive;
53
            }
54

55
            public override string ToString()
56
            {
57
                return this.Name;
58
            }
59
        }
60

61
        static Guid GetActivePowerScheme()
62
        {
63
            Guid activeSchema = Guid.Empty;
64
            IntPtr guidPtr = IntPtr.Zero;
65

66
            try
67
            {
68
                var errCode = PowerGetActiveScheme(IntPtr.Zero, out guidPtr);
69

70
                if (errCode != 0) { throw new Exception("GetActiveGuid() failed with code " + errCode); }
71
                if (guidPtr == IntPtr.Zero) { throw new Exception("GetActiveGuid() returned null pointer for GUID"); }
72

73
                activeSchema = (Guid)Marshal.PtrToStructure(guidPtr, typeof(Guid));
74
            }
75
            finally
76
            {
77
                if (guidPtr != IntPtr.Zero) { LocalFree(guidPtr); }
78
            }
79

80
            return activeSchema;
81
        }
82

83
        static void SetActivePowerScheme(Guid guid)
84
        {
85
            var errCode = PowerSetActiveScheme(IntPtr.Zero, ref guid);
86
            if (errCode != 0) { throw new Exception("SetActiveGuid() failed with code " + errCode); }
87
        }
88

89
        private const int ERROR_NO_MORE_ITEMS = 259;
90

91
        static List<PowerScheme> GetPowerSchemes()
92
        {
93
            var activeGuid = GetActivePowerScheme();
94
            return GetPowerSchemesGuids().Select(guid => new PowerScheme(GetPowerPlanName(guid), guid, guid == activeGuid)).ToList();
95
        }
96

97
        static IEnumerable<Guid> GetPowerSchemesGuids()
98
        {
99
            var schemeGuid = Guid.Empty;
100

101
            uint sizeSchemeGuid = (uint)Marshal.SizeOf(typeof(Guid));
102
            uint schemeIndex = 0;
103

104
            while (true)
105
            {
106
                uint errCode = PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)AccessFlags.ACCESS_SCHEME, schemeIndex, ref schemeGuid, ref sizeSchemeGuid);
107
                if (errCode == ERROR_NO_MORE_ITEMS) { yield break; }
108
                if (errCode != 0) { throw new Exception("GetPowerSchemeGUIDs() failed when getting buffer pointer with code " + errCode); }
109

110
                yield return schemeGuid;
111
                schemeIndex++;
112
            }
113
        }
114

115
        static string GetPowerPlanName(Guid guid)
116
        {
117
            string name = string.Empty;
118

119
            IntPtr bufferPointer = IntPtr.Zero;
120
            uint bufferSize = 0;
121

122
            try
123
            {
124
                var errCode = PowerReadFriendlyName(IntPtr.Zero, ref guid, IntPtr.Zero, IntPtr.Zero, bufferPointer, ref bufferSize);
125
                if (errCode != 0) { throw new Exception("GetPowerPlanName() failed when getting buffer size with code " + errCode); }
126

127
                if (bufferSize <= 0) { return String.Empty; }
128
                bufferPointer = Marshal.AllocHGlobal((int)bufferSize);
129

130
                errCode = PowerReadFriendlyName(IntPtr.Zero, ref guid, IntPtr.Zero, IntPtr.Zero, bufferPointer, ref bufferSize);
131
                if (errCode != 0) { throw new Exception("GetPowerPlanName() failed when getting buffer pointer with code " + errCode); }
132

133
                name = Marshal.PtrToStringUni(bufferPointer);
134
            }
135
            finally
136
            {
137
                if (bufferPointer != IntPtr.Zero) { Marshal.FreeHGlobal(bufferPointer); }
138
            }
139

140
            return name;
141
        }
142

143
        [DllImport("kernel32.dll", SetLastError = true)]
144
        static extern IntPtr LocalFree(IntPtr hMem);
145

146
        [DllImport("powrprof.dll", EntryPoint = "PowerSetActiveScheme")]
147
        static extern uint PowerSetActiveScheme(IntPtr UserPowerKey, ref Guid ActivePolicyGuid);
148

149
        [DllImport("powrprof.dll", EntryPoint = "PowerGetActiveScheme")]
150
        static extern uint PowerGetActiveScheme(IntPtr UserPowerKey, out IntPtr ActivePolicyGuid);
151

152
        [DllImport("powrprof.dll", EntryPoint = "PowerReadFriendlyName")]
153
        static extern uint PowerReadFriendlyName(IntPtr RootPowerKey, ref Guid SchemeGuid, IntPtr SubGroupOfPowerSettingsGuid, IntPtr PowerSettingGuid, IntPtr BufferPtr, ref uint BufferSize);
154

155
        [DllImport("PowrProf.dll")]
156
        static extern UInt32 PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, UInt32 AcessFlags, UInt32 Index, ref Guid Buffer, ref UInt32 BufferSize);
157

158
        enum AccessFlags : uint
159
        {
160
            ACCESS_SCHEME = 16,
161
            ACCESS_SUBGROUP = 17,
162
            ACCESS_INDIVIDUAL_SETTING = 18
163
        }
164
    }
165
}
166

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.