如何以编程方式防止 Windows 硬盘驱动器减速?

Posted

技术标签:

【中文标题】如何以编程方式防止 Windows 硬盘驱动器减速?【英文标题】:How to programatically prevent Windows from hard disk drive spin down? 【发布时间】:2012-02-02 17:50:39 【问题描述】:

我的程序在硬盘可用空间上执行任务。 任务相当长,需要 1-2 小时

问题是在笔记本电脑上,当用户处于非活动状态时,硬盘可能会在几分钟后关闭。

如何以编程方式防止 Windows 硬盘减速(关机)?

【问题讨论】:

从控制面板手动设置不同的电源计划。我会删除一个在我背后改变电源计划的程序。 计算机在使用磁盘时关闭了磁盘?这对我来说听起来不太对劲。你确定吗? 这不是“程序化的”,但您始终可以考虑打开驱动器索引。 >. 我仍然在努力理解为什么一个执行一些可能需要 1 到 2 小时的操作的应用程序会被 10 秒的启动时间所困扰。为什么要担心? @MartinJames,好的,假设您的操作需要 2 小时,并且必须每 2.5 分钟从磁盘读取数据。这将恢复磁盘 48 次,如果如您所说的启动时间需要 10 秒,则该操作将需要额外的 8 分钟。并且这些文件在非常大之前无法加载到内存中,并且取决于计算结果。我只是照原样回答这个问题;) 【参考方案1】:

为防止系统进入空闲模式,您可以尝试使用SetThreadExecutionState 函数。此函数通知系统应用程序正在使用中,并允许您指定线程的执行要求。用法可以是这样,但我不确定这是否也会影响磁盘断电计时器:

type
  EXECUTION_STATE = DWORD;

const
  ES_SYSTEM_REQUIRED = $00000001;
  ES_DISPLAY_REQUIRED = $00000002;
  ES_USER_PRESENT = $00000004;
  ES_AWAYMODE_REQUIRED = $00000040;
  ES_CONTINUOUS = $80000000;

function SetThreadExecutionState(esFlags: EXECUTION_STATE): EXECUTION_STATE;
  stdcall; external 'kernel32.dll' name 'SetThreadExecutionState';

procedure TForm1.Button1Click(Sender: TObject);
begin
  if SetThreadExecutionState(ES_CONTINUOUS or ES_SYSTEM_REQUIRED or
    ES_AWAYMODE_REQUIRED) <> 0 then
  try
    // execute your long running task here
  finally
    SetThreadExecutionState(ES_CONTINUOUS);
  end;
end;

或者还有专为 Windows 7 设计的新函数集 PowerCreateRequestPowerSetRequestPowerClearRequest,但文档令人困惑,我目前还没有找到任何使用示例。

或者您可以通过PowerWriteACValueIndexPowerWriteDCValueIndex 函数和GUID_DISK_SUBGROUP 电源设置子组来修改电源设置。

【讨论】:

不客气。无论如何,您使用了什么,帖子中的代码示例?这是否意味着SetThreadExecutionState 也会影响重置磁盘断电计时器? MSDN 文档很薄弱(我想删除关于 untested 的注释),这就是我问的原因:)谢谢 我测试过了。这就像一个魅力...... SetThreadExecutionState 也会影响磁盘断电计时器的重置。【参考方案2】:

Windows 不允许应用程序禁用电源控制更改,因为有问题的应用程序会导致电池耗尽。见http://blogs.msdn.com/b/oldnewthing/archive/2007/04/16/2148139.aspx

当系统电源状态即将改变时,您可以得到通知。见WM_POWERBROADCAST Messages。

【讨论】:

但是您可以告诉系统您需要额外的时间来完成您的任务(例如,当您观看电影时,您必须告诉系统您不想关闭显示器),恕我直言这就是(正如 TLama 在他的评论中所说)函数SetThreadExecutionState 的用途。所以事实上你正在打破电源计划。 @Martin,正如您提到的观看电影,您可以使用 SetThreadExecutionStateES_DISPLAY_REQUIRED 标志来保持您的显示。问题是我不确定(并且没有测试机器)此功能是否也适用于磁盘空闲计时器。

以上是关于如何以编程方式防止 Windows 硬盘驱动器减速?的主要内容,如果未能解决你的问题,请参考以下文章

如何以编程方式检测 SuSE Linux 中的 sata 驱动器拔出?

在 Windows 上以编程方式降速硬盘?

如何以编程方式在 Windows 中安装驱动器?

将电子邮件附件保存在硬盘上后,如何以编程方式删除它们[重复]

使用 C++ 以编程方式将新字母分配给现有驱动器

如何以编程方式测试 Mysql ODBC 驱动程序的版本