Frage

Ich bin mit Power iTunes automatisieren, aber die Fehlerbehandlung / Warten auf COM-Objekte Handhabung auf weniger als optimal finden.

Beispiel-Code

#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 

in itunes gehen und etwas tun, dass es eine Nachricht Pop-up macht - in meinem Fall habe ich in die Party Shuffle gehen und ich erhalte eine Fahne „Party-Shuffle automatisch bla bla ....“ mit einem „nicht anzeigen“ -Meldung .

An diesem Punkt, wenn das Skript ausgeführt wird dies immer wieder tun:

+      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

Wenn Sie, bis Sie gewartet hatte ein Dialogfeld, bevor Sie das Beispiel läuft dann stattdessen werden Sie erhalten diese wiederholt:

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)) {

Das wird sein, weil die $ Bibliothek Handle ist ungültig.

Wenn mein Beispiel etwas Wichtiges zu tun war - wie Spuren Umwandlung und dann die alten löschen, nicht Umgang mit dem Fehler auf die Spuren in itunes richtig fatal sein könnte. Ich möchte den Code härten, so dass es iTunes Hantieren Griffe und leise wiederholen, bis er Erfolg hat. Irgendwelche Vorschläge?

War es hilfreich?

Lösung

Hier ist eine Funktion, die Operationen erneut versuchen, eine Pause in Between Failures:

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
}

Für den ersten Fehler in Ihrem Beispiel könnten Sie die innere foreach Schleife wie folgt ändern:

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

Diese verwendet die Standardwerte für $wait und $maxRetries, so wird es versuchen, $Library.search 100 mal anrufen, warten 2 Sekunden zwischen jedem Versuch. Wenn alle Versuche fehlschlagen, wird der letzte Fehler auf den äußeren Umfang ausbreiten. Sie können $ErrorActionPreference auf Stop das Skript zu verhindern, dass weitere Anweisungen ausgeführt werden.

Andere Tipps

COM-Unterstützung in Powershell ist nicht 100% zuverlässig. Aber ich denke, das eigentliche Problem ist iTunes selbst. Die Anwendung und COM-Modell wurde nicht entwickelt, IMO, für diese Art von Management. Das heißt, Sie eine Falle in das Skript implementieren könnte. Wenn eine Ausnahme ausgelöst wird, können Sie das Skript Schlaf für ein paar Sekunden haben.

Ein Teil des Problems könnte sein, in wie $ Track.name ausgewertet wird. Sie versuchen, es zu zwingen könnte den Namen vollständig zu bewerten von $ ($ Track.name) verwendet wird.

Eine andere Sache, die Sie könnten versuchen, den -strict Parameter mit Ihrem neuen-Objekt-Befehl mit /

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top