У кого-нибудь есть синтаксис для одновременного удаления всех компонентов из приложения COM+ с помощью Powershell

У меня возникают проблемы при попытке выполнить цикл и удалить 91 компонент из моего приложения COM+.

Это мой код Powershell:

$app = $apps | Where-Object {$_.Name -eq 'pkgAdap2'}
$compColl = $apps.GetCollection("Components", $app.Key)
$compColl.Populate()

$index = 0
foreach($component in $compColl) {

    $compColl.Remove($index)
    $compColl.SaveChanges()

    $index++
}

Код работает, но он удаляет только ПОЛОВИНУ компонентов, а для остальных $index цикл возвращает эту ошибку:

Value does not fall within the expected range.
At line:4 char:5
+     $compColl.Remove($index)
+     ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], ArgumentException
    + FullyQualifiedErrorId : System.ArgumentException

Поэтому я продолжаю запускать его, и количество оставшихся компонентов уменьшается вдвое.

Я думаю, причина в том, что массив/коллекция, которую я «удаляю», повторно сортирует оставшиеся индексы, каждый раз перемещая их. Так что я прохожу только половину, прежде чем $index выходит за пределы досягаемости. Это единственное, что я могу понять, это делать это. Таким образом, я также попробовал другой подход:

while($compColl.Count > 0) {
    $compColl.Remove($compColl.Count)
}

Но это тоже не работает.

Кто-нибудь знает, как удалить все компоненты сразу?


person JustJohn    schedule 29.03.2017    source источник


Ответы (1)


Похоже, что индексы вашей коллекции основаны на 0, поэтому должно работать следующее:

while($compColl.Count -gt 0) {    
  $compColl.Remove($compColl.Count - 1) # remove last element, which updates .Count. Using 0 to remove the first one is a good option to.
}
$compColl.SaveChanges()

Если вы уверены, что коллекция не изменится во время ее перечисления, этот вариант, вероятно, немного более эффективен:

for ($i = $compColl.Count - 1; $i -ge 0; --$i) {
  $compColl.Remove($i)
}
$compColl.SaveChanges()

Проблема с вашим первоначальным подходом заключалась в том, что каждый вызов $compColl.Remove($index) неявно уменьшал индексы оставшихся элементов, так что $index++ в конечном итоге пропускал элементы до тех пор, пока не достигал значения, превышающего оставшийся самый высокий индекс, и терпел неудачу.

Как правило, проблематично перебирать элемент коллекции за элементом при изменении этой коллекции в теле цикла.

person mklement0    schedule 29.03.2017
comment
Второй работал как шарм. Первый, вероятно, тоже работает, но решил пойти по вашему совету. И да, я согласен с тем, почему моя версия не работала, потому что индексы уменьшались. - person JustJohn; 29.03.2017