From 9e99357de2955d7b4f2285c1d323f1065976597c Mon Sep 17 00:00:00 2001 From: yyagi Date: Mon, 14 Mar 2016 17:33:32 +0000 Subject: [PATCH] =?utf8?q?#34825=20DTXMania=E3=81=AE=E5=8B=95=E4=BD=9C?= =?utf8?q?=E4=B8=AD=E3=81=AE=E3=81=BF=E3=80=81=E9=9B=BB=E6=BA=90=E3=83=97?= =?utf8?q?=E3=83=A9=E3=83=B3=E3=82=92=E9=AB=98=E3=83=91=E3=83=95=E3=82=A9?= =?utf8?q?=E3=83=BC=E3=83=9E=E3=83=B3=E3=82=B9(High=20Performance)?= =?utf8?q?=E3=81=AB=E5=A4=89=E6=9B=B4=E3=81=97=E3=80=81=E7=B5=82=E4=BA=86?= =?utf8?q?=E6=99=82=E3=81=AB=E5=85=83=E3=81=AB=E6=88=BB=E3=81=99=E6=A9=9F?= =?utf8?q?=E8=83=BD=E3=82=92=E8=BF=BD=E5=8A=A0=E3=80=82=20=E7=8F=BE?= =?utf8?q?=E6=99=82=E7=82=B9=E3=81=A7=E3=81=AF=E3=80=81=E3=81=93=E3=81=AE?= =?utf8?q?=E6=A9=9F=E8=83=BD=E3=82=92ON/OFF=E3=81=99=E3=82=8B=E8=A8=AD?= =?utf8?q?=E5=AE=9A=E6=A9=9F=E8=83=BD=E3=81=AF=E3=81=AA=E3=81=8F=E3=80=81?= =?utf8?q?=E5=BF=85=E3=81=9A=E9=AB=98=E3=83=91=E3=83=95=E3=82=A9=E3=83=BC?= =?utf8?q?=E3=83=9E=E3=83=B3=E3=82=B9=E3=81=AB=E5=A4=89=E6=9B=B4=E3=81=99?= =?utf8?q?=E3=82=8B=E3=80=82=20=E3=81=9F=E3=81=A0=E3=81=97=E3=80=81Connect?= =?utf8?q?ed=20Standby=E3=81=AB=E5=AF=BE=E5=BF=9C=E3=81=97=E3=81=A6?= =?utf8?q?=E3=81=84=E3=82=8B=E5=A0=B4=E5=90=88=E3=81=AF=E3=80=81=E3=81=93?= =?utf8?q?=E3=81=AE=E5=8B=95=E4=BD=9C=E3=82=92=E8=A1=8C=E3=82=8F=E3=81=AA?= =?utf8?q?=E3=81=84=E3=80=82=20Win8.1=20x64=20=E3=83=87=E3=82=B9=E3=82=AF?= =?utf8?q?=E3=83=88=E3=83=83=E3=83=97=E6=A9=9F(Connected=20Standby?= =?utf8?q?=E9=9D=9E=E5=AF=BE=E5=BF=9C)=E3=81=A8=E3=80=81Win10=20x86=20?= =?utf8?q?=E3=82=BF=E3=83=96=E3=83=AC=E3=83=83=E3=83=88=E6=A9=9F(Connected?= =?utf8?q?=20Standby=E5=AF=BE=E5=BF=9C)=E3=81=A7=E3=80=81=E5=8B=95?= =?utf8?q?=E4=BD=9C=E7=A2=BA=E8=AA=8D=E6=B8=88=E3=81=BF=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.osdn.jp/svnroot/dtxmania/trunk@927 16f42ceb-6dc6-49c8-ba94-f2d53467949d --- .../コード/全体/CDTXMania.cs | 11 +- FDK17プロジェクト/FDK19.csproj | 1 + FDK17プロジェクト/コード/00.共通/COS.cs | 25 +++ .../コード/00.共通/CPowerPlan.cs | 169 +++++++++++++++++++++ .../コード/00.共通/CWin32.cs | 138 ++++++++++++++++- 5 files changed, 341 insertions(+), 3 deletions(-) create mode 100644 FDK17プロジェクト/コード/00.共通/CPowerPlan.cs diff --git a/DTXManiaプロジェクト/コード/全体/CDTXMania.cs b/DTXManiaプロジェクト/コード/全体/CDTXMania.cs index 2fb6eb51..1a8262fb 100644 --- a/DTXManiaプロジェクト/コード/全体/CDTXMania.cs +++ b/DTXManiaプロジェクト/コード/全体/CDTXMania.cs @@ -343,7 +343,6 @@ namespace DTXMania //--------------------- #endregion - #region [ Input管理 の初期化 ] //--------------------- Trace.TraceInformation("DirectInput, MIDI入力の初期化を行います。"); @@ -888,6 +887,14 @@ namespace DTXMania st.plugin.OnManagedリソースの作成(); Directory.SetCurrentDirectory(CDTXMania.Instance.strEXEのあるフォルダ); } + + #region [ 現在の電源プランをバックアップし、HighPerformanceに変更 ] + cPowerPlan = new CPowerPlan(); + cPowerPlan.BackupCurrentPowerPlan(); + cPowerPlan.ChangeHighPerformance(); + #endregion + + #if GPUFlushAfterPresent FrameEnd += dtxmania_FrameEnd; #endif @@ -964,6 +971,7 @@ namespace DTXMania } protected override void OnExiting(EventArgs e) { + cPowerPlan.RestoreCurrentPowerPlan(); // 電源プランを元のものに戻す CPowerManagement.tEnableMonitorSuspend(); // スリープ抑止状態を解除 this.t終了処理(); base.OnExiting(e); @@ -2023,6 +2031,7 @@ namespace DTXMania } private CSound previewSound; private CCounter ccMouseShow; + private CPowerPlan cPowerPlan; public void ShowWindowTitleWithSoundType() diff --git a/FDK17プロジェクト/FDK19.csproj b/FDK17プロジェクト/FDK19.csproj index 50b278fa..420c406f 100644 --- a/FDK17プロジェクト/FDK19.csproj +++ b/FDK17プロジェクト/FDK19.csproj @@ -81,6 +81,7 @@ + diff --git a/FDK17プロジェクト/コード/00.共通/COS.cs b/FDK17プロジェクト/コード/00.共通/COS.cs index f30c355c..d8a6b2af 100644 --- a/FDK17プロジェクト/コード/00.共通/COS.cs +++ b/FDK17プロジェクト/コード/00.共通/COS.cs @@ -31,5 +31,30 @@ namespace FDK } } } + /// + /// OSがXP以前ならfalse, Vista以降ならtrueを返す + /// + /// + public static bool bIsWin8OrLater + { + get + { + //プラットフォームの取得 + System.OperatingSystem os = System.Environment.OSVersion; + if ( os.Platform != PlatformID.Win32NT ) // NT系でなければ、XP以前か、PC Windows系以外のOSのため、Vista以降ではない。よってfalseを返す。 + { + return false; + } + + if ( os.Version.Major >= 6 && os.Version.Minor >= 2 ) + { + return true; + } + else + { + return false; + } + } + } } } diff --git a/FDK17プロジェクト/コード/00.共通/CPowerPlan.cs b/FDK17プロジェクト/コード/00.共通/CPowerPlan.cs new file mode 100644 index 00000000..cb4b4c9b --- /dev/null +++ b/FDK17プロジェクト/コード/00.共通/CPowerPlan.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime.InteropServices; +using System.Diagnostics; + +namespace FDK +{ + /// + /// 電源プランの制御を行う + /// + public class CPowerPlan + { + // 参考: 電源プラン制御: http://www.fsmpi.uni-bayreuth.de/~dun3/archives/programmatically-change-power-options-using-cshar/519.html + // 参考: 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 + // http://stackoverflow.com/questions/20407094/c-sharp-how-to-use-callntpowerinformation-with-interop-to-get-system-power-infor + + readonly private Guid GuidHighPerformance = new Guid( "8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c" ); // Vista以降は全部これのはず + private Guid GuidCurrent; + private bool bConnectedStandbySupported = false; + + + + + public CPowerPlan() + { + GuidCurrent = System.Guid.Empty; + } + + + public void BackupCurrentPowerPlan() + { + bConnectedStandbySupported = IsConnetedStandbySupported(); + + if ( bConnectedStandbySupported ) + { + // 何もしない + } + else + { + GuidCurrent = GetActivePowerPlan(); + Trace.TraceInformation( "現在の電源プラン「{0}」をバックアップしました。", GetFriendlyName( GuidCurrent ) ); + } + } + + /// + /// Connected Standbyサポート機種かどうかの判定 + /// (Connected Standby機種に対しては、電源プラン操作を行わない) + /// + private static bool IsConnetedStandbySupported() + { + if ( !COS.bIsWin8OrLater ) + { + // Win8以前であれば、ConnectedStandby非サポートが確定 + return false; + } + else + { + CWin32.SYSTEM_POWER_CAPABILITIES cap; + uint retval = CWin32.CallNtPowerInformation( + (int) CWin32.POWER_INFORMATION_LEVEL.SystemPowerCapabilities, + IntPtr.Zero, + 0, + out cap, + Marshal.SizeOf( typeof( CWin32.SYSTEM_POWER_CAPABILITIES ) ) + ); + if ( retval == 0 ) + { + Debug.WriteLine( "SYSTEM_POWER_CAPABILITIES.AOAC: " + cap.AoAc ); + if ( cap.AoAc ) + { + Debug.WriteLine( "Connected Standby is enabled." ); + return true; + } + else + { + Debug.WriteLine( "Connected Standby is NOT enabled." ); + return false; + } + } + else + { + Debug.WriteLine( "CallNtPowerInformation returned: " + retval ); + //Debug.WriteLine( "Call to CallNTPowerInformation failed. GetLastError: %d\n", GetLastError() ); + return false; + } + } + } + + public void RestoreCurrentPowerPlan() + { + if ( bConnectedStandbySupported ) + { + // 何もしない + } + else + { + if ( GuidCurrent != System.Guid.Empty ) + { + SetActivePowerPlan( GuidCurrent ); + Trace.TraceInformation( "電源プランを、「{0}」に戻しました。", GetFriendlyName( GuidCurrent ) ); + GuidCurrent = System.Guid.Empty; + } + } + } + public void ChangeHighPerformance() + { + if ( bConnectedStandbySupported ) + { + Trace.TraceInformation( "ConnectedStandby対応機種のため、電源プランの変更を行いません。" ); + } + else + { + SetActivePowerPlan( GuidHighPerformance ); + Trace.TraceInformation( "電源プランを、「{0}」に変更しました。", GetFriendlyName( GuidHighPerformance ) ); + } + } + + + + private void SetActivePowerPlan( Guid powerSchemeId ) + { + var schemeGuid = powerSchemeId; + CWin32.PowerSetActiveScheme( IntPtr.Zero, ref schemeGuid ); + } + + private Guid GetActivePowerPlan() + { + IntPtr pCurrentSchemeGuid = IntPtr.Zero; + CWin32.PowerGetActiveScheme( IntPtr.Zero, ref pCurrentSchemeGuid ); + var currentSchemeGuid = (Guid) Marshal.PtrToStructure( pCurrentSchemeGuid, typeof( Guid ) ); + return currentSchemeGuid; + } + + + public IEnumerable FindAll() + { + var schemeGuid = Guid.Empty; + uint sizeSchemeGuid = (uint) Marshal.SizeOf( typeof( Guid ) ); + uint schemeIndex = 0; + while ( CWin32.PowerEnumerate( IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint) CWin32.AccessFlags.ACCESS_SCHEME, + schemeIndex, ref schemeGuid, ref sizeSchemeGuid ) == 0 ) + { + yield return schemeGuid; + schemeIndex++; + } + } + + private string GetFriendlyName( Guid schemeGuid ) + { + uint sizeName = 1024; + IntPtr pSizeName = Marshal.AllocHGlobal( (int) sizeName ); + string friendlyName; + + try + { + CWin32.PowerReadFriendlyName( IntPtr.Zero, ref schemeGuid, IntPtr.Zero, IntPtr.Zero, pSizeName, ref sizeName ); + friendlyName = Marshal.PtrToStringUni( pSizeName ); + } + finally + { + Marshal.FreeHGlobal( pSizeName ); + } + return friendlyName; + } + } +} diff --git a/FDK17プロジェクト/コード/00.共通/CWin32.cs b/FDK17プロジェクト/コード/00.共通/CWin32.cs index 08e64893..d87bd9c4 100644 --- a/FDK17プロジェクト/コード/00.共通/CWin32.cs +++ b/FDK17プロジェクト/コード/00.共通/CWin32.cs @@ -363,8 +363,8 @@ namespace FDK [return: MarshalAs( UnmanagedType.Bool )] [DllImport( "user32.dll", CharSet = CharSet.Auto )] public static extern bool PeekMessage( out WindowMessage message, IntPtr hwnd, uint messageFilterMin, uint messageFilterMax, uint flags ); - [DllImport( "kernel32.dll", CharSet = CharSet.Auto )] - public static extern uint SetThreadExecutionState( uint esFlags ); + //[DllImport( "kernel32.dll", CharSet = CharSet.Auto )] + //public static extern uint SetThreadExecutionState( uint esFlags ); [DllImport( "Kernel32.Dll" )] public static unsafe extern void CopyMemory( void* pDest, void* pSrc, uint numOfBytes ); @@ -386,6 +386,32 @@ namespace FDK public static extern void GetSystemInfo( ref SYSTEM_INFO ptmpsi ); [DllImport( "kernel32.dll" )] internal static extern ExecutionState SetThreadExecutionState( ExecutionState esFlags ); + + + [DllImport("PowrProf.dll")] + public static extern UInt32 PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, UInt32 AcessFlags, UInt32 Index, ref Guid Buffer, ref UInt32 BufferSize); + public enum AccessFlags : uint + { + ACCESS_SCHEME = 16, + ACCESS_SUBGROUP = 17, + ACCESS_INDIVIDUAL_SETTING = 18 + } + [DllImport( "PowrProf.dll" )] + public static extern UInt32 PowerReadFriendlyName( IntPtr RootPowerKey, ref Guid SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, IntPtr PowerSettingGuid, IntPtr Buffer, ref UInt32 BufferSize ); + [DllImport( "PowrProf.dll" )] + public static extern uint PowerGetActiveScheme( IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid ); + [DllImport( "PowrProf.dll" )] + public static extern uint PowerSetActiveScheme(IntPtr UserRootPowerKey, ref Guid SchemeGuid); + [DllImport( "powrprof.dll" )] + public static extern uint CallNtPowerInformation( + int InformationLevel, + IntPtr lpInputBuffer, + int nInputBufferSize, + out SYSTEM_POWER_CAPABILITIES spi, + int nOutputBufferSize + ); + + //----------------- #endregion @@ -486,6 +512,114 @@ namespace FDK public uint dwProcessorLevel; public uint dwProcessorRevision; } + public struct BATTERY_REPORTING_SCALE + { + public ulong Granularity; + public ulong Capacity; + } + public enum SYSTEM_POWER_STATE + { + PowerSystemUnspecified = 0, + PowerSystemWorking = 1, + PowerSystemSleeping1 = 2, + PowerSystemSleeping2 = 3, + PowerSystemSleeping3 = 4, + PowerSystemHibernate = 5, + PowerSystemShutdown = 6, + PowerSystemMaximum = 7 + } + public struct SYSTEM_POWER_INFORMATION + { + public uint MaxIdlenessAllowed; + public uint Idleness; + public uint TimeRemaining; + public byte CoolingMode; + } + public enum POWER_INFORMATION_LEVEL : int + { + AdministratorPowerPolicy = 9, + LastSleepTime1 = 5, + LastWakeTime = 14, + ProcessorInformation = 11, + ProcessorPowerPolicyAc = 18, + ProcessorPowerPolicyCurrent = 22, + ProcessorPowerPolicyDc = 19, + SystemBatteryState = 5, + SystemExecutionState = 16, + SystemPowerCapabilities = 4, + SystemPowerInformation = 12, + SystemPowerPolicyAc = 0, + SystemPowerPolicyCurrent = 8, + SystemPowerPolicyDc = 1, + SystemReserveHiberFile = 10, + VerifyProcessorPowerPolicyAc = 20, + VerifyProcessorPowerPolicyDc = 21, + VerifySystemPolicyAc = 2, + VerifySystemPolicyDc = 3 + } + + // http://www.pinvoke.net/default.aspx/Structures/SYSTEM_POWER_STATE.html + public struct SYSTEM_POWER_CAPABILITIES + { + [MarshalAs( UnmanagedType.U1 )] + public bool PowerButtonPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool SleepButtonPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool LidPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool SystemS1; + [MarshalAs( UnmanagedType.U1 )] + public bool SystemS2; + [MarshalAs( UnmanagedType.U1 )] + public bool SystemS3; + [MarshalAs( UnmanagedType.U1 )] + public bool SystemS4; + [MarshalAs( UnmanagedType.U1 )] + public bool SystemS5; + [MarshalAs( UnmanagedType.U1 )] + public bool HiberFilePresent; + [MarshalAs( UnmanagedType.U1 )] + public bool FullWake; + [MarshalAs( UnmanagedType.U1 )] + public bool VideoDimPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool ApmPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool UpsPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool ThermalControl; + [MarshalAs( UnmanagedType.U1 )] + public bool ProcessorThrottle; + public byte ProcessorMinThrottle; + public byte ProcessorMaxThrottle; // Also known as ProcessorThrottleScale before Windows XP + [MarshalAs( UnmanagedType.U1 )] + public bool FastSystemS4; // Ignore if earlier than Windows XP + [MarshalAs( UnmanagedType.U1 )] + public bool Hiberboot; // Ignore if earlier than Windows XP + [MarshalAs( UnmanagedType.U1 )] + public bool WakeAlarmPresent; // Ignore if earlier than Windows XP + [MarshalAs( UnmanagedType.U1 )] + public bool AoAc; // Ignore if earlier than Windows XP + [MarshalAs( UnmanagedType.U1 )] + public bool DiskSpinDown; + public byte HiberFileType; // Ignore if earlier than Windows 10 (10.0.10240.0) + [MarshalAs( UnmanagedType.U1 )] + public bool AoAcConnectivitySupported; // Ignore if earlier than Windows 10 (10.0.10240.0) + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 6 )] + private readonly byte[] spare3; + [MarshalAs( UnmanagedType.U1 )] + public bool SystemBatteriesPresent; + [MarshalAs( UnmanagedType.U1 )] + public bool BatteriesAreShortTerm; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 3 )] + public BATTERY_REPORTING_SCALE[] BatteryScale; + public SYSTEM_POWER_STATE AcOnLineWake; + public SYSTEM_POWER_STATE SoftLidWake; + public SYSTEM_POWER_STATE RtcWake; + public SYSTEM_POWER_STATE MinDeviceWakeState; + public SYSTEM_POWER_STATE DefaultLowLatencyWake; + } //----------------- #endregion -- 2.11.0