IE COM自动化:如何在PowerShell中获取“window.execScript”的返回值



从另一篇文章来看,似乎可以从Internet Explorer API中获取IHTMLWindow2::execScript的返回值,但是链接的示例是在C++中,我并不真正理解它。我正在PowerShell中尝试做同样的事情,所以下面是我的代码,显示了问题:

$ie = New-Object -COM InternetExplorer.Application
$ie.visible = $true
$ie.navigate("http://google.com")
while ( $ie.busy ) { start-sleep -m 100 }
$document = $ie.document
$window = $document.parentWindow
Function eval($jsCommand) {
    # Of course it doesn't return anything here. How can I get the return value?
    return $window.execScript($jsCommand, 'javascript')
}
eval 'parseInt("12")' # returns nothing

我真正想做的是在我的PowerShell脚本中提供jQuery选择器/对象,这样我就可以做一些事情,比如:

eval '$("input#selector")' | where name -eq 'username'

等等。

更新:查看此Gist for PowerShell函数,以运行JavaScript/JQuery并将结果返回到PS,并超时。它是从下面的答案延伸而来的。

首选方法可能是@Matt建议使用eval方法,而不是在IE11中不推荐使用的execScript。然而,我仍然找不到如何从IE API访问eval。我提出了另一个问题来跟进。

然而,我可以想出一种在网页上执行JavaScript/jQuery并将结果返回给PowerShell的方法,方法是使用setAttribute将JavaScript返回值存储在DOM中,然后使用getAttribute在PowerShell中检索它。

# some web page with jQuery in it
$url = "http://jquery.com/"
# Use this function to run JavaScript on a web page. Your $jsCommand can
# return a value which will be returned by this function unless $global
# switch is specified in which case $jsCommand will be executed in global
# scope and cannot return a value. If you received error 80020101 it means
# you need to fix your JavaScript code.
Function ExecJavaScript($ie, $jsCommand, [switch]$global)
{
    if (!$global) {
        $jsCommand = "document.body.setAttribute('PSResult', (function(){$jsCommand})());"
    }
    $document = $ie.document
    $window = $document.parentWindow
    $window.execScript($jsCommand, 'javascript') | Out-Null
    if (!$global) {
        return $document.body.getAttribute('PSResult')
    }
}
Function CheckJQueryExists
{
    $result = ExecJavaScript $ie 'return window.hasOwnProperty("$");'
    return ($result -eq $true)
}
$ie = New-Object -COM InternetExplorer.Application -Property @{
    Navigate = $url
    Visible = $false
}
do { Start-Sleep -m 100 } while ( $ie.ReadyState -ne 4 )
$jQueryExists = CheckJQueryExists $ie
echo "jQuery exists? $jQueryExists"
# make a jQuery call
ExecJavaScript $ie @'
    // this is JS code, remember to use semicolons
    var content = $('#home-content');
    return content.text();
'@
# Quit and dispose IE COM
$ie.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) | out-null
Remove-Variable ie

最新更新