Cara terbaik untuk memeriksa apakah Objek PowerShell ada?

92

Saya mencari cara terbaik untuk memeriksa apakah Objek Com ada.

Ini kode yang saya miliki; Saya ingin meningkatkan baris terakhir:

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

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

Jawaban:

115

Saya akan tetap dengan $nullcek karena setiap nilai selain ''(string kosong), 0, $falsedan $nullakan melewati cek: if ($ie) {...}.

Keith Hill
sumber
1
Untuk menggunakan if ($ val) {...} lebih baik untuk boolean Semua pemeriksaan lainnya harus dilakukan jika ($ val -ne $ null) {..} Menguji diri sendiri. TY @Ke Hill
Ilya Gurenko
68

Anda juga bisa melakukannya

if ($ie) {
    # Do Something if $ie is not null
}
ravikanth
sumber
4
Saya suka opsi ini dan negasinyaif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
Chris Magnuson
16

Dalam contoh khusus Anda, mungkin Anda tidak perlu melakukan pemeriksaan sama sekali . Apakah itu mungkin New-Objectmengembalikan nol? Saya belum pernah melihat itu. Perintah harus gagal jika terjadi masalah dan kode lainnya dalam contoh tidak akan dijalankan. Jadi mengapa kita harus melakukan pemeriksaan itu?

Hanya dalam kode seperti di bawah ini kita memerlukan beberapa pemeriksaan (perbandingan eksplisit dengan $ null adalah yang terbaik):

# 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) {
    ...
}
Roman Kuzmin
sumber
1
Jika tipe COM Object tidak ada, New-Object akan mengeluarkan pengecualian. Tapi saya tidak melihat bagaimana itu bisa mengembalikan nol. Juga, mengabaikan Exception hanya untuk kemudian menguji null adalah bentuk yang buruk.
JasonMArcher
@JasonMArcher: Saya setuju dengan komentar terakhir, tentu saja. Tapi sungguh, apa yang Anda harapkan untuk saya tulis dalam contoh demo? Selain itu, tergantung pada skenario, bahkan kode ini mungkin baik-baik saja.
Roman Kuzmin
Pada dasarnya, letakkan semua kode yang menggunakan $ ie di dalam percobaan {}. Dengan cara itu, itu akan dilewati jika ada pengecualian.
JasonMArcher
2
Maka itu tidak akan menampilkan kode kasus ketika kita perlu memeriksa $ null.
Roman Kuzmin
11

Apa yang tidak disoroti oleh semua jawaban ini adalah ketika membandingkan nilai dengan $ null, Anda harus meletakkan $ null di sisi kiri, jika tidak, Anda mungkin mendapat masalah saat membandingkan dengan nilai tipe-koleksi. Lihat: 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"
}

Blok di atas (sayangnya) dieksekusi. Yang lebih menarik adalah bahwa di Powershell, nilai $ bisa berupa $ null dan bukan $ null:

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

Jadi, penting untuk meletakkan $ null di sisi kiri agar perbandingan ini berfungsi dengan collection:

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

Saya rasa ini menunjukkan lagi kekuatan Powershell!

Dag Wieers
sumber
Terkejut, jawaban ini tidak lebih disukai karena berisi detail kritis dari meletakkan $nulldi sisi kiri
sonyisda1
1

Ketik-cek dengan operator -is mengembalikan false untuk nilai null apa pun. Dalam kebanyakan kasus, jika tidak semua, $ value -is [System.Object] akan menjadi true untuk setiap kemungkinan nilai non-null. (Dalam semua kasus, ini akan menjadi salah untuk nilai null apa pun.)

Nilai saya tidak ada artinya jika bukan sebuah objek.

Aron
sumber
1
Atau bahkan $value -is [__ComObject]
Dave_J
0

Jika Anda seperti saya dan Anda mendarat di sini mencoba menemukan cara untuk mengetahui apakah variabel PowerShell Anda adalah rasa khusus yang tidak ada ini:

Objek COM yang telah dipisahkan dari RCW dasarnya tidak dapat digunakan.

Lalu inilah beberapa kode yang berhasil untuk saya:

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

contoh penggunaan:

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

disatukan dari jawaban orang lain yang lebih baik:

dan beberapa hal keren lainnya yang perlu diketahui:

Gregor y
sumber