繁体   English   中英

Powershell 7 和 IE 自动化错误 0x800A01B6

[英]Powershell 7 and IE automation Error 0x800A01B6

首先,Slenium WebDriver 不是一个选项,因为它需要批准才能运行,并且我被锁定在 Windows 环境中。 另外,我访问的站点工具很旧,只能在 Internet Exploder 中使用。

该脚本在 PowerShell 5.1 中“正常”,但我需要将其转换为 7.1。 我遇到了一些关于 IE Com object 以及我如何与之交互的奇怪问题。 我收到错误代码 0x800A01B6,它引用了“执行停止”,在 Microsoft 削弱错误 output 之前,完整的错误是:

Exception from HRESULT: 0x800A01B6
At line:1 char:1
+ ($ie.document.getElementsByName("email") |select -first 1).value = $u ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : OperationStopped: (:) [], NotSupportedException
+ FullyQualifiedErrorId : System.NotSupportedException

I previously bypassed this error by re-hooking the IE COM window through the Windows Shell, but now it's come back to haunt me. 如果不每次都重新连接 window,我似乎无法执行单个命令系列。 这似乎是一个小问题,但每次我想运行 JavaScript 方法时,是否会出现重新挂钩的问题? (除了脚本现在变得更加复杂,因为我无法存储任何参考)

我尝试了双与号运算符,看看它是否有助于将命令排成一行,但没有骰子。

我也尝试过 getElementByID,但它给了我同样的错误信息。 我确保实现了一个等待浏览器不忙的方法,但这似乎是我失败的地方。 我过去在自动化 IE 时遇到过这个问题。 当程序休眠等待浏览器完成加载时,发生了一些事情,我必须重新连接 window。

我知道 IE COM 有一些可以注册的事件触发器,但我认为我不能从 PowerShell 中做到这一点......(例如 Onload)

以下是相关代码以及我可以提供的内容:

$ie_list = [PSCustomObject]@{
    url1 = "http://test-url1"
    title1 = "INTER Net 1"
    hwnd1 = $false

    url2 = "http://test-url2"
    title2 = "INTER Net 2"
    hwnd2 = $false

    url3 = "http://test-url3"
    title3 = "INTER Net 3"
    hwnd3 = $false

    # First three internet, second three intranet

    url4 = "http://test-url4"
    title4 = "INTRA Net 1"
    hwnd4 = $false

    url5 = "http://test-url5"
    title5 = "INTRA Net 2"
    hwnd5 = $false

    url6 = "http://test-url6"
    title6 = "INTRA Net 3"
    hwnd6 = $false
}
for ($num = 1; $num -le 6; $num++)
{
    $ie_com = new-object -comobject InternetExplorer.Application 
    $ie_list."hwnd$num" = $ie_com.HWND
    $hWnd = $ie_list."hwnd$num"
    Write-Host "`nConnecting using URL $($ie_list."url$num")"
    $ie_com.navigate2($ie_list."url$num")
    Write-Host "Successfully created window $num with HWND $hWnd."
    # We can wait for the page to finish loading all the way!
    # If we did not release and re-hook, the object would null itself. Not cool.
    # Manual release COM object
    $ie_com = $false
    # Re-integrate using Shell COM methods. This typically works a little better but not by much. It's still Internet Explorer.
    $app = New-Object -Com shell.application
    $ie_com = $app.Windows() | Where-Object {$_.HWND -match $hWnd -and $_.Name -match "Internet Explorer"} | Select-Object -Last 1
    # Making sure it's still an object!
    if ($ie_com -isnot [object] -or $ie_com.Document -isnot [object])
    {
        # Something done messed up.
        Write-Host -ForegroundColor Red "FAILED to connect to Com Object $num at $hWnd."
        # Pause
        Continue
    }
    $doc = $ie_com.Document
    
    Write-Host "`tReconnected COM object $num at $hWnd"

    if ($ie_com.Busy -or $ie_com.ReadyState -ne 4)
    {
        Write-Host -NoNewline "Browser busy. Waiting"
        $timeout = 0
        while ($ie_com.Busy -and $ie_com.ReadyState -ne 4 -and $timeout -le 20)
        {
            Start-Sleep -Milliseconds 50
            Write-Host -NoNewline "."
            $timeout++
        }
        # Have to manually add linebreak
        Write-Host " "
    }
    $u_fill = $false
    $p_fill = $false

    # In upgraded to Powershell 7, IHTML3 is not required for reliability when it was previously used in 5.1
    # It's freakin weird. MS sucks.
    Try {
        $link = $doc.getElementsByName("j_username") | Select-Object -First 1 && $link.focus() && ($link.value = $env:USERNAME)
        $u_fill = $true
    }
    Catch {
        Write-Host -ForegroundColor Red "`tAn error occurred."
        Write-Host -ForegroundColor Red "`t$_`n`t$($_.ErrorDetails)"
    }

    if ($false -eq $u_fill)
    {
        Write-Host -ForegroundColor Red "`tUnable to fill in Username. Skipping..."
        Continue
    }

    Write-Host "`tUsername in window $num filled in"

    Try {
        $link = $doc.getElementsByName("j_password") | Select-Object -First 1 && $link.focus() && ($link.value = $pw)
        $p_fill = $true
    }
    Catch {
        Write-Host -ForegroundColor Red "`tAn error occurred."
        Write-Host -ForegroundColor Red "`t$_`n`t$($_.ErrorDetails)"
    }

    if ($false -eq $p_fill)
    {
        Write-Host -ForegroundColor Red "`tUnable to fill in Password. Skipping..."
        Continue
    }

    Write-Host "`tPassword in window $num filled in"

    # No issues with this window. Pull the lever, Kronk!

    $link = $doc.getElementsByName("input") | Where-Object { $_.value -eq "SIGN IN" } && $link.click()
    Write-Host -ForegroundColor Green "`tLogin button in window $num clicked"
}

Output

Connecting using URL http://test-url1
Successfully created window 1 with HWND 921560.
        Reconnected COM object 1 at 921560
Browser busy. Waiting..
        An error occurred.
        You cannot call a method on a null-valued expression.

        Unable to fill in Username. Skipping...

Connecting using URL http://test-url2
Successfully created window 2 with HWND 1314278.
        Reconnected COM object 2 at 1314278
Browser busy. Waiting..
        An error occurred.
        0x800A01B6

        Unable to fill in Username. Skipping...

以前,在 Powershell 5.1 中,我必须使用IHTML3_getElementsByName()方法获取元素,但 PowerShell 7 似乎无法使用这些相同的方法。 我测试的越多,我意识到这是一个 IE 安全问题。

我查看了 Windows UI 自动化,但似乎无法将模块直接导入 PowerShell。

作为测试,我将HTML表格保存在本地硬盘上,打开后,PowerShell表格填写成功。 对此的大多数解决方案都已有多年历史,引用了我提到的 IHTML3 方法,并将该站点添加为 IE 中的受信任站点。

值得庆幸的是,需要 Internet Explorer 的工具即将停用。 希望在我们被迫完全更新到 PowerShell 7 之前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM