Удаление COM-объектов в сценарии Powershell

У меня есть запланированная задача, которая запускает сценарий Powershell. Этот сценарий Powershell отправляет HTTP-запрос и выполняет поиск в возвращенном HTML. В результате этого скрипта у меня осталась куча процессов dllhost, которые не закрываются. Если я правильно понимаю, это результат COM-объектов.

Единственная переменная, связанная с COM-объектами:

$specifiedDiv = $request.ParsedHtml.Body.getElementsByTagName('div') |
    Where-Object{$_.getAttributeNode('class').Value -eq 'results'}

Когда я бегу $specifiedDiv.GetType(), Я получаю это как результат:

IsPublic IsSerial Name                                     BaseType                                                                                                                                                              
-------- -------- ----                                     --------                                                                                                                                                              
True     False    __ComObject                              System.MarshalByRefObject 

У меня вопрос: как закрыть этот объект или запретить скрипту создавать процессы dllhost?

Редактировать:

    Function garbageCollect ([object]$ref){

            ([System.Runtime.Interopservices.Marshal]::ReleaseComObject([System.__ComObject]$ref) -gt 0)
            [System.GC]::Collect()
            [System.GC]::WaitForPendingFinalizers()
        }
$parsedHtml = $request.ParsedHtml
$body = $parsedHtml.Body
$divs = $body.getElementsByTagName('div')


$classAttribute = $divs | Where-Object{$_.getAttributeNode('class').Value -eq 'results-found'}

        Remove-Variable -Name classAttribute
        Remove-Variable -Name parsedHtml
        Remove-Variable -Name body
        Remove-Variable -Name divs

        garbageCollect($parsedHtml)
        garbageCollect($body)

        foreach($div in $divs)
        {
            garbageCollect($div)
        }
        foreach($thing in $classAttribute)
        {
            garbageCollect($div)
        }

Я пробовал описанное выше, но все еще получаю процесс dllhost.

1 ответ

Что ж, это сложнее. Там есть

[System.InteropServices.Marshal]::ReleaseComobject($specifiedDiv)

Это может сработать... однако, как.NET работает с COM-объектами, у вас может быть куча промежуточных COM-объектов, создаваемых повсюду. Например, $request, $request.ParsedHtml, $request.ParsedHtml.Body. Тогда может быть целая куча других COM-объектов, созданных при вызове $_. GetAttributeNode('class').

$parsedHtml = $request.ParsedHtml
$body = $parsedHtml.Body
$divs = $body.getElementsByTagName('div')

foreach ($div in $divs)
{
   $attrNode = $div.getAttributeNode('class')

   if ($attrNode.Value -eq 'results')
   {
      $specificDiv = $attrNode
      break
   }
   else
   {
      [System.Runtime.Interopservices.Marshal]::ReleaseComObject($div)
   }
}

[System.Runtime.Interopservices.Marshal]::ReleaseComObject($divs)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($body)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($parsedHtml)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($request)
### what is this ??? [System.Runtime.Interopservices.Marshal]::ReleaseComObject($requestHome)


#### Do something with $specificDiv if you want...however, you might create more COM objects...


[System.Runtime.Interopservices.Marshal]::ReleaseComObject($specifiedDiv)
Другие вопросы по тегам