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

Posted

技术标签:

【中文标题】在 Windows 上以编程方式降速硬盘?【英文标题】:Spin Down Hard Disk Programmatically on Windows? 【发布时间】:2011-07-19 00:47:19 【问题描述】:

如何请求 Windows 以编程方式降低硬盘转速?我可以调用任何用户模式函数(或调用内核模式函数或发送 IRP)来实现这一点吗?

我尝试过编写一个程序,将ATA STANDBY command 直接发送到硬盘,但问题是这种方法不会通知系统,因此每当系统需要刷新缓存时,它就会再次唤醒硬盘。我如何告诉 系统 为我执行此操作? (如果系统这样做了,它会保存缓存并在数据变得太大时“突发”数据,而不是小增量写入。)

(这里的重点是直接执行此操作,不是通过将系统范围的降速超时更改为 1 秒时间并等待磁盘减速。我需要一个可以在我使用笔记本电脑时在特定时刻调用的函数,而不是不适合 95% 情况的通用函数。)


到目前为止我已经走了多远:

我觉得PoCallDriver 和IRP_MJ_POWER 可能对此有用,但我的内核模式编程经验非常有限(而且驱动程序经验几乎为零)所以我真的不知道。


请阅读:

更新

人们似乎反复提到我已经提到的解决方案不起作用。就像我上面说的,我已经尝试过“hacky”解决方案,这些解决方案可以更改超时值或直接向驱动器发出命令,以及我问过的全部原因这里的问题是那些没有没有做我需要的事情。 阅读整个问题(尤其是第 2 和第 3 段),然后再重复我在你的答案中已经说过的话——这就是 整个问题在问题中。


更多信息:

我发现this document about Disk Idle Detection 很有用,但我的答案不在其中。它指出 电源管理器 将 IRP 发送到磁盘驱动程序(因此我怀疑 IRP_MJ_POWER 很有用),但我不知道如何使用这些信息。

【问题讨论】:

现在这是一个核心问题! 那么你是想指示电源管理子系统让HD进入睡眠状态,而不是直接指示HD进入睡眠状态? 您能否添加一段解释,说明为什么常规方法(即“让操作系统根据系统和用户策略为您管理”)不适合您的场景?提前致谢! 我相信实现您既定目标的最简单方法:磁盘不旋转、节省电池寿命、防止热量积聚和消除噪音将是安装固态磁盘。您甚至可以获得显着的性能提升。 @Ben:我想更便宜的方法是阅读书籍并让笔记本电脑休眠 :-) 【参考方案1】:

我希望这会有所帮助:

这个:http://msdn.microsoft.com/en-us/library/aa394173%28VS.85%29.aspx

导致: http://msdn.microsoft.com/en-us/library/aa394132%28VS.85%29.aspx#properties

然后,您可以浏览到: http://msdn.microsoft.com/en-us/library/aa393485(v=VS.85).aspx

本文档似乎概述了我认为您正在寻找的内容。

附:只是想帮忙,不要向信使开枪。

【讨论】:

@Dima:哈哈我喜欢你的 P.S. :) 如果结果没有帮助,我不会投反对票,我只会在答案完全错误(比如“关闭你的启动盘!”)或者如果它重复我已经提到的内容时才会这样做在问题中不起作用(例如“设置超时值”)。你的似乎也不是,所以你很安全。 ;)(顺便说一句,这实际上看起来有点帮助......让我们看看它是否有效。) :) 很好,松了一口气 - 让我知道它是否确实如此(我自己有点好奇) - 尽管 MS 没有选择实施这些方法的事实应该说明我们来解决这个问题。 @Dima:哈哈,很高兴你松了一口气。 :-) 所以我尝试在 WMIC 中输入 CIM_Controller,它只是说 alias not found... 你知道如何在 WMIC 和/或 VBScript 中使用它吗? @Dima:我不知道如何让它工作(实际上我从来没有想过如何让 WMI 查询工作)......有什么想法吗? (我猜我无论如何都会遇到 Not Implemented 错误,但值得一试。) 看看这个想法:include.wutils.com/wmi/ROOT%5Ccimv2/CIM_ManagedSystemElement/…——我没有花太多时间研究这些东西——最接近的是通过 wmi 使用打印机驱动程序,并通过一些通用框架直接使用打印机本身(不记得名字了,太长了)。【参考方案2】:

您尝试过 WMI 吗?根据 MSDN 文档,您应该能够通过 WMI 向 HDD 发送降速命令:

http://msdn.microsoft.com/en-us/library/aa393493%28v=VS.85%29.aspx

uint32 SetPowerState(
  [in]  uint16 PowerState,
  [in]  datetime Time
);

编辑:

此代码列出了系统中的所有驱动器以及支持此 API 的驱动器:

strServer = "."

Set objWMI = GetObject("winmgmts://" & strServer & "/root\cimv2")
rem Set objInstances = objWMI.InstancesOf("CIM_DiskDrive",48)
Set objInstances = objWMI.ExecQuery("Select * from CIM_DiskDrive",,48) 
On Error Resume Next
For Each objInstance in objInstances
    With objInstance
        WScript.Echo Join(.Capabilities, ", ")
        WScript.Echo Join(.CapabilityDescriptions, ", ")
        WScript.Echo .Caption
        WScript.Echo .PNPDeviceID
        WScript.Echo "PowerManagementCapabilities: "  & .PowerManagementCapabilities
        WScript.Echo "PowerManagement Supported: " & .PowerManagementSupported
        WScript.Echo .Status
        WScript.Echo .StatusInfo
    End With
On Error Goto 0
Next

只需将此代码保存为 .vbs 文件并从命令行运行。

【讨论】:

这和迪玛的回答一样。 @Mehrdad :添加了特定代码,说明特定驱动器是否公开此功能。 我认为MS没有通过WMI实现这一点,但我会尝试一下,谢谢。 视实际设备而定。例如,SD 卡没有改变电源状态的能力。确保这一点的唯一方法是查询功能以检查这是否由特定设备(和驱动程序)实现。 我的硬盘好像不支持 WMI 调用。【参考方案3】:

对于 Mehrdad 提出的具体问题,我没有答案。

但是,为了帮助其他找到此页面的人试图弄清楚如何让他们的磁盘在应该但没有待机的时候进入:

    我发现在 USB 磁盘上,MS PwrTest 声称磁盘已关闭,但实际上它仍在旋转。即使在 win 7 中全局磁盘超时非常短,也会发生这种情况。(这意味着即使系统认为它已关闭磁盘,它也可能实际上并未关闭。因此,即使找到了正确的方法。这可能与各种USB磁盘控制器如何实现电源状态有关。)

    我还发现程序HDDScan成功可以关闭磁盘,并且可以成功设置磁盘尊重的超时值。此外,当操作系统访问磁盘时,磁盘会旋转,如果您需要使用它,这是一件好事,但如果您担心它一直在旋转以刷新 1kB 缓冲区,那就不是很好了。 (我选择将 HDDScan 中的空闲超时设置为比系统电源管理器超时时间多 1 分钟。这有望确保系统不会认为磁盘未启动。) p>

我注意到 powercfg 有一个选项可以防止空闲时钟因不频繁的磁盘写入而重新启动。 (称为“突发忽略时间”。)

您可以在这里获得 HDDScan:HDDScan.com 和 PwrTest:Windows Driver Kit。不幸的是,PwrTest 迫使你首先安装很多其他的 MS 东西,但如果你能弄清楚如何从他们令人困惑的网页下载它,它就是免费的。

【讨论】:

【参考方案4】:

虽然没有明显的方法可以满足您的要求(即告诉电源管理“就好像关闭磁盘的计时器已过期一样”),但可能有几种方法可以模拟它:

    在驱动器上调用FlushFileBuffers(您需要提升才能打开\\.\C),然后向驱动器发出STANDBY 命令。

    进行 API 调用,将磁盘减速的超时设置为 1 秒,然后在 1 秒后将其增加回原来的值。请注意,您可能需要提升到前一个值,而不是立即跳转到它。

【讨论】:

你自己问过So you want to instruct the power management subsystem to put the HD to sleep, not directly instruct the HD to go to sleep?吗?我以为你已经很好地理解了这个问题......你为什么只是发布我已经在我的问题中提到的不起作用【参考方案5】:

我相信Devcon Command line utility 应该能够完成您需要做的事情。如果是 - 源代码在 Windows Ddk 中可用。

【讨论】:

这很有趣!您介意详细说明我应该使用哪个开关吗? 使用状态开关运行 devcon 会列出可用的设备。例如 devcon 状态 。然后,您可以使用 remove 禁用您想要的设备。例如,在我的机器上 - devcon status * 列出“IDE\DISKST31000528AS____________________________CC38____\5&5C6CFD6&0&1.1.0”。我可以通过执行“devcon remove IDE\DISKST3100”来弹出它。 err - 对格式化感到抱歉 - 无法弄清楚如何清理它。请注意,部分设备名称(通配符)的末尾必须有一个“*”,当然 - 您可以提供整个设备名称。 呃...所以你是在建议我禁用我的启动盘? 禁用启动盘可能不是一个聪明的主意,您可能想在辅助驱动器上尝试一下。

以上是关于在 Windows 上以编程方式降速硬盘?的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows 上以编程方式获取每个进程的磁盘 io 统计信息?

在运行 Windows IoT 的 RPi3 上以编程方式接受入站蓝牙配对请求

可以在每个会话的基础上以编程方式启用/禁用 DPI 缩放吗?

黑苹果双系统mac系统下显示winds硬盘。。里面没东西咋办

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

CVPR上百人中招新冠,emoji成“呈堂证供”,M2 MBP被曝硬盘降速,今日更多大新闻在此...