4

我有一个 PowerShell 脚本,它导航到我们 Intranet 上的(可能)经典 ASP 页面,以停止在我们的服务器上运行的 Windows 服务,作为该服务部署过程的一部分(并在部署新文件后重新启动它)。它运行良好,直到我们最近升级到 IE9。这是脚本。

# Open service page in IE
$ie = new-object -comobject InternetExplorer.Application
$ie.visible = $true
$ie.navigate($serviceUrl)
while($ie.busy) { start-sleep 1 }

# Stop service
$ie.Document.getElementById("dropDownActionList").value = "Stop"
$ie.Document.getElementById("buttonTakeAction").click()
while($ie.busy) { start-sleep 1 }

现在,当我运行脚本时,它成功启动了 IE,但抛出以下错误:

You cannot call a method on a null-valued expression.
At C:\Projects\ABC\Scripts\Deploy.ps1:85 char:28
+ $ie.Document.getElementById <<<< ("dropDownActionList").value = "Stop"
    + CategoryInfo          : InvalidOperation: (getElementById:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

当我在 PowerShell 中进行调查时,我发现如果我创建 IE ComObject,它首先具有有效的属性,但是一旦我导航到服务控制页面,所有属性都是空的(几乎就像 ComObject 消失了一样? )。例如,之前HWND属性有一个有效值,但现在它是 null($ie.hwnd -eq $null返回 true)。当我导航到该页面时,PowerShell 中没有显示错误。

我查看了一些类似的 问题,但第一个问题与我的情况不符(在我的情况下该Document属性为 null),而对于后一个问题,IE9 默认为 Intranet 站点的兼容模式。我保存了 ASP 页面并通过w3c 验证器运行它,它抛出了一些错误(尽管与我试图处理的元素无关)。不幸的是,我无法解决这些问题。其他网站似乎没有这个问题。对问题可能是什么有任何怀疑以及有关解决方法的建议?

4

2 回答 2

11

我刚刚完成了这个……有点。在我关闭 IE 中的保护模式之前,我看到了相同的行为。这似乎与从一个安全区域提交到下一个安全区域有关。所以.. 假设您的原始页面位于 Internet 区域中,并且启用了保护模式,您提交到受信任区域或 Intranet 或其他任何地方的页面,看起来 COM 上下文丢失了。大概是故意的。我将尝试修复这些区域,并保持保护模式开启。

希望这可以帮助。

编辑:如果您在提升模式下运行 powershell(以管理员身份运行),这也不是问题

于 2013-02-21T06:51:45.467 回答
9

另外:http: //msdn.microsoft.com/en-us/library/bb625962.aspx

这个问题是由 Internet Explorer 8 以来的完整性级别引起的。这也是应用程序以管理员身份运行良好的原因。

由于 IE-8 在“低完整性”模式下运行,因此无法从脚本中自动执行 IE。这是因为脚本以属于“中等完整性”模式的用户身份运行。安全设计是这样的,它可以发送从中等到低完整性的指令,但不能接收从低到中等完整性的数据。

更新:这是一个工作示例,如何在不更改任何设置的情况下执行此操作。它取回丢失的 com-Object。

 function ConnectIExplorer() {
    param($HWND)

    $objShellApp = New-Object -ComObject Shell.Application 
    try {
      $EA = $ErrorActionPreference; $ErrorActionPreference = 'Stop'
      $objNewIE = $objShellApp.Windows() | ?{$_.HWND -eq $HWND}
      $objNewIE.Visible = $true
    } catch {
      #it may happen, that the Shell.Application does not find the window in a timely-manner, therefore quick-sleep and try again
      Write-Host "Waiting for page to be loaded ..." 
      Start-Sleep -Milliseconds 500
      try {
        $objNewIE = $objShellApp.Windows() | ?{$_.HWND -eq $HWND}
        $objNewIE.Visible = $true
      } catch {
        Write-Host "Could not retreive the -com Object InternetExplorer. Aborting." -ForegroundColor Red
        $objNewIE = $null
      }     
    } finally { 
      $ErrorActionPreference = $EA
      $objShellApp = $null
    }
    return $objNewIE
  } 




$HWND = ($objIE = New-Object -ComObject InternetExplorer.Application).HWND
$objIE.Navigate("https://www.google.com")
$objIE = ConnectIExplorer -HWND $HWND
于 2014-11-25T12:44:45.113 回答