Лучший способ проверить, существует ли объект PowerShell? - PullRequest
80 голосов
/ 13 декабря 2010

Я ищу лучший способ проверить, существует ли объект Com.

Вот код, который у меня есть;Я хотел бы улучшить последнюю строку:

$ie = New-Object -ComObject InternetExplorer.Application
$ie.Navigate("http://www.stackoverflow.com")
$ie.Visible = $true

$ie -ne $null #Are there better options?

Ответы [ 7 ]

99 голосов
/ 13 декабря 2010

Я бы придерживался проверки $null, поскольку любое значение, кроме '' (пустая строка), 0, $false и $null пройдет проверку: if ($ie) {...}.

57 голосов
/ 13 декабря 2010

Вы также можете сделать

if ($ie) {
    # Do Something if $ie is not null
}
15 голосов
/ 14 декабря 2010

В вашем конкретном примере, возможно, вам вообще не нужно выполнять никаких проверок .Возможно ли, чтобы New-Object вернул ноль?Я никогда не видел этого.Команда должна завершиться неудачей в случае возникновения проблемы, а остальная часть кода в примере не будет выполнена.Так зачем вообще делать такие проверки?

Только в коде, подобном приведенному ниже, нам нужны некоторые проверки (лучше всего явное сравнение с $ null):

# we just try to get a new object
$ie = $null
try {
    $ie = New-Object -ComObject InternetExplorer.Application
}
catch {
    Write-Warning $_
}

# check and continuation
if ($ie -ne $null) {
    ...
}
4 голосов
/ 21 марта 2018

Что все эти ответы не выделяют, так это то, что при сравнении значения с $ null вы должны поместить $ null слева, иначе вы можете столкнуться с проблемами при сравнении со значением типа коллекции. Смотри: https://github.com/nightroman/PowerShellTraps/blob/master/Basic/Comparison-operators-with-collections/looks-like-object-is-null.ps1

$value = @(1, $null, 2, $null)
if ($value -eq $null) {
    Write-Host "$value is $null"
}

Вышеуказанный блок (к сожалению) выполнен. Еще более интересно то, что в Powershell значение $ может быть как $ null, так и не $ null:

$value = @(1, $null, 2, $null)
if (($value -eq $null) -and ($value -ne $null)) {
    Write-Host "$value is both $null and not $null"
}

Поэтому важно поставить $ null слева, чтобы эти сравнения работали с коллекциями:

$value = @(1, $null, 2, $null)
if (($null -eq $value) -and ($null -ne $value)) {
    Write-Host "$value is both $null and not $null"
}

Полагаю, это еще раз показывает мощь Powershell!

1 голос
/ 12 января 2015

Проверка типов с помощью оператора -is возвращает false для любого нулевого значения.В большинстве случаев, если не все, $ value -is [System.Object] будет истинным для любого возможного ненулевого значения.(Во всех случаях это будет false для любого нулевого значения.)

Мое значение - ничто, если не объект.

0 голосов
/ 13 июня 2018

Если вы похожи на меня, то приземлились здесь, пытаясь найти способ определить, является ли ваша переменная PowerShell именно этой разновидностью несуществующего:

COM-объект, который был отделен отего базовый RCW не может быть использован.

Тогда вот некоторый код, который работал для меня:

function Count-RCW([__ComObject]$ComObj){
   try{$iuk = [System.Runtime.InteropServices.Marshal]::GetIUnknownForObject($ComObj)}
   catch{return 0}
   return [System.Runtime.InteropServices.Marshal]::Release($iuk)-1
}

пример использования:

if((Count-RCW $ExcelApp) -gt 0){[System.Runtime.InteropServices.Marshal]::FinalReleaseComObject($ExcelApp)}

, слитый вместе с другимилучшие ответы людей:

и некоторыми другими интересными вещами:

0 голосов
/ 10 июля 2017

У меня была такая же проблема. Это решение работает для меня.

$Word = $null
$Word = [System.Runtime.InteropServices.Marshal]::GetActiveObject('word.application')
if ($Word -eq $null)
{
    $Word = new-object -ComObject word.application
}

https://msdn.microsoft.com/de-de/library/system.runtime.interopservices.marshal.getactiveobject(v=vs.110).aspx

...