2 using System.Collections.Generic;
5 using System.Threading.Tasks;
6 using System.Runtime.InteropServices;
7 using System.Diagnostics;
14 public static class CPowerPlan
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
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;
25 public static void BackupCurrentPowerPlan()
27 bConnectedStandbySupported = IsConnetedStandbySupported();
29 if ( bConnectedStandbySupported )
35 GuidBackup = GetActivePowerPlan();
36 Trace.TraceInformation( "現在の電源プラン「{0}」をバックアップしました。", GetFriendlyName( GuidBackup ) );
41 /// Connected Standbyサポート機種かどうかの判定
42 /// (Connected Standby機種に対しては、電源プラン操作を行わない)
44 private static bool IsConnetedStandbySupported()
46 if ( !COS.bIsWin8OrLater )
48 // Win8以前であれば、ConnectedStandby非サポートが確定
52 CWin32.SYSTEM_POWER_CAPABILITIES cap;
53 uint retval = CWin32.CallNtPowerInformation(
54 (int) CWin32.POWER_INFORMATION_LEVEL.SystemPowerCapabilities,
58 Marshal.SizeOf( typeof( CWin32.SYSTEM_POWER_CAPABILITIES ) )
62 //Debug.WriteLine( "SYSTEM_POWER_CAPABILITIES.AOAC: " + cap.AoAc );
65 //Debug.WriteLine( "Connected Standby is enabled." );
70 //Debug.WriteLine( "Connected Standby is NOT enabled." );
76 Debug.WriteLine( "CallNtPowerInformation returned: " + retval );
77 //Debug.WriteLine( "Call to CallNTPowerInformation failed. GetLastError: %d\n", GetLastError() );
82 public static void RestoreCurrentPowerPlan()
84 if ( bConnectedStandbySupported )
90 if ( GuidBackup != System.Guid.Empty )
92 SetActivePowerPlan( GuidBackup );
93 Trace.TraceInformation( "電源プランを、「{0}」に戻しました。", GetFriendlyName( GuidBackup ) );
94 GuidBackup = System.Guid.Empty;
98 public static void ChangeHighPerformance()
100 if ( bConnectedStandbySupported )
102 Trace.TraceInformation( "ConnectedStandby対応機種のため、電源プランの変更を行いません。" );
106 SetActivePowerPlan( GuidHighPerformance );
107 Trace.TraceInformation( "電源プランを、「{0}」に変更しました。", GetFriendlyName( GuidHighPerformance ) );
113 private static void SetActivePowerPlan( Guid powerSchemeId )
115 var schemeGuid = powerSchemeId;
116 CWin32.PowerSetActiveScheme( IntPtr.Zero, ref schemeGuid );
119 private static Guid GetActivePowerPlan()
121 IntPtr pCurrentSchemeGuid = IntPtr.Zero;
122 CWin32.PowerGetActiveScheme( IntPtr.Zero, ref pCurrentSchemeGuid );
123 var currentSchemeGuid = (Guid) Marshal.PtrToStructure( pCurrentSchemeGuid, typeof( Guid ) );
124 return currentSchemeGuid;
128 private static IEnumerable<Guid> FindAll()
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 )
136 yield return schemeGuid;
141 private static string GetFriendlyName( Guid schemeGuid )
143 uint sizeName = 1024;
144 IntPtr pSizeName = Marshal.AllocHGlobal( (int) sizeName );
149 CWin32.PowerReadFriendlyName( IntPtr.Zero, ref schemeGuid, IntPtr.Zero, IntPtr.Zero, pSizeName, ref sizeName );
150 friendlyName = Marshal.PtrToStringUni( pSizeName );
154 Marshal.FreeHGlobal( pSizeName );