C# PowerEnumerate PInvoke调整数组大小

C# PowerEnumerate PInvoke调整数组大小,c#,winapi,pinvoke,power-management,C#,Winapi,Pinvoke,Power Management,我试图编写一个C程序,通过调用枚举Windows电源管理方案,但在调试以下代码后,我注意到缓冲区的长度是1 uint length = 0; byte[] buffer = new byte[0]; Guid id = Guid.Empty; PowerEnumerate(IntPtr.Zero, ref id, ref id, 16, 0, ref buffer, ref length); buffer = new byte[length]; PowerEnumerate(IntPtr.Zer

我试图编写一个C程序,通过调用枚举Windows电源管理方案,但在调试以下代码后,我注意到
缓冲区的长度是
1

uint length = 0;
byte[] buffer = new byte[0];
Guid id = Guid.Empty;
PowerEnumerate(IntPtr.Zero, ref id, ref id, 16, 0, ref buffer, ref length);
buffer = new byte[length];
PowerEnumerate(IntPtr.Zero, ref id, ref id, 16, 0, ref buffer, ref bufferSize);
PowerEnumerate
声明如下:

[DllImport("powrprof.dll")]
public static extern UInt32 PowerEnumerate
(
    IntPtr RootPowerKey, 
    ref Guid SchemeGuid, 
    ref Guid SubGroupOfPowerSettingsGuid, 
    PowerDataAccessor AccessFlags,
    UInt32 Index, 
    ref Byte[] Buffer, 
    ref UInt32 BufferSize
);
PowerEnumerate
被调用两次。第一次获取所需的缓冲区长度。第二次实际读入缓冲区

调试时,我注意到第一次调用
PowerEnumerate
(第4行)将
长度设置为
16
(这很奇怪,因为我在调试的环境中有多个电源方案,而一个GUID是16字节,但这可能是另一回事),并将
缓冲区的大小调整为1字节

第二次实例化
buffer
后(第5行),其长度由第一次调用
PowerEnumerate
指定,
buffer
的长度为16字节。但是对
PowerEnumerate
(第6行)的第二次调用将
缓冲区的大小再次调整为1字节

我一遍又一遍地读我的代码,但我看不出任何错误,我的脑袋很快就没头发了


为什么我不能从上面的代码中得到预期的结果?声明有问题吗?

缓冲区
参数声明不正确。字节数组已经是一个引用,经过
ref
将使其成为双指针。应该是:

byte[] Buffer
在第一次调用时传递缓冲区参数的
null

看起来还应该为guid传递
NULL
。您可能需要将这些参数声明为
IntPtr
并传递
IntPtr.Zero

忽略返回值而忽略错误检查也是一个可怕的错误。你必须马上解决这个问题

我将使用以下声明:

[DllImport("powrprof.dll")]
public static extern uint PowerEnumerate
(
    IntPtr RootPowerKey,
    IntPtr SchemeGuid,
    IntPtr SubGroupOfPowerSettingsGuid,
    PowerDataAccessor AccessFlags,
    uint Index,
    byte[] Buffer,
    ref uint BufferSize
);

该死的,我从来没有正确的选择过这些职业,现在我因为忽略了回报值而感觉很糟糕。无论如何,这似乎是可行的(尽管仍然只枚举了一个GUID,但我将在稍后进行研究)。谢谢对于第二个问题(仅接收一个GUID):
PowerEnumerate
仅检索一个项—
索引
参数指定的项;一种常见的方法是使用
for
循环。此外,在枚举电源方案时(参数
AccessFlags
16
),最小缓冲区长度始终为16字节,因此不需要第一次调用
PowerEnumerate