Powershell Mount-DiskImage:输入/输出操作因线程退出或应用程序请求而中止

编程语言 2026-07-12

我写了一个PowerShell脚本,用来挂载Kodak Photo CD的 ISO文件,然后再用pcdtojpeg把它们转换成JPEG。它运行正常,但在某些磁盘镜像上偶尔会出现这个错误:

Mount-DiskImage:
Line |
   2 |  try{Mount-DiskImage -ImagePath $_.FullName
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | The I/O operation has been aborted because of either a thread exit or an application request.

我可以用wincdemu或 Windows自带工具手动挂载ISO,它本身并不是损坏之类的。

这是为什么?我该怎么做才能防止它,或者检测到它并重试?

这些错误甚至不会中断程序流程,它只是把错误信息输出到控制台。还有一些因为ISO没有被挂载而导致读取不到存在的文件的错误。我尝试把它放进try/catch里,但并没有改变任何行为。

ISO文件存放在一个外接的Thunderbolt 3硬盘的文件夹里,我也把JPEG写到同一驱动器上的另一个文件夹里,但任务管理器显示该驱动器并未被完全占用之类的。

这是我的脚本

cd "C:\Users\mirandac\Desktop\pcdtojpeg_1_0_17\Binaries\Windows"
$disks = "D:\Corel Professional Photos Collection"
Get-ChildItem –Path $disks -Recurse |Foreach-Object {
try{Mount-DiskImage -ImagePath $_.FullName
$message = "Mount: "
$message = $message + $_
$message
}
catch{
$message = "Mount Failed"
$message
Dismount-DiskImage -ImagePath $_.FullName
Start-Sleep -Seconds 10
Mount-DiskImage -ImagePath $_.FullName
$message = "Mount: "
$message = $message + $_
$message
}
Start-Sleep -Seconds 1
$first = Get-ChildItem -Path E:\Corel -Force -Recurse -File -Name | Select-Object -First 1
$last = Get-ChildItem -Path E:\Corel -Force -Recurse -File -Name | Select-Object -Last 1 -Skip 1
$first = $first -replace "\.[^.]+$"
$last = $last -replace "\.[^.]+$"
$A = "E:\COREL\"
$B = ".PCD"
$C = "D:\PICS\"
$D = ".jpeg"
for ($i = [int]$first; $i -le ([int]$first + 99); $i++){
$diskpath = $A + [string]$i + $B
$picpath = $C + [string]$i + $D
if(-not(Test-Path $picpath)){
.\pcdtojpeg.exe $diskpath $picpath
}
}
Dismount-DiskImage -ImagePath $_.FullName
Start-Sleep -Seconds 1
$message = "Dismount: "
$message = $message + $_
$message
}

我在Windows 11上使用PowerShell 7.4.13。

我的磁盘镜像来自Internet Archive上的Corel Professional Photos Collection。

解决方案

  • 你立刻遇到的问题就是Santiago指出的那个:因为 Mount-DiskImage 报告的是一个 非终止 错误,try ... catch 不能用来捕获它;若要后者成功,你需要添加 -ErrorAction Stop,这在以下帖子中有解答:

  • Try/catch似乎没有效果

  • Try Catch not working in Powershell Script
  • 另请参阅:

    • 在为命令作者提供何时发出终止错误与非终止错误的指导时,PowerShell的基本错误类型的描述:此回答
    • 关于PowerShell错误处理令人惊讶的复杂性全面概述:GitHub文档问题#1583
    • 或者,检查 自动 $? 变量 以确定是否发生了错误,如下所示。
    • 至于 再次尝试:假设你遇到的错误是一个 瞬时的 错误,你可以按照下面的思路实现一个 重试循环
$VerbosePreference = 'Continue' # Remove this line to silence verbose output.
Get-ChildItem $disks -File -Recurse -Filter *.iso | ForEach-Object {

  # Try to mount the ISO image, up to 3 attempts with a delay in between.
  foreach ($i in 1..3) {
    $mountedImage = 
      Mount-DiskImage -ImagePath $_.FullName -ErrorAction SilentlyContinue -ErrorVariable mountError
    if ($?) { break } # Succeeded; exit loop.
    Start-Sleep -Seconds 1
    Write-Verbose "Retrying mount of $($_.FullName)..."
  }

  # If mounting failed even after retries, emit a non-terminating error and
  # proceed to the next input ISO file.
  if (-not $mountedImage) {
    Write-Error "Failed to mount $($_.FullName) after multiple attempts: $mountError"
    return # Proceed to next ISO file.
  }

  # Determine the drive letter of the newly mounted image, e.g. E:
  $mappedDrive = ($mountedImage | Get-Volume).DriveLetter + ':'

  # Work with $mappedDrive here...
  Write-Verbose "Successfully mounted $($_.FullName) as drive $mappedDrive"

  # Unmount again...
  $null = Dismount-DiskImage -ImagePath $_.FullName
}

注:

  • 先说一个不寻常的要求(你的代码通过使用 $_.FullName 正确处理了这一点):莫名其妙地,-ImagePath 参数在 Mount-DiskImageDismount-DiskImage 中都需要一个 完整(绝对)文件路径。
  • CIM实例 Mount-DiskImage 输出用于描述已经成功挂载的镜像,但它本身并不会透露新挂载镜像的 驱动器字母;后者可以通过将该实例通过管道输送到 Get-Volume 来确定,如上所示。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章