2013-04-15 45 views
3

我需要我的應用程序來讀取諸如關閉顯示器,進入睡眠或進入休眠狀態之前系統等待的時間。據我所知,我需要使用電源管理功能(http://msdn.microsoft.com/en-us/library/aa373163%28v=vs.85%29.aspx)特別是,它看起來像我需要使用PowerEnumerate方法(http://msdn.microsoft.com/en-us/library/aa372730%28v=vs.85%29.aspx)。如何使用電源管理功能(PowerEnuimerate)獲取電源設置

我真的很困惑如何做到這一點。首先,我在C#中做了這個,代碼看起來是C++。其次,C++代碼似乎並沒有真正告訴你如何專門閱讀我想要的不同時間。

請注意,我是Windows編程和C#的新手。我的大部分經驗都來自Java和Android。

感謝

回答

11

我發現了一個example on MSDN在VB中使用PowerEnumerate功能。

我已將示例轉換爲C#,並將友好名稱添加到循環中每個視頻設置的輸出中。您可以將GUID_VIDEO_SUBGROUP更改爲其他子組之一以查看其他設置。

using System; 
using System.ComponentModel; 
using System.Runtime.InteropServices; 
using System.Text; 

namespace TestProject 
{ 
    class PowerEnumerator 
    { 
     private static Guid NO_SUBGROUP_GUID = new Guid("fea3413e-7e05-4911-9a71-700331f1c294"); 
     private static Guid GUID_DISK_SUBGROUP = new Guid("0012ee47-9041-4b5d-9b77-535fba8b1442"); 
     private static Guid GUID_SYSTEM_BUTTON_SUBGROUP = new Guid("4f971e89-eebd-4455-a8de-9e59040e7347"); 
     private static Guid GUID_PROCESSOR_SETTINGS_SUBGROUP = new Guid("54533251-82be-4824-96c1-47b60b740d00"); 
     private static Guid GUID_VIDEO_SUBGROUP = new Guid("7516b95f-f776-4464-8c53-06167f40cc99"); 
     private static Guid GUID_BATTERY_SUBGROUP = new Guid("e73a048d-bf27-4f12-9731-8b2076e8891f"); 
     private static Guid GUID_SLEEP_SUBGROUP = new Guid("238C9FA8-0AAD-41ED-83F4-97BE242C8F20"); 
     private static Guid GUID_PCIEXPRESS_SETTINGS_SUBGROUP = new Guid("501a4d13-42af-4429-9fd1-a8218c268e20"); 

     [DllImport("powrprof.dll")] 
     static extern uint PowerEnumerate(
      IntPtr RootPowerKey, 
      IntPtr SchemeGuid, 
      ref Guid SubGroupOfPowerSetting, 
      uint AccessFlags, 
      uint Index, 
      ref Guid Buffer, 
      ref uint BufferSize); 

     [DllImport("powrprof.dll")] 
     static extern uint PowerGetActiveScheme(
      IntPtr UserRootPowerKey, 
      ref IntPtr ActivePolicyGuid); 

     [DllImport("powrprof.dll")] 
     static extern uint PowerReadACValue(
      IntPtr RootPowerKey, 
      IntPtr SchemeGuid, 
      IntPtr SubGroupOfPowerSettingGuid, 
      ref Guid PowerSettingGuid, 
      ref int Type, 
      ref IntPtr Buffer, 
      ref uint BufferSize 
      ); 

     [DllImport("powrprof.dll", CharSet = CharSet.Unicode)] 
     static extern uint PowerReadFriendlyName(
      IntPtr RootPowerKey, 
      IntPtr SchemeGuid, 
      IntPtr SubGroupOfPowerSettingGuid, 
      IntPtr PowerSettingGuid, 
      StringBuilder Buffer, 
      ref uint BufferSize 
      ); 

     [DllImport("kernel32.dll")] 
     static extern IntPtr LocalFree(
      IntPtr hMem 
      ); 

     private const uint ERROR_MORE_DATA = 234; 

     public static void GetCurrentPowerEnumerateVistaAPI() 
     { 
      IntPtr activeGuidPtr = IntPtr.Zero; 
      try 
      { 
       uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr); 
       if (res != 0) 
        throw new Win32Exception(); 

       //Get Friendly Name 
       uint buffSize = 0; 
       StringBuilder buffer = new StringBuilder(); 
       Guid subGroupGuid = Guid.Empty; 
       Guid powerSettingGuid = Guid.Empty; 
       res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr, 
        IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize); 

       if (res == ERROR_MORE_DATA) 
       { 
        buffer.Capacity = (int)buffSize; 
        res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr, 
         IntPtr.Zero, IntPtr.Zero, buffer, ref buffSize); 
       } 

       if (res != 0) 
        throw new Win32Exception(); 

       Console.WriteLine("ReadFriendlyName = " + 
        buffer.ToString()); 

       //Get the Power Settings 
       Guid VideoSettingGuid = Guid.Empty; 
       uint index = 0; 
       uint BufferSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Guid))); 

       while (
        PowerEnumerate(IntPtr.Zero, activeGuidPtr, ref GUID_VIDEO_SUBGROUP, 
        18, index, ref VideoSettingGuid, ref BufferSize) == 0) 
       { 
        uint size = 4; 
        IntPtr temp = IntPtr.Zero; 
        int type = 0; 
        res = PowerReadACValue(IntPtr.Zero, activeGuidPtr, IntPtr.Zero, 
         ref VideoSettingGuid, ref type, ref temp, ref size); 

        IntPtr pSubGroup = Marshal.AllocHGlobal(Marshal.SizeOf(GUID_VIDEO_SUBGROUP)); 
        Marshal.StructureToPtr(GUID_VIDEO_SUBGROUP, pSubGroup, false); 
        IntPtr pSetting = Marshal.AllocHGlobal(Marshal.SizeOf(VideoSettingGuid)); 
        Marshal.StructureToPtr(VideoSettingGuid, pSetting, false); 

        uint builderSize = 200; 
        StringBuilder builder = new StringBuilder((int)builderSize); 
        res = PowerReadFriendlyName(IntPtr.Zero, activeGuidPtr, 
         pSubGroup, pSetting, builder, ref builderSize); 
        Console.WriteLine(builder.ToString() + " = " + temp.ToString()); 

        index++; 
       } 
      } 
      finally 
      { 
       if (activeGuidPtr != IntPtr.Zero) 
       { 
        IntPtr res = LocalFree(activeGuidPtr); 
        if (res != IntPtr.Zero) 
         throw new Win32Exception(); 
       } 
      } 
     } 
    } 
} 

從該代碼輸出結果:

Power Settings

+0

哇!!!謝謝!!!!! –

+0

看起來我們正在使用一堆.dll。我在哪裏可以找到他們的文檔? –

+0

根據[MSDN'PowerEnumerate'頁面](http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa372730)powrprof.dll似乎包含在新版本的Windows(Vista&更新版本)中(v = vs.85).aspx)(見頁面底部)和kernel32.dll(LocalFree函數)自從至少XP以來一直是Windows的一部分:[MSDN上的LocalFree](http://msdn.microsoft.com/zh-cn/ com/en-us/library/windows/desktop/aa366730(v = vs.85).aspx) – endofzero