C# 如何使用CallNtPowerInformation获取LastSleepTime
我有一些代码,我将使用这些代码通过CallNtPowerInformation获取一些电源信息。目前,我在获得最后一次睡眠时间方面遇到了一些问题。有人能举例帮助吗C# 如何使用CallNtPowerInformation获取LastSleepTime,c#,winapi,C#,Winapi,我有一些代码,我将使用这些代码通过CallNtPowerInformation获取一些电源信息。目前,我在获得最后一次睡眠时间方面遇到了一些问题。有人能举例帮助吗 [DllImport("PowrProf.dll", SetLastError = true)] private static extern uint CallNtPowerInformation( POWER_INFORMATION_LEVEL InformationLevel, IntPt
[DllImport("PowrProf.dll", SetLastError = true)]
private static extern uint CallNtPowerInformation(
POWER_INFORMATION_LEVEL InformationLevel,
IntPtr lpInputBuffer,
int nInputBufferSize,
ref IntPtr lpOutputBuffer,
int nOutputBufferSize
);
public void GetPowerInfo(int pil)
{
IntPtr buff = new IntPtr();
var result = CallNtPowerInformation(
(POWER_INFORMATION_LEVEL) pil,
IntPtr.Zero,
0,
ref buff,
Marshal.SizeOf(pil)
);
if (result != 0) return;
var fields =
typeof( SYSTEM_BATTERY_STATE ).GetFields( BindingFlags.Public | BindingFlags.Instance );
foreach (var t in fields)
Debug.WriteLine(
"{0}: {1}",
t.Name,
t.GetValue( buff )
);
}
现在我得到错误代码0xc0000023状态\缓冲区\太小
实际上,您的代码在我看来有点奇怪,但是,如果您想获得最后一次睡眠时间,您应该使用大小适当的变量(在您的情况下是long,并带有适当的CallNtPowerInformation声明)或手动封送(参见下面的示例)
假设CallNtPowerInformation的声明如下:
[DllImport("PowrProf.dll", EntryPoint = "CallNtPowerInformation", ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)]
private static extern int CallNtPowerInformation(
PowerInformationLevel informationLevel,
[In]IntPtr lpInputBuffer,
uint nInputBufferSize,
[In, Out]IntPtr lpOutputBuffer,
uint nOutputBufferSize);
然后这样称呼它,例如:
public long GetLastSleepTime()
{
IntPtr lastSleep = IntPtr.Zero;
try
{
lastSleep = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(long)));
int ntStatus = CallNtPowerInformation(PowerInformationLevel.LastSleepTime, IntPtr.Zero, 0, lastSleep,
(uint)Marshal.SizeOf(typeof(long)));
if (ntStatus != 0)
return 0;
// receives a ULONGLONG that specifies the interrupt-time count, in 100-nanosecond units, at the last system sleep time
// there are 1e9 nanoseconds in a second, so there are 1e7 100 - nanoseconds in a second
long lastSleepTimeInSeconds = Marshal.ReadInt64(lastSleep, 0) / 10000000;
return lastSleepTimeInSeconds;
}
finally
{
if (lastSleep != IntPtr.Zero)
Marshal.FreeCoTaskMem(lastSleep);
}
}
lpOutputBuffer缓冲区接收ULONGLONG,因此大小必须为8字节。但是你用的是4字节size@RbMm您对
CallNtPowerInformation
的声明是什么?@jeroemostert对不起。我补充说it@user3525444-那又怎样?输出缓冲区的大小必须为8字节。但不是代码中的4。结果和状态\u缓冲区\u太小