RPC_E_SERVERCALL_RETRYLATER在powershell自动化
-
05-07-2019 - |
题
我使用的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秒钟之间的每一个尝试。如果所有重试失败了,最后一个错误将会传播到的外部范围。你可以设定 $ErrorActionPreference
要 Stop
防止脚本来自执行任何进一步的发言。
其他提示
COM支持在directory域服务对象(或属不是100%可靠的。但我认为,真正的问题是iTunes本身。该应用程序和COM模型设计,海事组织,对于这种类型的管理。这就是说,你可以实现一个陷阱成你的剧本。如果一个异常升起,你可以有脚本睡了几秒钟。
一部分问题可能会在如何$轨道。名字是正在进行评估。你可以试图迫使它能够充分评估所用的名称使用$($轨道。名)。
其他一件事你可以尝试使用的严格参数与你的新对象的命令/
不隶属于 StackOverflow