C++ 创建ChargeInhibit断言(OS X 10.6.8)
平台(OS X 10.6.8)- [Macbook Pro-这很重要,因为我想处理电池处理-不适用于台式机] 如果我犯了一个我看不到的基本错误,请原谅我,因为我已经五年或更长时间没有编写过任何C/C++了,而且我没有完全按照苹果API希望您处理它们的方式,所以这就是我的问题所在。基本上,我希望能够在我的命令下禁止从交流适配器充电,这样我就可以在笔记本电脑使用和插入电源时选择是否充电。我找不到任何实用程序可以做到这一点,所以起初我把它写成硬件级别的东西,不能从软件更改,但后来我遇到了一些鼓舞人心的东西: 如果打开终端窗口并运行C++ 创建ChargeInhibit断言(OS X 10.6.8),c++,macos,battery,iokit,power-management,C++,Macos,Battery,Iokit,Power Management,平台(OS X 10.6.8)- [Macbook Pro-这很重要,因为我想处理电池处理-不适用于台式机] 如果我犯了一个我看不到的基本错误,请原谅我,因为我已经五年或更长时间没有编写过任何C/C++了,而且我没有完全按照苹果API希望您处理它们的方式,所以这就是我的问题所在。基本上,我希望能够在我的命令下禁止从交流适配器充电,这样我就可以在笔记本电脑使用和插入电源时选择是否充电。我找不到任何实用程序可以做到这一点,所以起初我把它写成硬件级别的东西,不能从软件更改,但后来我遇到了一些鼓舞人心的
pmset -g assertionslog
您将得到一个断言列表,每个断言都有一个0或1,指示某个进程是否断言了该断言。第一个标题是ChargeInhibit,经过一番挖掘,我发现它在软件级别上完全符合我的要求。我只需要弄清楚如何维护它
我从苹果源代码归档中的一个名为“我将函数sendsmartmatterycommand复制到我的XCode项目中”的文件中复制了一些代码,并花时间链接其他标题和复制定义,直到我能够正确编译它。以下是复制的函数:
// 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;
}
int CInh()
{
kern_return_t kret = sendSmartBatteryCommand( kSBUCChargeInhibit, 255); // zero:uninhibit, non-zero:inhibit
if(kret == KERN_SUCCESS)
return 1;
else
return 0;
}
当我尝试使用它发送充电抑制和流入禁用断言时,我会返回成功值,但是pmset的日志没有显示任何更改,电池充电/不充电的实际状态也没有显示任何更改
我还尝试将服务的名称从“AppleSmartBatteryManager”修改为一个无意义的词,以查看函数是否返回failure,它确实返回了failure,这表明我正在连接到一个真正的服务
关于如何尽可能简单地做到这一点,有什么建议吗
顺便说一句,我试图从apple源站点的源程序包中重新编译PowerManagement项目中的AppleSmartBatteryManager,但是我发现XCode中的错误太多了,我无法处理。我希望尝试以某种方式与现有服务交互,而不会让我在自己的项目旁边重新编译AppleSmartBatteryManager源代码
编辑:
顺便说一下,这是我调用函数的一个示例:
// 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;
}
int CInh()
{
kern_return_t kret = sendSmartBatteryCommand( kSBUCChargeInhibit, 255); // zero:uninhibit, non-zero:inhibit
if(kret == KERN_SUCCESS)
return 1;
else
return 0;
}
其中,“which”参数的选项在我的头文件(也从SetActive.c复制)的枚举中定义:
我先是尝试了同样的方法,但没有成功,然后我发现了“pmset noidle”。()这提出了一个断言,但不是正确的。查看“防止空闲睡眠”功能 更改此项:
IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
kIOPMAssertionLevelOn,
CFSTR("pmset prevent sleep"),
&neverSleep))
致:
并添加以下定义:
// Disables battery charging (requires root to initiate)
#define kIOPMAssertionTypeInhibitCharging CFSTR("ChargeInhibit")
#define kIOPMChargeInhibitAssertion kIOPMAssertionTypeInhibitCharging
我先是尝试了同样的方法,但没有成功,然后我发现了“pmset noidle”。()这提出了一个断言,但不是正确的。查看“防止空闲睡眠”功能 更改此项:
IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep,
kIOPMAssertionLevelOn,
CFSTR("pmset prevent sleep"),
&neverSleep))
致:
并添加以下定义:
// Disables battery charging (requires root to initiate)
#define kIOPMAssertionTypeInhibitCharging CFSTR("ChargeInhibit")
#define kIOPMChargeInhibitAssertion kIOPMAssertionTypeInhibitCharging
你能找到一个解决方案并让它工作吗?我一直试图用完全相同的目标来做同样的事情,但还没有达到你的程度。你能找到解决办法并使其发挥作用吗?我一直试图用完全相同的目标来实现同样的目标,但还没有达到你的程度。。