public static ExtendedBatteryInformation Get() { IntPtr deviceDataPointer = IntPtr.Zero; IntPtr queryInfoPointer = IntPtr.Zero; IntPtr batteryInfoPointer = IntPtr.Zero; IntPtr batteryWaitStatusPointer = IntPtr.Zero; IntPtr batteryStatusPointer = IntPtr.Zero; try { IntPtr deviceHandle = SetupDiGetClassDevs( Win32.GUID_DEVCLASS_BATTERY, Win32.DEVICE_GET_CLASS_FLAGS.DIGCF_PRESENT | Win32.DEVICE_GET_CLASS_FLAGS.DIGCF_DEVICEINTERFACE); Win32.SP_DEVICE_INTERFACE_DATA deviceInterfaceData = new Win32.SP_DEVICE_INTERFACE_DATA(); deviceInterfaceData.CbSize = Marshal.SizeOf(deviceInterfaceData); SetupDiEnumDeviceInterfaces(deviceHandle, Win32.GUID_DEVCLASS_BATTERY, 0, ref deviceInterfaceData); deviceDataPointer = Marshal.AllocHGlobal(Win32.DEVICE_INTERFACE_BUFFER_SIZE); //Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData = // (Win32.SP_DEVICE_INTERFACE_DETAIL_DATA)Marshal.PtrToStructure(deviceDataPointer, typeof(Win32.SP_DEVICE_INTERFACE_DETAIL_DATA)); //toggle these two and see if anything changes... ^^^^^^^^^^^^ Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData = new Win32.SP_DEVICE_INTERFACE_DETAIL_DATA(); deviceDetailData.CbSize = IntPtr.Size == 8 ? 8 : 4 + Marshal.SystemDefaultCharSize; SetupDiGetDeviceInterfaceDetail(deviceHandle, ref deviceInterfaceData, ref deviceDetailData, Win32.DEVICE_INTERFACE_BUFFER_SIZE); IntPtr batteryHandle = CreateFile(deviceDetailData.DevicePath, FileAccess.ReadWrite, FileShare.ReadWrite, FileMode.Open, Win32.FILE_ATTRIBUTES.Normal); Win32.BATTERY_QUERY_INFORMATION queryInformation = new Win32.BATTERY_QUERY_INFORMATION(); DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_TAG, ref queryInformation.BatteryTag); Win32.BATTERY_INFORMATION batteryInformation = new Win32.BATTERY_INFORMATION(); queryInformation.InformationLevel = Win32.BATTERY_QUERY_INFORMATION_LEVEL.BatteryInformation; int queryInfoSize = Marshal.SizeOf(queryInformation); int batteryInfoSize = Marshal.SizeOf(batteryInformation); queryInfoPointer = Marshal.AllocHGlobal(queryInfoSize); Marshal.StructureToPtr(queryInformation, queryInfoPointer, false); batteryInfoPointer = Marshal.AllocHGlobal(batteryInfoSize); Marshal.StructureToPtr(batteryInformation, batteryInfoPointer, false); DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_INFORMATION, queryInfoPointer, queryInfoSize, batteryInfoPointer, batteryInfoSize); Win32.BATTERY_INFORMATION updatedBatteryInformation = (Win32.BATTERY_INFORMATION)Marshal.PtrToStructure(batteryInfoPointer, typeof(Win32.BATTERY_INFORMATION)); Win32.BATTERY_WAIT_STATUS batteryWaitStatus = new Win32.BATTERY_WAIT_STATUS(); batteryWaitStatus.BatteryTag = queryInformation.BatteryTag; Win32.BATTERY_STATUS batteryStatus = new Win32.BATTERY_STATUS(); int waitStatusSize = Marshal.SizeOf(batteryWaitStatus); int batteryStatusSize = Marshal.SizeOf(batteryStatus); batteryWaitStatusPointer = Marshal.AllocHGlobal(waitStatusSize); Marshal.StructureToPtr(batteryWaitStatus, batteryWaitStatusPointer, false); batteryStatusPointer = Marshal.AllocHGlobal(batteryStatusSize); Marshal.StructureToPtr(batteryStatus, batteryStatusPointer, false); DeviceIoControl(batteryHandle, Win32.IOCTL_BATTERY_QUERY_STATUS, batteryWaitStatusPointer, waitStatusSize, batteryStatusPointer, batteryStatusSize); Win32.BATTERY_STATUS updatedStatus = (Win32.BATTERY_STATUS)Marshal.PtrToStructure(batteryStatusPointer, typeof(Win32.BATTERY_STATUS)); Win32.SetupDiDestroyDeviceInfoList(deviceHandle); return(new ExtendedBatteryInformation() { DesignedCapacity = updatedBatteryInformation.DesignedCapacity, FullChargeCapacity = updatedBatteryInformation.FullChargedCapacity, CycleCount = updatedBatteryInformation.CycleCount, PowerState = updatedStatus.PowerState, CurrentCapacity = updatedStatus.Capacity, Voltage = updatedStatus.Voltage, Rate = updatedStatus.Rate }); } finally { Marshal.FreeHGlobal(deviceDataPointer); Marshal.FreeHGlobal(queryInfoPointer); Marshal.FreeHGlobal(batteryInfoPointer); Marshal.FreeHGlobal(batteryStatusPointer); Marshal.FreeHGlobal(batteryWaitStatusPointer); } }
private static bool SetupDiGetDeviceInterfaceDetail( IntPtr deviceInfoSet, ref Win32.SP_DEVICE_INTERFACE_DATA deviceInterfaceData, ref Win32.SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData, int deviceInterfaceDetailSize) { //int tmpSize = Marshal.SizeOf(deviceInterfaceDetailData); uint reqSize; bool retval = Win32.SetupDiGetDeviceInterfaceDetail( deviceInfoSet, ref deviceInterfaceData, ref deviceInterfaceDetailData, (uint)deviceInterfaceDetailSize, out reqSize, IntPtr.Zero); if (!retval) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != 0) { throw Marshal.GetExceptionForHR(errorCode); } else { throw new Exception( "SetupDiGetDeviceInterfaceDetail call failed but Win32 didn't catch an error."); } } return(retval); }