C# PowerEnumerate PInvoke调整数组大小
我试图编写一个C程序,通过调用枚举Windows电源管理方案,但在调试以下代码后,我注意到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
缓冲区的长度是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
。