我有一个PowerShell脚本导航到我们内部网上的(可能是)经典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,它首先具有有效属性,但是当我导航到服务控制页面时,所有属性都为null(几乎就像ComObject一样)走了?)。例如,在HWND
属性具有有效值之前,但现在它为null($ie.hwnd -eq $null
返回true)。当我导航到页面时,PowerShell中没有显示错误。
我查看了一些similar questions,但第一个与我的情况不符(我的情况Document
属性为空),后者为IE9默认为Intranet站点的兼容模式。我保存了ASP页面并通过w3c validator运行它并且它抛出了一些错误(尽管没有与我正在尝试处理的元素相关)。不幸的是我无法解决这些问题。其他网站似乎没有这个问题。对问题可能存在的任何疑问以及对解决方案的建议?
答案 0 :(得分:9)
我刚刚完成了这个......在IE中关闭保护模式之前,我看到了相同的行为。这似乎与从一个安全区域提交到下一个安全区域有关。因此,假设您的原始页面位于Internet区域,启用了保护模式,您提交到受信任区域或Intranet中的页面或其他任何内容,似乎COM上下文丢失。可能是故意的。我将尝试修复区域,并保持保护模式。
希望这有帮助。
编辑:如果您在高架模式下运行powershell(以管理员身份运行),这也不是问题
答案 1 :(得分:6)
另外: http://msdn.microsoft.com/en-us/library/bb625962.aspx
此问题是由Internet Explorer 8以来的完整性级别引起的。 这也是为什么应用程序以管理员身份运行良好的原因。
由于IE-8在低完整性中运行&#34;模式,无法在脚本中自动化IE。这是因为脚本以属于&#34;中等完整性&#34;的用户身份运行。模式。安全设计使得它可以从中到低的完整性发送指令,但不能从低到中的完整性接收数据。
更新:以下是如何在不更改任何设置的情况下执行此操作的示例。它会找回丢失的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