powershell - 在 Powershell 脚本中处理 COM 对象
问题描述
我有一个运行 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 进程。
解决方案
嗯,它比这更复杂。有
[System.InteropServices.Marshal]::ReleaseComobject($specifiedDiv)
这可能行得通……但是,.NET 使用 COM 对象的方式,您可能会在各处创建一堆中间 COM 对象。如$request、$request.ParsedHtml、$request.ParsedHtml.Body。然后可能会在调用 $_.getAttributeNode('class') 时创建一大堆其他 COM 对象。
$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)
推荐阅读
- filepond - 水平而不是垂直显示
- sqlite - 插入sqlite颤振而不冻结界面
- javascript - 如何在 XML 中查找和替换文本并避免某些文本
- python - 方法和函数之间的python关系
- typescript - 无法以 ElementArrayFinder 作为参数来解决承诺
- middleman - Netlify CMS 使用中间人嵌套 YAML
- visual-c++ - 如何将 OCX 绘制到 CBitmap (MFC, c++)
- go - Go 同步和并发模型
- javascript - 试图在 ajax 之外访问 dataTable 变量是未定义的
- google-apps-script - 如何减少 Google App 脚本服务调用