none
如何在 C# 使用 PowerEnumerate function RRS feed

  • 問題

  • 請問各位高手,

    我想在 C# 使用 PowerEnumerate function, 但遇到了困難 ><

    PowerEnumerate function 在 MSDN 的說明在下面的網址:

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/power/base/powerenumerate.asp

    它的 Prototype 如下:

    DWORD
    PowerEnumerate (
        __in_opt HKEY RootPowerKey,
        __in_opt CONST GUID *SchemeGuid,
        __in_opt CONST GUID *SubGroupOfPowerSettingsGuid,
        __in POWER_DATA_ACCESSOR AccessFlags,
        __in ULONG Index,
        __out_bcount_opt(*BufferSize) UCHAR *Buffer,
        __inout DWORD *BufferSize
        );

    我想使用 DllImport 的方式, 程式如下:

    [DllImport("powrprof.dll")]
    private static extern UInt32 PowerEnumerate (
            IntPtr RootPowerKey,
            ref IntPtr SchemeGuid,
            ref IntPtr SubGroupOfPowerSettingsGuid,
            UInt16 AccessFlags,
            ulong Index,
            out IntPtr Buffer,
            ref IntPtr BufferSize
            );

    ulong SchemeIndex = 0;
    IntPtr BufferSize = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UInt32)));
    Marshal.WriteInt16(BufferSize, 16);
    IntPtr tmpGuid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));

    IntPtr guid1 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));
    IntPtr guid2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid)));

    UInt32 ret = PowerEnumerate(
        IntPtr.Zero,
        ref guid1,
        ref guid2,
        (UInt16)POWER_DATA_ACCESSOR.ACCESS_SCHEME,
        SchemeIndex,
        out tmpGuid,
        ref BufferSize);

     

    但執行都會遇到下面的錯誤訊息:

    A call to PInvoke function 'Main_UserControl::PowerEnumerate' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

    請問我應該如何修改我的程式呢?

    謝謝 ^_^

    2006年6月14日 上午 02:57

解答

  • 我目前沒遇到這情況, 你可以試試改 #define _WIN32_WINNT 的值看看

    還有確認一下 powrprof.lib 是不是 link 到 Vista SDK 裡的...而不是 link 到舊的 powrprof.lib

    我的程式在 Vista RTM 版本測試沒問題

    2006年11月23日 上午 01:56

所有回覆

  • Dear Erison:

    你的開發環境在Vista嗎?

    在XP裡的Powrprof.dll並沒有Export這個Function.

    2006年6月27日 下午 05:57
  • Dear Robert,

    對呀,我是在 Vista 上開發的,

    Vista 新的 Power Management 多了許多新的 API,

    就像是 PowerEnumerate 這個 Function。

    因為一直無法轉到 C# 上面,網路上也找不到解答,所以想來請教一下大家 ^_^

    我目前做法是用 C++ 做 DLL 給 C# 用,雖然可以跑但感覺就多了一層,似乎比較不好。

    2006年6月29日 上午 02:51
  • 你好,能讲一下c++里面怎么使用powerenumerate么?里面的index怎么控制循环呢?能给出程式范例嘛?
    2006年11月21日 上午 09:54
  • GUID SchemeGuid;
    ULONG index = 0;
    DWORD BufferSize = sizeof(GUID);
    PUCHAR pDataBuf = NULL;
    DWORD dwSize = 0;

    while(ERROR_SUCCESS == PowerEnumerate(NULL, NULL, NULL, ACCESS_SCHEME, index, (PUCHAR)&SchemeGuid, &BufferSize))
    {
        PowerReadFriendlyName(NULL, (GUID*)&SchemeGuid, NULL, NULL, (PUCHAR)pDataBuf, &dwSize);
      
        index++;
    }

    2006年11月21日 上午 11:14
  • 谢谢,请问您有没有碰到这种情况,使用函数编译时提示说PowerSetActiveScheme 未找到标识符,我不清楚是不是新的powrprof.h中
    PowerSetActiveScheme是放在
    #if(NTDDI_VERSION>=NTDDI_LONGHORN)
    的原因,我的时vista的rtm版本
    2006年11月22日 上午 02:29
  • 我目前沒遇到這情況, 你可以試試改 #define _WIN32_WINNT 的值看看

    還有確認一下 powrprof.lib 是不是 link 到 Vista SDK 裡的...而不是 link 到舊的 powrprof.lib

    我的程式在 Vista RTM 版本測試沒問題

    2006年11月23日 上午 01:56
  • ok了,谢谢
    2006年11月23日 上午 10:53
  • 我最近剛好也有一樣的需求,目前網路上還是沒有多少關於 Vista Power Management API 的 sample 可以參考。

     

    容我不要臉的分享一下我目前的用法~

     

    DllImport 宣告的部分:

     

    [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);

     

    實際使用的程式碼:

     

    {

                Guid   Buffer = new Guid();
                UInt32 SchemeIndex = 0;
                UInt32 BufferSize = (UInt32)Marshal.SizeOf(typeof(Guid));

     

                while (0 == PowerEnumerate(
                    IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 16, SchemeIndex, ref Buffer, ref BufferSize))
                {
                    Console.Write(Buffer.ToString() + ": ");

     

                    UInt32 name_size = 1024;
                    IntPtr temp = Marshal.AllocHGlobal(1024);

     

                    PowerReadFriendlyName(
                        IntPtr.Zero, ref Buffer, IntPtr.Zero, IntPtr.Zero, temp, ref name_size);

     

                    Console.Writeline(Marshal.PtrToStringUni(temp));

     

                    Marshal.FreeHGlobal(temp);

     

                    SchemeIndex++;
                }

    }

     

    希望對需要的人有幫助。

    2007年8月14日 上午 03:21