OSDN Git Service

1e09bddd207fe396ab10c88ffacf79b6ec3884a3
[dtxmania/dtxmania.git] / FDK / コード / 00.共通 / CPowerPlan.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Runtime.InteropServices;
7 using System.Diagnostics;
8
9 namespace FDK
10 {
11         /// <summary>
12         /// 電源プランの制御を行う
13         /// </summary>
14         public static class CPowerPlan
15         {
16                 // 参考: 電源プラン制御: http://www.fsmpi.uni-bayreuth.de/~dun3/archives/programmatically-change-power-options-using-cshar/519.html
17                 // 参考: ConnectedStandby判別: https://social.msdn.microsoft.com/Forums/en-US/eeb164a3-8ceb-4eb2-8768-4faaa7218c59/how-to-experimentally-confirm-that-connected-standby-mode-is-enabled-on-a-computer-system?forum=tailoringappsfordevices
18                 //                             http://stackoverflow.com/questions/20407094/c-sharp-how-to-use-callntpowerinformation-with-interop-to-get-system-power-infor
19
20                 readonly private static Guid GuidHighPerformance = new Guid( "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c" );          // Vista以降は全部これのはず
21                 private static Guid GuidBackup = Guid.Empty;
22                 private static bool bConnectedStandbySupported = false;
23
24
25                 public static void BackupCurrentPowerPlan()
26                 {
27                         bConnectedStandbySupported = IsConnetedStandbySupported();
28                         
29                         if ( bConnectedStandbySupported )
30                         {
31                                 // 何もしない
32                         }
33                         else
34                         {
35                                 GuidBackup = GetActivePowerPlan();
36                                 Trace.TraceInformation( "現在の電源プラン「{0}」をバックアップしました。", GetFriendlyName( GuidBackup ) );
37                         }
38                 }
39
40                 /// <summary>
41                 /// Connected Standbyサポート機種かどうかの判定
42                 /// (Connected Standby機種に対しては、電源プラン操作を行わない)
43                 /// </summary>
44                 private static bool IsConnetedStandbySupported()
45                 {
46                         if ( !COS.bIsWin8OrLater )
47                         {
48                                 // Win8以前であれば、ConnectedStandby非サポートが確定
49                                 return false;
50                         }
51
52                         CWin32.SYSTEM_POWER_CAPABILITIES cap;
53                         uint retval = CWin32.CallNtPowerInformation(
54                                 (int) CWin32.POWER_INFORMATION_LEVEL.SystemPowerCapabilities,
55                                 IntPtr.Zero,
56                                 0,
57                                 out cap,
58                                 Marshal.SizeOf( typeof( CWin32.SYSTEM_POWER_CAPABILITIES ) )
59                         );
60                         if ( retval == 0 )
61                         {
62                                 //Debug.WriteLine( "SYSTEM_POWER_CAPABILITIES.AOAC: " + cap.AoAc );
63                                 if ( cap.AoAc )
64                                 {
65                                         //Debug.WriteLine( "Connected Standby is enabled." );
66                                         return true;
67                                 }
68                                 else
69                                 {
70                                         //Debug.WriteLine( "Connected Standby is NOT enabled." );
71                                         return false;
72                                 }
73                         }
74                         else
75                         {
76                                 Debug.WriteLine( "CallNtPowerInformation returned: " + retval );
77                                 //Debug.WriteLine( "Call to CallNTPowerInformation failed. GetLastError: %d\n", GetLastError() );
78                                 return false;
79                         }
80                 }
81
82                 public static void RestoreCurrentPowerPlan()
83                 {
84                         if ( bConnectedStandbySupported )
85                         {
86                                 // 何もしない
87                         }
88                         else
89                         {
90                                 if ( GuidBackup != System.Guid.Empty )
91                                 {
92                                         SetActivePowerPlan( GuidBackup );
93                                         Trace.TraceInformation( "電源プランを、「{0}」に戻しました。", GetFriendlyName( GuidBackup ) );
94                                         GuidBackup = System.Guid.Empty;
95                                 }
96                         }
97                 }
98                 public static void ChangeHighPerformance()
99                 {
100                         if ( bConnectedStandbySupported )
101                         {
102                                 Trace.TraceInformation( "ConnectedStandby対応機種のため、電源プランの変更を行いません。" );
103                         }
104                         else
105                         {
106                                 SetActivePowerPlan( GuidHighPerformance );
107                                 Trace.TraceInformation( "電源プランを、「{0}」に変更しました。", GetFriendlyName( GuidHighPerformance ) );
108                         }
109                 }
110
111
112
113                 private static void SetActivePowerPlan( Guid powerSchemeId )
114                 {
115                         var schemeGuid = powerSchemeId;
116                         CWin32.PowerSetActiveScheme( IntPtr.Zero, ref schemeGuid );
117                 }
118
119                 private static Guid GetActivePowerPlan()
120                 {
121                         IntPtr pCurrentSchemeGuid = IntPtr.Zero;
122                         CWin32.PowerGetActiveScheme( IntPtr.Zero, ref pCurrentSchemeGuid );
123                         var currentSchemeGuid = (Guid) Marshal.PtrToStructure( pCurrentSchemeGuid, typeof( Guid ) );
124                         return currentSchemeGuid;
125                 }
126
127
128                 private static IEnumerable<Guid> FindAll()
129                 {
130                         var schemeGuid = Guid.Empty;
131                         uint sizeSchemeGuid = (uint) Marshal.SizeOf( typeof( Guid ) );
132                         uint schemeIndex = 0;
133                         while ( CWin32.PowerEnumerate( IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint) CWin32.AccessFlags.ACCESS_SCHEME,
134                                 schemeIndex, ref schemeGuid, ref sizeSchemeGuid ) == 0 )
135                         {
136                                 yield return schemeGuid;
137                                 schemeIndex++;
138                         }
139                 }
140
141                 private static string GetFriendlyName( Guid schemeGuid )
142                 {
143                         uint sizeName = 1024;
144                         IntPtr pSizeName = Marshal.AllocHGlobal( (int) sizeName );
145                         string friendlyName;
146
147                         try
148                         {
149                                 CWin32.PowerReadFriendlyName( IntPtr.Zero, ref schemeGuid, IntPtr.Zero, IntPtr.Zero, pSizeName, ref sizeName );
150                                 friendlyName = Marshal.PtrToStringUni( pSizeName );
151                         }
152                         finally
153                         {
154                                 Marshal.FreeHGlobal( pSizeName );
155                         }
156                         return friendlyName;
157                 }
158         }
159 }