如何请求Windows以编程方式关闭硬盘?我可以调用任何用户模式函数(或调用内核模式函数或发送IRP)以实现此目的吗?
我试过制作一个程序直接向硬盘发送ATA STANDBY command,但问题是这个方法没有通知系统,因此每当系统需要刷新缓存时,它我会再次唤醒硬盘。如何告诉系统为我这样做? (如果系统执行此操作,它将保存缓存并在数据变得过大时“突发”数据,而不是以较小的增量写入。)
(这里的全部内容是将直接,不通过将系统范围的减速超时更改为1秒钟并等待磁盘来执行此操作我需要一个功能,当我使用笔记本电脑时,我可以在特定时刻拨打电话,而不是那些不适合95%情况的通用功能。)
到目前为止我已经走了多远:
我觉得PoCallDriver和IRP_MJ_POWER可能对此有用,但我的内核模式编程经验非常有限(并且几乎没有驱动程序经验)所以我真的不知道。
更新:
人们似乎一再提到我已经提到的解决方案不起作用。就像我上面说过的那样,我已经已经尝试过
更多信息:
我发现this document about Disk Idle Detection很有用,但我的答案不在那里。它声明 Power Manager 向磁盘驱动程序发送IRP(因此我怀疑IRP_MJ_POWER
有用),但我不知道如何使用这些信息。
答案 0 :(得分:5)
我希望这会有所帮助:
这: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
本文档似乎概述了您的想法。
P.S。只是想提供帮助,不要射杀消息。
答案 1 :(得分:2)
你试过WMI吗?根据MSDN文档,您应该能够通过WMI发送spindown命令到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文件,然后从命令行运行该文件。
答案 2 :(得分:0)
虽然没有明显的方法可以做你要求的事情(即告诉电源管理“就好像磁盘旋转的定时器已经过期”),但可能有几种方法可以模拟它:
在驱动器上调用FlushFileBuffers(需要将其提升为打开\\.\C
),然后将STANDBY
命令发送到驱动器。
进行API调用,将磁盘旋转的超时时间设置为1秒,然后在1秒后将其增加回原来的值。请注意,您可能需要提升到之前的值,而不是立即跳转到它。
答案 3 :(得分:0)
我对Mehrdad问的具体问题没有答案。
然而,为了帮助其他人找到这个页面,试图找出如何让他们的磁盘处于待机状态时应该但不是:
我发现在USB磁盘上,MS PwrTest声称磁盘已关闭,但实际上它仍在旋转。即使在win 7中真正短的全局磁盘超时,也会发生这种情况。(这意味着即使系统认为它已关闭磁盘,它也可能实际上没有关闭。因此,Mehrdad的最初目标可能不起作用,即使找到了正确的方法。这可能与各种USB磁盘控制器如何实现电源状态有关。)
我还发现程序HDDScan可以成功关闭磁盘,并且可以成功设置磁盘所遵循的超时值。此外,当操作系统访问磁盘时,磁盘会旋转,如果你需要使用它,这是一件好事,但如果你担心它一直在旋转以冲洗1kB缓冲区,那就太好了。 (我选择将HDDScan中的空闲超时设置为比系统电源管理器超时时间长1分钟。这有望确保系统不会认为磁盘在没有时会旋转。)
我注意到powercfg有一个选项可以阻止空闲时钟从小的不经常磁盘写入中重新启动。 (被称为“爆发忽略时间。”)
您可以在此处获取HDDScan:HDDScan.com和PwrTest:Windows Driver Kit。不幸的是,PwrTest的东西迫使你先安装了很多其他MS的东西,但如果你能弄清楚如何从他们混乱的网页上下载它,它就是免费的。
答案 4 :(得分:-1)
我相信Devcon Command line utility应该能够完成你需要做的事情。如果是 - 源代码在Windows Ddk中可用。