문제

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로 가서 메시지를 팝업하는 일을하십시오. 제 경우에는 파티 셔플로 들어가서 "파티 셔플을 자동으로 Blah blah ...."메시지를 표시합니다.

이 시점에서 스크립트를 실행하면 반복적으로 다음을 수행합니다.

+      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 초를 기다립니다. 모든 재 검색이 실패하면 마지막 오류는 외부 범위로 전파됩니다. 당신은 설정할 수 있습니다 $ErrorActionPreference 에게 Stop 스크립트가 더 이상의 설명을 실행하지 못하게합니다.

다른 팁

PowerShell의 Com 지원은 100% 신뢰할 수 없습니다. 그러나 실제 문제는 iTunes 자체라고 생각합니다. 응용 프로그램 및 COM 모델은 이러한 유형의 관리를 위해 IMO가 설계되지 않았습니다. 즉, 스크립트에 함정을 구현할 수 있습니다. 예외가 제기되면 몇 초 동안 스크립트를 잠들 수 있습니다.

문제의 일부는 $ track.name을 평가하는 방법에있을 수 있습니다. $ ($ track.name)을 사용하여 이름을 완전히 평가하도록 강요 할 수 있습니다.

당신이 시도 할 수있는 또 다른 것은 새로운 객체 명령/와 함께 -strict 매개 변수를 사용하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top