Win10论坛

Win10正式版系统下载主题平板

重定义Modern UI,打造完美Windows全新体验

Windows10下载|安装|新手宝典|必备软件

搜索
查看: 2649|回复: 43

[原创内容] 解决/修复笔记本电量低断电问题 [复制链接]

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 14:33:12 |显示全部楼层

问题: 低电量模式下笔记本不会按照系统提示自动进入睡眠或者休眠.


解决方法: 检测电量是否处于临界状态, 如果是, 则利用系统内建的函数向系统传递睡眠/休眠/关机的信息以实现睡眠.



概述


这个问题来源已久, 不仅黑苹果的笔记本上面存在, MacBook上面也有这样的问题. 简单的解决方法是利用脚本时时刻刻抓取系统的电量, 然后判断是否在临界状态来实现的. 脚本简单高效, 确实是不错的选择. 然而这次我想试着提高程序本身效率和判断的精确度, 所以选择了采用Objective-C, 通过Objective-C, 我可以轻松的通过syscall更精确更高效的调用系统中的电量信息, 以此来完成整个修复的过程.


安装了这个程序/驱动之后, 系统会没有插入电源同时电量低于临界百分比(<7%)或者续航时间不足10分钟的时候自动让系统进入睡眠/休眠/关机状态, 以保证数据不会丢失. 希望你们喜欢, 如果觉得有用, 别忘了在https://github.com/syscl/IOPowerManagement 中点赞(Star)哦;)



安装方法


1. 打开终端, 下载IOPowerManagement/

  1. git clone https://github.com/syscl/IOPowerManagement
复制代码

2. 将所需要的文件复制到相应目录

  1. cd IOPowerManagement/
  2. sudo cp -RX IOPowerManagement /etc
  3. sudo cp -RX com.syscl.iopm.plist /Library/LaunchDameons/
复制代码

3. 向系统注册相应的服务

  1. sudo launchctl load /Library/LaunchDameons/com.syscl.iopm.plist
复制代码

4. 重启即可



个性化配置

1) 如果你的计算机无法正确的睡眠, 可修改IOPowerManagement.m当中的:

  ret = TransportEventSystemCall(kAESleep); —-> ret = TransportEventSystemCall(kAEShutDown);

这样,便可以在低电量的时候自动关闭计算机而不是睡眠.


2) 如果你觉得睡眠/关机的临界条件太苛刻, 可以修改IOPowerManagement.h中的:

int lowBatPercentage           = 6;   // system default percentage

数值成为你想要的数值, 例如在电量低于3%的时候让系统进行休眠, 则将上面的内容修改为:

int lowBatPercentage           = 3;   // system default percentage

同样的, 如果你电脑的睡眠/关机速度相当快, 可以适当的降低续航时间限制, 例如把默认的续航小于10分钟(= 600秒)即睡眠修改为续航小于3分钟(= 180秒):

int timeToSleep_seconds = 600; --> int timeToSleep_seconds = 180;


3) 在完成上述修改之后, 需要对上述的内容保存, 然后编译以产生预期的程序, 请使用下述的命令来进行编译:

  1. clang IOPowerManagement.m -fobjc-arc -fmodules -mmacosx-version-min=10.6 -o IOPowerManagement
复制代码

然后按照安装方法来进行安装即可.



注意


1. 上述个性化配置会在后期完善成可以自动配置的版本(无需再次编译), 但是最近因为我临近期末考试, 加上每周作业都比较多, 所以更新会比较慢, 请大家耐心等待.

2. Kext的版本我也在开发, 但是, 目前开来并非必要的, 因为还要考虑白苹果用户的使用情况(SIP限制).

3. 有任何好的建议请大家不要吝啬到https://github.com/syscl/IOPowerManagement 点issue给我, 有你们的建议和反馈才会让这个项目更好:)

4. 代码开源, 以防大家担心我的代码中加入了恶意代码

5. 祝你们好运!


syscl



2

查看全部评分

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 14:33:29 |显示全部楼层
本帖最后由 syscl 于 2016-10-22 15:40 编辑

现在已经可以定制自己的行为了, 通过修改配置文件com.syscl.iopm.plist中的
  1. <key>ProgramArguments</key>
  2.         <array>
  3.                 <string>IOPowerManagement</string>
  4.         </array>
复制代码
成为
  1. <key>ProgramArguments</key>
  2.         <array>
  3.                 <string>IOPowerManagement -sleep</string>
  4.         </array>
复制代码
或者
  1. <key>ProgramArguments</key>
  2.         <array>
  3.                 <string>IOPowerManagement -shutdown</string>
  4.         </array>
复制代码
即可.

更多的功能即将加入!

////

作死党

Rank: 7Rank: 7Rank: 7

UID
4690694
帖子
1353
PB币
173
贡献
0
技术
0
活跃
1387
发表于 2016-10-22 14:36:08 来自手机 |显示全部楼层
板凳。又解决了一大问题

Vanilla.

UID
4568967
帖子
13838
PB币
34
贡献
0
技术
94
活跃
2727

十一周年

发表于 2016-10-22 15:19:23 |显示全部楼层
这样的话和applealc一样 定制性不高呢…
可以用info override吧 然后用修改info的方式 init() bin
syscall 也要变吧估计

btw kext应该和pike学习下~ 避免iLog 10.12下看kernel log比较麻烦

Rank: 9

UID
763723
帖子
2115
PB币
2476
贡献
0
技术
94
活跃
1287

7周年庆典勋章 8周年庆典勋章

发表于 2016-10-22 15:32:21 |显示全部楼层
口袋妖怪heart 发表于 2016-10-22 15:19
这样的话和applealc一样 定制性不高呢…
可以用info override吧 然后用修改info的方式 init() bin
syscal ...

各位督查,这个审核制度怎么这么严啊,发个帖子审核n长时间,没法及时沟通交流啊

Vanilla.

UID
4568967
帖子
13838
PB币
34
贡献
0
技术
94
活跃
2727

十一周年

发表于 2016-10-22 15:33:53 来自手机 |显示全部楼层
hello_ok 发表于 2016-10-22 15:32
各位督查,这个审核制度怎么这么严啊,发个帖子审核n长时间,没法及时沟通交流啊

不清楚…

Rank: 7Rank: 7Rank: 7

UID
995781
帖子
1474
PB币
348
贡献
0
技术
10
活跃
456
发表于 2016-10-22 15:37:11 |显示全部楼层
多谢督查下载看一下

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 15:41:20 |显示全部楼层
现在已经可以通过配置文件控制程序的行为, 无需再编译(当然我更倾向于编译的方法, 因为简单高效).

////

Rank: 1

UID
4790253
帖子
45
PB币
0
贡献
0
技术
0
活跃
29
发表于 2016-10-22 15:43:06 |显示全部楼层

作死党

Rank: 7Rank: 7Rank: 7

UID
4690694
帖子
1353
PB币
173
贡献
0
技术
0
活跃
1387
发表于 2016-10-22 15:45:14 |显示全部楼层
支持休眠么。。。

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 15:45:33 |显示全部楼层
hello_ok 发表于 2016-10-22 15:32
各位督查,这个审核制度怎么这么严啊,发个帖子审核n长时间,没法及时沟通交流啊

你发了些什么 这个等级不应该啊。

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 15:47:32 |显示全部楼层
我不要用户名 发表于 2016-10-22 15:45
支持休眠么。。。

支持的...

作死党

Rank: 7Rank: 7Rank: 7

UID
4690694
帖子
1353
PB币
173
贡献
0
技术
0
活跃
1387
发表于 2016-10-22 15:51:22 |显示全部楼层
口袋妖怪heart 发表于 2016-10-22 15:19
这样的话和applealc一样 定制性不高呢…
可以用info override吧 然后用修改info的方式 init() bin
syscal ...

自己冒仿的配置文件放进去AppleALC,删除其他的多余的配置文件,也可以定制,哈哈

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 15:52:06 |显示全部楼层
我不要用户名 发表于 2016-10-22 15:45
支持休眠么。。。

让我把你的问题回答的更完整一些吧, 实际上, 这个程序通过
  1. kAESleep
复制代码
来向系统传递睡眠/休眠的行为. 但是, 控制系统睡眠还是休眠行为的, 是:
  1. hibernatemode
复制代码
如果你本身定义了休眠的hibernatemode那么自动通过kAESleep传递给系统的操作就是休眠, 反之则是睡眠.

////

Vanilla.

UID
4568967
帖子
13838
PB币
34
贡献
0
技术
94
活跃
2727

十一周年

发表于 2016-10-22 15:53:16 |显示全部楼层
syscl 发表于 2016-10-22 15:41
现在已经可以通过配置文件控制程序的行为, 无需再编译(当然我更倾向于编译的方法, 因为简单高效).

////

init lowBatPercentage 应该赋空值/不赋值吧 改用define等等在info下控制bin 这样更好些我觉得~ timeToSleep_seconds 一样的解法

作死党

Rank: 7Rank: 7Rank: 7

UID
4690694
帖子
1353
PB币
173
贡献
0
技术
0
活跃
1387
发表于 2016-10-22 15:55:03 |显示全部楼层
syscl 发表于 2016-10-22 15:52
让我把你的问题回答的更完整一些吧, 实际上, 这个程序通过
来向系统传递睡眠/休眠的行为. 但是, 控制系统 ...

soga。
懂了
技术帝就是不一样

Rank: 9

UID
763723
帖子
2115
PB币
2476
贡献
0
技术
94
活跃
1287

7周年庆典勋章 8周年庆典勋章

发表于 2016-10-22 16:00:47 |显示全部楼层
syscl 发表于 2016-10-22 15:45
你发了些什么 这个等级不应该啊。

最近发的帖子就是这些,全是学习黑苹果的求助帖
附件: 你需要登录才可以下载或查看附件。没有帐号?注册

苦逼的医学生。。。考试月勿扰,扣扣一概不回!

Rank: 11Rank: 11Rank: 11

UID
2043294
帖子
4557
PB币
318
贡献
0
技术
151
活跃
2044

7周年庆典勋章 8周年庆典勋章 我是大学生!

发表于 2016-10-22 16:01:38 |显示全部楼层
赶紧先过来支持一下

Rank: 5Rank: 5Rank: 5

UID
316591
帖子
1023
PB币
2237
贡献
0
技术
0
活跃
816
发表于 2016-10-22 16:37:43 |显示全部楼层
感谢楼主,又解决了一大问题。

远景FANS

UID
424619
帖子
4181
PB币
533
贡献
0
技术
741
活跃
2185

巡察使 我是大学生!

发表于 2016-10-22 16:43:03 |显示全部楼层
口袋妖怪heart 发表于 2016-10-22 15:53
init lowBatPercentage 应该赋空值/不赋值吧 改用define等等在info下控制bin 这样更好些我觉得~ timeToS ...

用define(宏)可以说是错误的温床:
1. 没有类型检查, define做的事情完全是文本替换
2. 这是编译器编译前的行为, 也就是说, 变量直接被替换成文本后, 失去了应有的灵活性
3. 容易引发拼写错误, 在C/C++/Objective-C里面, 如果不小心写了如下的句子(经常发生!):
  1. #define lowBatPercentage 10;
复制代码
直接导致的后果就是, 在编译过程中lowBatPercentage被替换成"10;"
4. 当利用define定义函数的过程中, 会引起隐晦的不易发现的错误, 例如:
  1. #define square_func a*a
复制代码
在这个顶一下, 调用:
  1. square_func(a+b);
复制代码
直接导致的结果是:
  1. a+b*a+b = (a+b)+ab != (a*a+2ab+b*b)
复制代码
5. 再看一个例子:
  1. #define swap(x,y) t=x; x=y; y=t;
  2. if(x<y) swap(x,y); --> if(x<y) t=x; x=y; y=t; --> if(x<y) { t=x; } x=y; y=t;
复制代码

上面便是常见的用define的错误,  如果仔细的看一些kext的源代码, 会注意到下面这类写法:
  1. #define MyLog(args...) do { IOLog("IOPowerDeploy: " args); } while(0)
复制代码
为什么会用到这一类写法来解决define带来的问题的原因.

syscl
回顶部
Copyright (C) 2005-2019 pcbeta.com, All rights reserved
Powered by Discuz!  苏ICP备17027154号
请勿发布违反中华人民共和国法律法规的言论,会员观点不代表远景论坛官方立场。
远景在线 | 远景论坛 | 苹果论坛 | Win10论坛 | Win8论坛 | Win7论坛 | WP论坛 | Office论坛 | 电脑硬件 | 安卓软件