Bir PowerShell Nesnesinin var olup olmadığını kontrol etmenin en iyi yolu?


92

Bir Com Nesnesinin var olup olmadığını kontrol etmenin en iyi yolunu arıyorum.

İşte sahip olduğum kod; Son satırı geliştirmek istiyorum:

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

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

Yanıtlar:


115

Ben sopa ile olur $nulldışındaki herhangi bir değere beri çek ''(boş dize), 0, $falseve $nullçek geçecek: if ($ie) {...}.


1
Kullanmak için if ($ val) {...} booleler için daha iyidir Diğer tüm kontroller if ($ val -ne $ null) {..} Kendimi test ettim. TY @Keith Hill
Ilya Gurenko

68

Sen de yapabilirsin

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

4
Bu seçeneği ve olumsuzluğunu seviyorumif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
Chris Magnuson

16

Sizin özel örneğinizde, belki de herhangi bir kontrol yapmanız gerekmez . New-ObjectBoş döndürmek mümkün mü ? Bunu hiç görmedim. Komut, bir sorun olması durumunda başarısız olmalıdır ve örnekteki kodun geri kalanı çalıştırılmayacaktır. Öyleyse neden bu kontrolleri yapmalıyız?

Sadece aşağıdaki gibi kodda bazı kontrollere ihtiyacımız var ($ null ile açık karşılaştırma en iyisidir):

# 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 Nesne türü mevcut değilse, New-Object bir istisna atar. Ama nasıl sıfır döndürebileceğini anlamıyorum. Ayrıca, İstisnayı yok saymak, yalnızca null testi yapmak için kötü biçimdir.
JasonMArcher

@JasonMArcher: Son söze kesinlikle katılıyorum. Ama gerçekten, demo örneğinde ne yazmamı bekliyorsunuz? Ayrıca, bir senaryoya bağlı olarak bu kod bile iyi olabilir.
Roman Kuzmin

Esasen, $ ie kullanan tüm kodu try {} içine koyun. Bu şekilde, bir istisna varsa atlanır.
JasonMArcher

2
O zaman $ null olup olmadığını kontrol etmemiz gerektiğinde bir durum gösteren kod olmazdı.
Roman Kuzmin

11

Tüm bu yanıtların vurgulamadığı şey, bir değeri $ null ile karşılaştırırken, sol tarafa $ null koymanız gerektiğidir, aksi takdirde bir koleksiyon türü değeri ile karşılaştırırken başınız belaya girebilir. Bakınız: 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"
}

Yukarıdaki blok (maalesef) yürütülmüştür. Daha da ilginç olan, Powershell'de bir $ değerinin hem $ null olabileceği hem de $ null olamayacağıdır:

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

Bu nedenle, bu karşılaştırmaların koleksiyonlarda çalışması için sol tarafa $ null koymak önemlidir:

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

Sanırım bu yine Powershell'in gücünü gösteriyor!


Sol tarafa koymanın kritik detayını içerdiği için bu yanıtın daha fazla oylanmaması şaşırttı$null
sonyisda1

1

-İs operatörü ile tür denetimi, herhangi bir boş değer için yanlış döndürür. Çoğu durumda, tümü değilse de, $ değer -is [System.Object], olası boş olmayan değerler için doğru olacaktır. (Her durumda, herhangi bir boş değer için yanlış olacaktır.)

Değerim bir nesne değilse hiçbir şeydir.


1
Veya hatta $value -is [__ComObject]
Dave_J


0

Benim gibisiniz ve buraya, PowerShell değişkeninizin varolmayanın bu özel çeşidi olup olmadığını anlamanın bir yolunu bulmaya çalıştınız:

Temeldeki RCW'den ayrılmış bir COM nesnesi kullanılamaz.

O zaman işte benim için çalışan bazı kodlar:

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

örnek kullanım:

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

diğer insanların daha iyi cevaplarından bir araya getirildi:

ve bilinmesi gereken diğer harika şeyler:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.