我正在从硬盘中恢复文件,其中一些文件是不可读的。我无法更改硬件级别超时/ ERC,当我有数十万个文件时,它很难解决,其中有数万个文件可能无法读取。
数据问题是控制器故障的结果。购买匹配的驱动器(一直向下),我已经能够访问驱动器,并且可以毫无问题地复制大量驱动器。但是,整个驱动器中都有不可读的文件,访问时会导致SATA总线挂起。我使用过各种可恢复的文件复制应用程序,如robocopy
,RichCopy和其他十几个应用程序,但它们都有相同的问题。它们的RETRY计数基于实际获取驱动器报告的错误。问题是驱动器报告错误需要很长时间,这意味着单个文件可能需要长达一个小时才能正式失败。我知道每个文件应该有多快,所以我想构建一个PowerShell CMDLET或类似的东西,它允许我传入源文件名和目标文件名,让它尝试复制文件。如果在5秒后,文件没有被复制(或者如果它有 - 这可能是一个愚蠢的过程),我希望它能够退出。我将编写一个脚本,单独触发每个复制过程,等待完成之前的过程,但我到目前为止还没有找到一个很好的方法来限制进程的时间限制。
非常感谢您提出的任何建议!
编辑:我很乐意在新线程中生成Copy-Item
,使用新的PID,然后倒计时,然后杀死该PID。我只是PowerShell的新手,并且已经看到了很多相互冲突的方法来强加定时器,而这种方法在最佳实践方式上会失败。
编辑2 请注意,遇到磁盘的坏区域时,robocopy
等应用程序将完全挂起。这些不是简单的挂起,但是窗口将尝试保留的总线挂起以便不丢失数据。在这些实例中,任务管理器无法终止进程,但Process Explorer IS。我不确定方法论的区别是什么,但无论如何,它似乎都很重要。
答案 0 :(得分:6)
我会说在PowerShell中执行此类操作的规范方法是background jobs。
a -> Map k Int
使用您要运行的任何命令替换scriptblock中的$timeout = 300 # seconds
$job = Start-Job -ScriptBlock { Copy-Item ... }
Wait-Job -Job $job -Timeout $timeout
Stop-Job -Job $job
Receive-Job -Job $job
Remove-Job -Job $job
。但要注意,要在scriptblock中使用的所有变量必须在scriptblock中定义,通过Copy-Item
参数传入,或者以-ArgumentList
范围限定符为前缀。
using:
的替代方案是一个循环,等待作业完成或达到超时:
Wait-Job