你好。我有一台 SB2(Surface Book 2),我是不幸的用户之一,面临着困扰许多 SB2 机器的臭名昭著的 0.4GHz 限制问题。问题在于,SB2 突然且非常频繁地根据环境温度从 4GHz 提升到 0.4GHz 严重节流,并停留在那里一两分钟(这会导致整个笔记本电脑的速度严重减慢)。这是非常令人沮丧的,几乎使机器无法用于即使是最简单的工作负载。
微软显然表示它在 2019 年 10 月更新中修复了该问题,但我和其他几位用户仍然面临着这个问题。我非常肯定我的机器是最新的,我什至手动安装了所有最新的 Surface Book 2 固件更新。
正如你所看到的,单元本身的温度并不高,但CPU却精确地节流在0.4GHz。
我几乎尝试了一切。降低电压直至屏幕冻结、禁用 BD PROCHOT、禁用 GPE 中的电源节流、搞乱注册表、调整多个 CPU/GPU 设置。什么都没起作用。
当限制开始时你只能做两件事:
在实践中,无论工作量有多大,每 10 秒更改一次滑块,都可以无限地带来流畅的体验,而不会受到限制。当然,这不是一个可行的手动解决方法。
从理论上讲,我认为如果我能找到一种以编程方式控制此模式的方法,我也许可以通过每 10 秒左右切换一次电源模式来告别这个问题。
我不介意它是在 win32 (winapi) 还是 .net 中。我查了很多,发现了这个有关电源管理的内容,但是win32中似乎没有设置界面。我可能会忽略它,所以这是我的问题:
有没有办法以编程方式控制 Windows 10 中的电源模式?
好的...我一直想要命令行或编程访问来调整电源滑块一段时间,并且在研究它时我已经多次看到这篇文章。我很惊讶没有人费心去弄清楚这一点。我今天自己解决了这个问题,原因是 Windows 11 似乎已经从任务栏中删除了电源滑块,你必须深入研究“设置”应用程序来调整它。
\n如前所述,在注册表项 HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Power\\User\\PowerSchemes 中,您可以找到值“ActiveOverlayAcPowerScheme”和“ActiveOverlayDcPowerScheme”,它们记录了交流电源滑块的当前值和电池电量分别。但是,更改这些值不足以调整功率滑块或系统的操作模式。
\n事实证明,C:\\Windows\\System32\\powrprof.dll 中有一个名为 PowerSetActiveOverlayScheme 的未记录方法。它需要一个参数。我“猜测”它将采用与 PowerSetActiveScheme 相同的方式获取 GUID,并且它似乎有效。
\n注意 \xe2\x80\x94 Microsoft 不支持使用未记录的 API。此方法可能会在未来的 Windows 版本中失效。它可以用于个人修补,但我不建议在任何实际的生产项目中使用它。
\n以下是 C# PInvoke 签名:
\n[DllImportAttribute("powrprof.dll", EntryPoint = "PowerSetActiveOverlayScheme")]\npublic static extern uint PowerSetActiveOverlayScheme(Guid OverlaySchemeGuid);\nRun Code Online (Sandbox Code Playgroud)\n成功时返回零,失败时返回非零。
\n调用它很简单:
\nPowerSetActiveOverlayScheme(new Guid("ded574b5-45a0-4f42-8737-46345c09c238"));\nRun Code Online (Sandbox Code Playgroud)\n它立即生效。这个特定的 GUID 将滑块一直移动到右侧,并且还更新了注册表中的“ActiveOverlayAcPowerScheme”值。使用全零的 GUID 将滑块重置为中间值。当您将电源滑块设置到不同位置时,只需观察注册表中显示的值即可查看可用的 GUID 选项。
\n有两种方法可用于读取滑块的当前位置。我不确定它们之间有什么区别,它们在我的测试中每次都返回相同的值。
\n[DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetActualOverlayScheme")]\npublic static extern uint PowerGetActualOverlayScheme(out Guid ActualOverlayGuid);\n\n[DllImportAttribute("powrprof.dll", EntryPoint = "PowerGetEffectiveOverlayScheme")]\npublic static extern uint PowerGetEffectiveOverlayScheme(out Guid EffectiveOverlayGuid);\nRun Code Online (Sandbox Code Playgroud)\n它们还会在成功时返回零,在失败时返回非零。他们可以被称为...
\nif (PowerGetEffectiveOverlayScheme(out Guid activeScheme) == 0)\n{\n Console.WriteLine(activeScheme);\n}\nRun Code Online (Sandbox Code Playgroud)\n还有一种名为“PowerGetOverlaySchemes”的方法,我认为该方法可用于获取可以使用的可用 GUID 列表。它似乎需要三个参数,但我没有费心去弄清楚。
\n我创建了一个可用于设置电源模式的命令行程序,可以在https://github.com/AaronKelley/PowerMode找到它。
\n小智 6
亚伦的回答非常棒,对我帮助很大,谢谢。
\n如果你和我一样
\n没有 Visual Studio 准备好为您自己和/或编译他的工具
\n不一定要运行 GitHub 上的任意可执行文件(无意冒犯),
\n您可以使用Python(在本例中为3)来完成同样的事情。
\n为了完整起见,我将复制免责声明:
\n\n\n注意 \xe2\x80\x94 Microsoft 不支持使用未记录的 API。此方法可能会在未来的 Windows 版本中失效。它可以用于个人修补,但我不建议在任何实际的生产项目中使用它。
\n
另请注意,以下只是基本的概念验证代码!
\n获取当前活动的字节序列:
\nimport ctypes\n\noutput_buffer = ctypes.create_string_buffer(b"",16)\n\nctypes.windll.powrprof.PowerGetEffectiveOverlayScheme(output_buffer)\nprint("Current Effective Byte Sequence: " + output_buffer.value.hex())\n\nctypes.windll.powrprof.PowerGetActualOverlayScheme(output_buffer)\nprint("Current Actual Byte Sequence: " + output_buffer.value.hex())\nRun Code Online (Sandbox Code Playgroud)\n在我的系统上,这会产生以下值:
\n| 模式 | 字节序列 |
|---|---|
| 更好的电池 | 77c71c9647259d4f81747d86181b8a7a |
| 更好的性能 | 00000000000000000000000000000000 |
| 最棒的表演 | b574d5dea045424f873746345c09c238 |
显然,亚伦和我的系统具有相同的特点,其中“更好的性能”字节序列只是全零(而不是“预期”值3af9B8d9-7c97-431d-ad78-34a8bfea439f)。
请注意,字节序列77c71c9647259d4f81747d86181b8a7a相当于 GUID 961cc777-2547-4f9d-8174-7d86181b8a7a,b574d5dea045424f873746345c09c238代表ded574b5-45a0-4f42-8737-46345c09c238。
这是因为 GUID 的书写方式与它们在内存中的实际表示方式不同。(如果我们假设 GUID 的字节被写入ABCD-EF-GH-IJ-KLMN其字节序列表示形式最终为DCBAFEHGIJKLMN)。请参阅/sf/answers/486724521/(特别是“二进制编码可能不同”下的段落和表格)和/或https://uuid.ramsey.dev/en/latest/nonstandard/guid.html如果您想知道更多。
设置一个值(本例中为“更好的电池”)的工作原理如下:
\nimport ctypes\n\nmodes = {\n "better_battery": "77c71c9647259d4f81747d86181b8a7a",\n "better_performance": "00000000000000000000000000000000",\n "best_performance": "b574d5dea045424f873746345c09c238"\n}\n\nctypes.windll.powrprof.PowerSetActiveOverlayScheme(bytes.fromhex(modes["better_battery"]))\n\nRun Code Online (Sandbox Code Playgroud)\n对我来说,这是一个尝试 Python 的好机会ctypes:)。
| 归档时间: |
|
| 查看次数: |
3384 次 |
| 最近记录: |