我使用的PowersHell自动化iTunes但发现的错误处理/等待com对象的处理要比最佳的。

例码

#Cause an RPC error
$iTunes = New-Object -ComObject iTunes.Application
$LibrarySource = $iTunes.LibrarySource
# Get "playlist" objects for main sections
foreach ($PList in $LibrarySource.Playlists)
{
  if($Plist.name -eq "Library") {
    $Library = $Plist
  }
}
do {
  write-host -ForegroundColor Green "Running a loop"
  foreach ($Track in $Library.Tracks)
  {
     foreach ($FoundTrack in $Library.search("$Track.name", 5)) {
       # do nothing... we don't care...
       write-host "." -nonewline
     }
  }
} while(1) 
#END 

去itunes和做些什么让它流行起来的消息在我的情况下,我去洗牌方,我得到一面旗帜"缔约方自动洗牌等等等等等...." 一个"不显示"的信息。

在这一点上,如果运行的脚本将做到这一重复:

+      foreach ($FoundTrack in $Library.search( <<<< "$Track.name", 5)) {
Exception calling "Search" with "2" argument(s): "The message filter indicated
that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVER
CALL_RETRYLATER))"
At C:\Documents and Settings\Me\My Documents\example.ps1:17 char:45
+      foreach ($FoundTrack in $Library.search( <<<< "$Track.name", 5)) {
Exception calling "Search" with "2" argument(s): "The message filter indicated
that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVER
CALL_RETRYLATER))"
At C:\Documents and Settings\Me\My Documents\example.ps1:17 char:45

如果你等到你有一个对话框前运行的例子然后你会得到这个:

Running a loop
You cannot call a method on a null-valued expression.
At C:\Documents and Settings\Me\example.ps1:17 char:45
+      foreach ($FoundTrack in $Library.search( <<<< "$Track.name", 5)) {

那将是因为美元的库的处理是无效的。

如果我的例子是在做一些重要的东西-像转换轨道,然后删除旧的,不处理错误的正确可能是致命的轨道在itunes。我想要硬化起码使它处理的iTunes是繁忙和会默默地试,直到它已成功。任何建议?

有帮助吗?

解决方案

这里有一个功能,以试行动,暂停在之间的失败:

function retry( [scriptblock]$action, [int]$wait=2, [int]$maxRetries=100 ) {
  $results = $null

  $currentRetry = 0
  $success = $false
  while( -not $success ) {
    trap {
      # Set status variables at function scope.
      Set-Variable -scope 1 success $false
      Set-Variable -scope 1 currentRetry ($currentRetry + 1)

      if( $currentRetry -gt $maxRetries ) { break }

      if( $wait ) { Start-Sleep $wait }
      continue
    }

    $success = $true
    $results = . $action
  }

  return $results
}

对于第一个错误你如,你可以改变内 foreach 环像这样:

$FoundTracks = retry { $Library.search( "$Track.name", 5 ) }
foreach ($FoundTrack in $FoundTracks) { ... }

这种使用默认值 $wait$maxRetries, ,因此,它将试图呼叫 $Library.search 100倍,等2秒钟之间的每一个尝试。如果所有重试失败了,最后一个错误将会传播到的外部范围。你可以设定 $ErrorActionPreferenceStop 防止脚本来自执行任何进一步的发言。

其他提示

COM支持在directory域服务对象(或属不是100%可靠的。但我认为,真正的问题是iTunes本身。该应用程序和COM模型设计,海事组织,对于这种类型的管理。这就是说,你可以实现一个陷阱成你的剧本。如果一个异常升起,你可以有脚本睡了几秒钟。

一部分问题可能会在如何$轨道。名字是正在进行评估。你可以试图迫使它能够充分评估所用的名称使用$($轨道。名)。

其他一件事你可以尝试使用的严格参数与你的新对象的命令/

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top