سؤال

وأنا باستخدام PowerShell لأتمتة اي تيونز لكن العثور على معالجة الأخطاء / انتظار للكائنات كوم التعامل مع لتكون أقل من المستوى الأمثل.

وكود مثال

#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 

والذهاب الى اي تيونز والقيام بشيء ما يجعله يطفو على الرسالة - في حالتي أنا الخوض في المراوغة الحزب وأحصل على لافتة "حزب خلط تلقائيا بلاه بلاه ...." مع رسالة "عدم عرض" .

وعند هذه النقطة إذا تشغيل البرنامج النصي سوف نفعل ذلك مرارا وتكرارا:

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

وهذا سوف يكون ذلك بسبب التعامل مع المكتبة $ غير صالح.

إذا بلدي على سبيل المثال كان يفعل شيء مهم - مثل تحويل المسارات وثم حذف القديمة، وليس التعامل مع الخطأ بشكل صحيح يمكن أن تكون قاتلة لمسارات في اي تيونز. أريد أن تتصلب عن رمز بحيث يتعامل مع اي تيونز كونه مشغول وسوف إعادة المحاولة بصمت حتى انها النجاح. أي اقتراحات؟

هل كانت مفيدة؟

المحلول

إليك وظيفة لإعادة المحاولة العمليات، والتوقف بين الفشل:

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 لمنع البرنامج النصي من تنفيذ أي بيانات أخرى.

نصائح أخرى

والدعم COM في PowerShell غير قابلة موثوقة 100٪. ولكن أعتقد أن القضية الحقيقية هي اي تيونز نفسها. لم يتم تصميم التطبيق وCOM نموذج، IMO، لهذا النوع من الإدارة. قال ذلك، هل يمكن تنفيذ فخ في السيناريو الخاص بك. إذا تم رفع استثناء، هل يمكن أن يكون النوم النصي لبضع ثوان.

وجزء من المشكلة قد تكون في الكيفية التي يتم بها تقييم $ Track.name. قد تتمكن من محاولة إجبارها على إجراء تقييم كامل الاسم باستخدام $ ($ Track.name).

واحد الشيء الآخر الذي قد تحاول يستخدم المعلمة -strict مع قيادة وجوه الجديد /

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top