Найкращий спосіб перевірити, чи існує об’єкт PowerShell?


90

Я шукаю найкращий спосіб перевірити, чи існує об’єкт Com.

Ось код, який я маю; Я хотів би покращити останній рядок:

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

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

Відповіді:


114

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


1
Використовувати, якщо ($ val) {...} краще для логічних типів. Усі інші перевірки повинні бути if ($ val -ne $ null) {..} Перевірив сам. TY @Keith Hill
Ілля Гуренко

65

Ви також можете зробити

if ($ie) {
    # Do Something if $ie is not null
}

4
Мені подобається цей варіант та його запереченняif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
Кріс Магнусон

16

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

Тільки в коді, як показано нижче, нам потрібні деякі перевірки (найкраще порівняння з $ 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) {
    ...
}

1
Якщо тип об'єкта COM не існує, New-Object видасть виняток. Але я не розумію, як це може повернути нуль. Крім того, ігнорування винятку лише для перевірки на нуль є поганою формою.
JasonMArcher

@JasonMArcher: Я повністю погоджуюсь з останнім зауваженням. Але насправді, що б ви очікували від мене на прикладі демонстрації? До того ж, залежно від сценарію, навіть цей код може бути чудовим.
Роман Кузьмін

По суті, помістіть увесь код, який використовує $, тобто всередину try {}. Таким чином він пропускається, якщо є виняток.
JasonMArcher

2
Тоді це не буде код, що показує випадок, коли нам потрібно перевірити наявність $ null.
Роман Кузьмін

10

Усі ці відповіді не виділяють, що, порівнюючи значення з $ 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!


Здивований, ця відповідь не є більш прихильною, оскільки вона містить критичну деталь поставлення $nullна лівій стороні
sonyisda1

1

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

Моє значення - це ніщо, якщо не об’єкт.


1
Або навіть $value -is [__ComObject]
Dave_J


0

Якщо ви схожі на мене, і ви приземлилися тут, намагаючись знайти спосіб визначити, чи є ваша змінна 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)}

поєднані з кращими відповідями інших людей:

та деякі інші цікаві речі:

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.