创建一个ChargeInhibit断言(OS X 10.6.8) [英] Creating a ChargeInhibit Assertion (OS X 10.6.8)

查看:149
本文介绍了创建一个ChargeInhibit断言(OS X 10.6.8)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

平台(OS X 10.6.8)- [Macbook Pro-这很重要,因为我想处理电池处理-不适用于台式机]

Platform (OS X 10.6.8) - [Macbook Pro - this is important as I want to deal with the battery handling - not applicable for a desktop]

如果我犯了一个我看不到的基本错误,请原谅我,因为我已经五年没有写过任何C/C ++了,而且我还没有完全遵循Apple API希望您采用的方式与他们打交道,这就是我的问题.基本上,我希望能够根据命令禁止使用AC适配器充电,以便我可以选择在笔记本计算机使用和插入时是否对笔记本计算机进行充电.我找不到能够执行此操作的任何实用程序这样,所以我起初将其写为硬件级别上的内容,无法从软件上进行更改,但是后来我遇到了令人鼓舞的内容:

Forgive me if I've made a basic mistake that I don't see, as I haven't written any C/C++ in five years or more, and I'm not fully following the way apple APIs want you to deal with them, so this is what my question regards. Basically, I want to be able to inhibit charging from the AC adaptor at my command, so that I can choose whether to charge my laptop or not while it's in use and plugged in. I hadn't been able to find any utilities that do this, so I had at first written it off as something that was on the hardware level and couldn't be changed from software, but then I ran across something encouraging:

如果打开终端"窗口并运行

If you open a Terminal window and run

pmset -g assertionslog

您将获得一个断言列表,每个断言都为0或1,指示某个进程是否已断言该断言.其中第一个标题为ChargeInhibit,经过一番挖掘,我发现它恰好在软件级别上实现了我想要的功能.我只需要弄清楚如何声明它即可.

you get a list of assertions, and a 0 or 1 for each, indicating if some process has asserted that assertion. The first of them is titled ChargeInhibit, and I discovered after some digging that this does exactly what I want, at the software level. I just have to figure out how to assert it.

我从苹果源档案中一个名为 SetActive.c(链接)我将sendSmartBatteryCommand函数复制到了我的XCode项目中,并花了一些时间链接其他头文件并复制定义,直到可以正确编译它为止.这是复制的函数:

I copied some code from a file in the apple source archive called SetActive.c (link) I copied the function sendSmartBatteryCommand into my XCode project, and spent time linking other headers and copying over definitions until I could get it to compile correctly. Here is the copied function:

// The copied function, 
// modified very slightly:
// to return a success/fail value instead of void

kern_return_t sendSmartBatteryCommand(uint32_t which, uint32_t level)
{

    io_service_t    sbmanager = MACH_PORT_NULL;
    io_connect_t    sbconnection = MACH_PORT_NULL;
    kern_return_t   kret = 99;
    uint32_t        output_count = 1;
    uint64_t        uc_return = kIOReturnError;
    uint64_t        level_64 = level;

    // Find SmartBattery manager
    sbmanager = IOServiceGetMatchingService(MACH_PORT_NULL,
                                            IOServiceMatching("AppleSmartBatteryManager"));

    if(MACH_PORT_NULL == sbmanager) {

        goto bail;
    }

    kret = IOServiceOpen( sbmanager, mach_task_self(), 0, &sbconnection);
    if(kIOReturnSuccess != kret) {
        goto bail;
    }

    kret = IOConnectCallMethod(
                               sbconnection, // connection
                               which,      // selector
                               &level_64,  // uint64_t *input
                               1,          // input Count
                               NULL,       // input struct count
                               0,          // input struct count
                               &uc_return, // output
                               &output_count,  // output count
                               NULL,       // output struct
                               0);         // output struct count

bail:

    if (MACH_PORT_NULL != sbconnection) {
        IOServiceClose(sbconnection);
    }

    if (MACH_PORT_NULL != sbmanager) {
        IOObjectRelease(sbmanager);
    }

    return kret;
}

当我尝试使用成功值发送用于禁止充电和禁止流入的断言时,我会获得成功值,但是pmset的日志没有显示任何更改,并且电池充电/不充电的实际状态也没有

I get success values back when I try to use it to send assertions for charge inhibiting and inflow disabling, but the log from pmset doesn't show any changes, and neither does the actual state of my battery charging / not-charging.

我还尝试过修改服务名称,以从"AppleSmartBatteryManager"查找为一个废话,只是为了查看该函数是否返回失败,并且确实如此,这表明我正在连接到真实的服务.

I've also tried modifying the name of the service to look for from "AppleSmartBatteryManager" to a nonsense word just to see if the function returns failure, and it does, so that indicates I'm connecting to a real service.

关于如何尽可能简单地实现这一目标的任何提示?

Any tips on how I can achieve this as simply as possible?

顺便说一句,我试图从Apple源站点上的源包中重新编译PowerManagement项目中的AppleSmartBatteryManager,但是在XCode中我遇到的错误更多.我正在尝试以某种不会与我自己的项目一起重新编译AppleSmartBatteryManager源的方式与现有服务进行交互.

By the way, I've tried to recompile the AppleSmartBatteryManager in the PowerManagement project from the source package on the apple source site, but I way more errors in XCode than I can deal with. I'm looking to try to interact with the existing service in some way that does not make me recompile the AppleSmartBatteryManager source alongside my own project.

顺便说一下,这是我调用函数的一个示例:

By the way, this is an example of me calling the function:

int CInh()
{
    kern_return_t kret = sendSmartBatteryCommand( kSBUCChargeInhibit, 255);  // zero:uninhibit, non-zero:inhibit

    if(kret == KERN_SUCCESS)
        return 1;
    else
        return 0;
}

在我的头文件(也从SetActive.c复制)中的枚举中定义了哪个"参数的选项:

Where options for the "which" parameter are defined in an enum in my header file (also copied from SetActive.c):

enum {
    kSBUCInflowDisable = 0,
    kSBUCChargeInhibit = 1
};

推荐答案

我首先没有运气就尝试了同样的事情,然后发现"pmset noidle". ( pmset.c )这引起了一个断言,只是不正确的断言.看一下功能prevent_idle_sleep.

I first tried the same thing with no luck, then i found "pmset noidle." (pmset.c) This raises an assertion, just not the right one. Look at the function prevent_idle_sleep.

更改此:

IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
                    kIOPMAssertionLevelOn,
                    CFSTR("pmset prevent sleep"),
                    &neverSleep))

收件人:

IOPMAssertionCreateWithName(kIOPMAssertionTypeInhibitCharging,
                    kIOPMAssertionLevelOn,
                    CFSTR("prevent charging..."),
                    &neverSleep))

并添加以下定义:

// Disables battery charging (requires root to initiate)
#define kIOPMAssertionTypeInhibitCharging       CFSTR("ChargeInhibit")
#define kIOPMChargeInhibitAssertion             kIOPMAssertionTypeInhibitCharging

这篇关于创建一个ChargeInhibit断言(OS X 10.6.8)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆