Powershell自动化期间的RPC_E_SERVERCALL_RETRYLATER [英] RPC_E_SERVERCALL_RETRYLATER during powershell automation

查看:105
本文介绍了Powershell自动化期间的RPC_E_SERVERCALL_RETRYLATER的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用PowersHell来自动执行iTunes,但是发现错误处理/等待com对象的处理不尽人意.

I'm using PowersHell to automate iTunes but find the error handling / waiting for com objects handling to be less than optimal.

示例代码

#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并做一些使其弹出的消息-在我的情况下,我进入Party Shuffle,并得到一条标语"Party shuffle自动等等……",并带有不显示"消息

Go into itunes and do something that makes it pop up a message - in my case I go into the Party Shuffle and I get a banner "Party shuffle automatically blah blah...." with a "Do not display" message.

在这一点上,如果运行脚本将反复执行此操作:

At this point if running the script will do this repeatedly:

+      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

如果在运行示例之前一直等到有一个对话框,那么您将反复得到此信息:

If you waited until you you had a dialog box before running the example then instead you'll get this repeatedly:

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

那是因为$ Library句柄无效.

That'll be because the $Library handle is invalid.

如果我的示例做的是重要的事情-例如转换轨道,然后删除旧轨道,则不能正确处理错误可能会对iTunes中的轨道造成致命影响. 我想强化代码,以使其处理iTunes繁忙的内容,并将以静默方式重试,直到成功为止.有什么建议吗?

If my example was doing something important - like converting tracks and then deleting the old ones, not handling the error correctly could be fatal to tracks in itunes. I want to harden up the code so that it handles iTunes being busy and will silently retry until it has success. Any suggestions?

推荐答案

以下是重试操作的函数,在两次失败之间暂停:

Here's a function to retry operations, pausing 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
}

对于示例中的第一个错误,您可以像这样更改内部foreach循环:

For the first error in your example, you could change the inner foreach loop like this:

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

这使用$wait$maxRetries的默认值,因此它将尝试调用$Library.search 100次,每次尝试之间等待2秒.如果所有重试均失败,则最后一个错误将传播到外部范围.您可以将$ErrorActionPreference设置为Stop,以防止脚本执行任何其他语句.

This uses the default values for $wait and $maxRetries, so it will attempt to call $Library.search 100 times, waiting 2 seconds between each try. If all retries fail, the last error will propagate to the outer scope. You can set $ErrorActionPreference to Stop to prevent the script from executing any further statements.

这篇关于Powershell自动化期间的RPC_E_SERVERCALL_RETRYLATER的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆