源码开源-C#获取macbook电池数据
本文是代码实战,无废话。 用三个方法获取macOS电池数据。全是通过 微软跨平台开发Xamarin C#
通过macos的IOKit 获取电池的数据。C # 源码如下:
using System;
using System.Runtime.InteropServices;
using CoreFoundation;
using Foundation;
using ObjCRuntime;
namespace YuanMacLib
{
public static class BatteryInfoFromIOKit
{
[DllImport( "/System/Library/Frameworks/IOKit.framework/IOKit" )]
private static extern uint IOServiceGetMatchingService( uint masterPort, IntPtr matching);
[DllImport( "/System/Library/Frameworks/IOKit.framework/IOKit" )]
private static extern IntPtr IOServiceMatching( string name);
[DllImport( "/System/Library/Frameworks/IOKit.framework/IOKit" )]
private static extern IntPtr IORegistryEntryCreateCFProperty(
uint entry, IntPtr key, IntPtr allocator, uint options);
[DllImport( "/System/Library/Frameworks/IOKit.framework/IOKit" )]
private static extern int IOObjectRelease( uint obj);
///
/// 电池设计容量
///
///
public static int ? GetDesignCapacity()
{
const string kIOPlatformExpertDevice = "AppleSmartBattery" ; //"IOPlatformExpertDevice";
uint platformExpert = 0;
IntPtr property = IntPtr.Zero;
try
{
platformExpert = IOServiceGetMatchingService(0,
IOServiceMatching(kIOPlatformExpertDevice));
if (platformExpert == 0) return null ;
using ( var key = new NSString( "DesignCapacity" ))
{
property = IORegistryEntryCreateCFProperty(
platformExpert, key.Handle, IntPtr.Zero, 0);
}
if (property == IntPtr.Zero) return null ;
var nsNumber = Runtime.GetNSObject(property, true );
return nsNumber?.Int32Value;
}
finally
{
if (property != IntPtr.Zero)
property = IntPtr.Zero; //用这个代替,因为CFObject.Dispose(property); 没有dispose 在这个版本xamarin.Mac里
if (platformExpert != 0)
IOObjectRelease(platformExpert);
}
}
}
}
通过mac OS 类似windows注册表的IOReg中获取电池数据
using System;
using System.Diagnostics;
using System.Globalization;
namespace YuanMacLib
{
// 定义一个类来存储解析出的电池信息
public class BatteryData
{
public int? CycleCount { get; set; }
public int? FullChargeCapacity { get; set; }
public int? DesignCapacity { get; set; }
public int? MaxCapacity { get; set; }
public int? TimeToFullCharge { get; set; } // 单位:分钟
public int? AvgTimeToEmpty { get; set; } // 单位:分钟
// 计算电池健康度百分比
public double? HealthPercent =>
(DesignCapacity > 0 && FullChargeCapacity.HasValue)
? (double)FullChargeCapacity / DesignCapacity * 100
: null;
}
public static class BatteryInfoFromIOReg
{
public static BatteryData GetBatteryData()
{
var data = new BatteryData();
try
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "/usr/sbin/ioreg",
Arguments = "-r -c AppleSmartBattery -w 0",
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
foreach (var line in output.Split('\n'))
{
var trimmed = line.Trim();
// 解析 "CycleCount" = 318
if (trimmed.StartsWith("\"CycleCount\" =", StringComparison.Ordinal))
{
data.CycleCount = ParseIntValue(trimmed);
}
// 解析 "FullChargeCapacity" = 5524
else if (trimmed.StartsWith("\"FullChargeCapacity\" =", StringComparison.Ordinal))
{
data.FullChargeCapacity = ParseIntValue(trimmed);
}
// 解析 "DesignCapacity"
else if (trimmed.StartsWith("\"DesignCapacity\" =", StringComparison.Ordinal))
{
data.DesignCapacity = ParseIntValue(trimmed);
}
// 解析 "MaxCapacity"
else if (trimmed.StartsWith("\"MaxCapacity\" =", StringComparison.Ordinal))
{
data.MaxCapacity = ParseIntValue(trimmed);
}
// 解析 "TimeToFullCharge" (可能不存在,尝试 AvgTimeToFull)
else if (trimmed.StartsWith("\"TimeToFullCharge\" =", StringComparison.Ordinal))
{
data.TimeToFullCharge = ParseIntValue(trimmed);
}
// 解析 "AvgTimeToEmpty" (可能不存在)
else if (trimmed.StartsWith("\"AvgTimeToEmpty\" =", StringComparison.Ordinal))
{
data.AvgTimeToEmpty = ParseIntValue(trimmed);
}
}
}
catch (Exception ex)
{
Debug.WriteLine($"获取电池详细信息失败: {ex.Message}");
}
return data;
}
private static int? ParseIntValue(string line)
{
// 提取 = 号后的数值,并移除末尾的 ;
var parts = line.Split('=');
if (parts.Length < 2) return null;
var valueStr = parts[1].Trim().TrimEnd(';');
if (int.TryParse(valueStr, NumberStyles.Integer, CultureInfo.InvariantCulture, out int value))
return value;
return null;
}
}
}
/************************************************************************
*
*
* IOReg获取的电池相关,不同版本的macOS会有些不同
*
*
*
+-o AppleSmartBattery <class AppleSmartBattery, id 0x100000267, registered, matched, active, busy 0 (0 ms), retain 6>
{
"TimeRemaining" = 902
"AvgTimeToEmpty" = 902
"AdapterDetails" = {"SerialNumber"=0,"FamilyCode"=0,"AdapterID"=0,"AdapterRevision"=0}
"AppleRawCurrentCapacity" = 6273
"InstantTimeToEmpty" = 900
"AppleRawMaxCapacity" = 6856
"ExternalChargeCapable" = No
"FullPathUpdated" = 1790993303
"Voltage" = 12343
"PermanentFailureStatus" = 0
"BatteryInvalidWakeSeconds" = 30
"AdapterInfo" = 0
"MaxCapacity" = 6856
"DesignCycleCount70" = 65535
"UpdateTime" = 1790993423
"Manufacturer" = "SMP"
"AppleRawAdapterDetails" = ({"SerialNumber"=0,"FamilyCode"=0,"AdapterID"=0,"AdapterRevision"=0})
"Location" = 0
"CurrentCapacity" = 6273
"LegacyBatteryInfo" = {"Amperage"=18446744073709551199,"Flags"=4,"Capacity"=6856,"Current"=6273,"Voltage"=12343,"Cycle Count"=2}
"BatteryInstalled" = Yes
"FirmwareSerialNumber" = 8
"CycleCount" = 2
"ChargerData" = {"ChargingVoltage"=0,"ChargingCurrent"=0,"NotChargingReason"=1}
"AvgTimeToFull" = 65535
"BatteryData" = {"StateOfCharge"=91,"PMUConfigured"=0,"CellVoltage"=(4107,4113,4123),"LifetimeData"={"UpdateTime"=1790993423},"Serial"="C2243251I0XLY2D3R","SystemPower"=1318,"DesignCapacity"=6800,"CycleCount"=2,"Voltage"=12334,"Qmax"=(6780,6800,6790)}
"OperationStatus" = 58375
"PackReserve" = 167
"DesignCapacity" = 6800
"BootPathUpdated" = 1790990304
"PostDischargeWaitSeconds" = 120
"Serial" = "C2243251I0XLY2D3R"
"Temperature" = 2985
"UserVisiblePathUpdated" = 1790993423
"IOReportLegendPublic" = Yes
"InstantAmperage" = 18446744073709551199
"ManufacturerData" = <"2020-12-06">
"FullyCharged" = No
"MaxErr" = 2
"DeviceName" = "bq20z451"
"IOGeneralInterest" = "IOCommand is not serializable"
"IOReportLegend" = ({"IOReportChannels"=((7167869599145487988,6460407809,"BatteryCycleCount")),"IOReportGroupName"="Battery","IOReportChannelInfo"={"IOReportChannelUnit"=0}})
"Amperage" = 18446744073709551199
"IsCharging" = No
"DesignCycleCount9C" = 1000
"PostChargeWaitSeconds" = 120
"ExternalConnected" = No
}
*
*
*****************************************************************************/
通过Xamarin.Essential获取macOS 电池数据
using System;
using Xamarin.Essentials;
namespace YuanMacLib
{
public class BatteryInfoHelper
{
public static double GetBatteryPercent()
{
double level = Battery.ChargeLevel;
level = level * 100;
return level;
}
public static string getState()
{
// 根据状态执行逻辑
switch (Battery.State)
{
case BatteryState.Charging:
// 正在充电
return "充电中";//break;
case BatteryState.Full:
// 电池已满
return "电量已满"; //break;
case BatteryState.Discharging:
case BatteryState.NotCharging:
// 正在放电或未充电
return "正在放电或未充电"; //break;
case BatteryState.NotPresent:
// 设备无电池(如台式机)
return "本机无电池"; //break;
case BatteryState.Unknown:
// 无法检测状态
return "无法检测状态"; // break;
default:
return "状态未知";
}
}
public static string EnergySaverStatus()
{
return Battery.EnergySaverStatus.ToString();
}
/// <summary>
/// 内部demo
/// </summary>
private static void GetBatteryStatus()
{
// 1. 获取当前电量百分比 (0.0 到 1.0)
// 如果连接交流电或无电池,通常返回 1.0
double level = Battery.ChargeLevel;
// 2. 获取电池状态
BatteryState state = Battery.State;
// 3. 获取电源来源
BatteryPowerSource source = Battery.PowerSource;
// 输出调试信息
//($"电池电量: {level * 100}%"
//$"电池状态: {state}"
//$"电源来源: {source}"
// 根据状态执行逻辑
switch (state)
{
case BatteryState.Charging:
// 正在充电
break;
case BatteryState.Full:
// 电池已满
break;
case BatteryState.Discharging:
case BatteryState.NotCharging:
// 正在放电或未充电
break;
case BatteryState.NotPresent:
// 设备无电池(如台式机)
break;
case BatteryState.Unknown:
// 无法检测状态
break;
}
}
}
}
开发环境:Visual Studio 2019 for MAC 8.3.1 和 Xcode 11.2
系统是 macOS 11.7 Big Sur

浙公网安备 33010602011771号