PowerShell IE9 ComObject имеет все нулевые свойства после перехода на веб-страницу
У меня есть сценарий 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, он сначала имеет допустимые свойства, но как только я перехожу на страницу управления сервисом, все свойства становятся нулевыми (почти как если бы ComObject исчез?). Например, перед HWND
свойство имело допустимое значение, но теперь оно равно нулю ($ie.hwnd -eq $null
возвращает истину). При переходе на страницу не отображается ошибка в PowerShell.
Я посмотрел на некоторые похожие вопросы, но первый не соответствует моим обстоятельствам (Document
свойство равно нулю в моем случае), а что касается последнего, IE9 по умолчанию работает в режиме совместимости для сайтов интрасети. Я сохранил страницу ASP и запустил ее через валидатор w3c, и он выдал некоторые ошибки (хотя ни один из них не связан с элементами, с которыми я пытаюсь разобраться). К сожалению, я не могу это исправить. Другие сайты, похоже, не имеют этой проблемы. Есть какие-то подозрения в том, что проблема может быть и рекомендации по обходным путям?
2 ответа
Я просто работал через это.. вроде. Я видел такое же поведение, пока не отключил защищенный режим в IE. Похоже, это как-то связано с отправкой из одной зоны безопасности в другую. Итак... при условии, что ваша исходная страница находится в зоне интернета с включенным защищенным режимом, вы отправляете страницу в доверенную зону или интранет или что-то еще, кажется, что контекст COM потерян. Вероятно, намеренный. Я собираюсь попробовать исправить зоны и оставить защищенный режим включенным.
Надеюсь это поможет.
РЕДАКТИРОВАТЬ: Это также не проблема, если вы запускаете PowerShell в режиме повышенных прав (запуск от имени администратора)
Кроме того: http://msdn.microsoft.com/en-us/library/bb625962.aspx
Эта проблема вызвана уровнями целостности начиная с Internet Explorer 8. Это также причина, почему приложение работает хорошо как администратор.
Поскольку IE-8 работает в режиме "низкой целостности", автоматизировать IE из скрипта невозможно. Это потому, что скрипт запускается как пользователь, который относится к режиму "средней целостности". Конструкция безопасности такова, что она может отправлять инструкции от средней до низкой целостности, но не может принимать данные от низкой до средней целостности.
Обновление: вот рабочий пример, как это сделать без изменения каких-либо настроек. Возвращает потерянный ком-объект.
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