源码开源-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

 

posted @ 2026-10-04 13:25  鑫_源  阅读(10)  评论(0)    收藏  举报