2014-10-09 12 views
5

Sono interessato a ottenere tutti i piani di alimentazione che hai nel tuo computer utilizzando C#.Ottieni piani di risparmio energia/schemi in C# (utilizzando WinAPI)

Stavo pensando che potrebbe essere in grado di utilizzare la funzione API PowerEnumerate in qualche modo:

DWORD WINAPI PowerEnumerate(
    _In_opt_ HKEY RootPowerKey, 
    _In_opt_ const GUID *SchemeGuid, 
    _In_opt_ const GUID *SubGroupOfPowerSettingsGuid, 
    _In_  POWER_DATA_ACCESSOR AccessFlags, 
    _In_  ULONG Index, 
    _Out_opt_ UCHAR *Buffer, 
    _Inout_ DWORD *BufferSize 
); 

Ma non ho idea su come come io davvero non so C. Quindi .. Come può Mi piace, elencare attraverso tutti i piani energetici disponibili e crearne una lista. Poi voglio essere in grado di accedere a ciascun programma di gestione dell'energia e al loro "nome descrittivo".

Quindi .. Forse se qualcuno che è bravo a usare WinAPI di C# che vorrebbe aiutare, sarebbe bello - o se qualcuno ha una soluzione migliore. Ho davvero cercato di trovare una buona risposta a questo, ma sembra che non ce ne siano. Penso che questo aiuterebbe molte persone.

Qualcuno può aiutare con questo?

risposta

6

Questo dovrebbe farlo:

using System; 
using System.Linq; 
using System.Reflection; 
using System.Runtime.InteropServices; 
using System.Collections.Generic; 

public class Program 
{ 
    [DllImport("PowrProf.dll")] 
    public static extern UInt32 PowerEnumerate(IntPtr RootPowerKey, IntPtr SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, UInt32 AcessFlags, UInt32 Index, ref Guid Buffer, ref UInt32 BufferSize); 

    [DllImport("PowrProf.dll")] 
    public static extern UInt32 PowerReadFriendlyName(IntPtr RootPowerKey, ref Guid SchemeGuid, IntPtr SubGroupOfPowerSettingGuid, IntPtr PowerSettingGuid, IntPtr Buffer, ref UInt32 BufferSize); 

    public enum AccessFlags : uint 
    { 
     ACCESS_SCHEME = 16, 
     ACCESS_SUBGROUP = 17, 
     ACCESS_INDIVIDUAL_SETTING = 18 
    } 

    private static string ReadFriendlyName(Guid schemeGuid) 
    { 
     uint sizeName = 1024; 
     IntPtr pSizeName = Marshal.AllocHGlobal((int)sizeName); 

     string friendlyName; 

     try 
     { 
      PowerReadFriendlyName(IntPtr.Zero, ref schemeGuid, IntPtr.Zero, IntPtr.Zero, pSizeName, ref sizeName); 
      friendlyName = Marshal.PtrToStringUni(pSizeName); 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(pSizeName); 
     } 

     return friendlyName; 
    } 

    public static IEnumerable<Guid> GetAll() 
    { 
     var schemeGuid = Guid.Empty; 

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

     while (PowerEnumerate(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)AccessFlags.ACCESS_SCHEME, schemeIndex, ref schemeGuid, ref sizeSchemeGuid) == 0) 
     { 
      yield return schemeGuid; 
      schemeIndex++; 
     } 
    } 

    public static void Main() 
    { 
     var guidPlans = GetAll(); 

     foreach (Guid guidPlan in guidPlans) 
     { 
      Console.WriteLine(ReadFriendlyName(guidPlan)); 
     } 
    } 
} 

Potrebbe essere necessario eseguire questo programma come amministratore per motivi di sicurezza.

+0

Funziona proprio come volevo! Grazie mille!! Se hai tempo, sarebbe bello se potessi collegarti ad un tutorial in cui potrei imparare come fare questo genere di cose da solo. Ancora una volta, grazie! – CrashproofCode

+0

Blech ... usa C++/CLI invece di P/Invoke. A ciascuno il suo... –

Problemi correlati