Cách tốt nhất để kiểm tra xem một Đối tượng PowerShell có tồn tại không?


90

Tôi đang tìm cách tốt nhất để kiểm tra xem Đối tượng Com có ​​tồn tại hay không.

Đây là mã mà tôi có; Tôi muốn cải thiện dòng cuối cùng:

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

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

Câu trả lời:


114

Tôi sẽ gắn bó với $nullkiểm tra từ bất kỳ giá trị khác hơn ''(chuỗi rỗng), 0, $false$nullsẽ vượt qua kiểm tra: if ($ie) {...}.


1
Để sử dụng if ($ val) {...} tốt hơn cho boolean Tất cả các kiểm tra khác phải là if ($ val -ne $ null) {..} Tôi tự kiểm tra. TY @Keith Hill
Ilya Gurenko

65

Bạn cũng có thể làm

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

4
Tôi thích tùy chọn này và phủ định của nóif (-not $ie) { # Do something if $ie doesn't exist/is falsey }
Chris Magnuson

16

Trong ví dụ cụ thể của bạn, có lẽ bạn không phải thực hiện bất kỳ kiểm tra nào cả . Có thể New-Objecttrả về null không? Tôi chưa bao giờ thấy chúng. Lệnh sẽ không thành công trong trường hợp có sự cố và phần còn lại của mã trong ví dụ này sẽ không được thực thi. Vậy tại sao chúng ta nên thực hiện việc kiểm tra đó?

Chỉ trong đoạn mã như bên dưới, chúng tôi cần một số kiểm tra (so sánh rõ ràng với $ null là tốt nhất):

# 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
Nếu kiểu Đối tượng COM không tồn tại, Đối tượng Mới sẽ ném ra một ngoại lệ. Nhưng tôi không hiểu làm thế nào nó có thể trả về giá trị rỗng. Ngoài ra, bỏ qua Exception chỉ để kiểm tra null là một hình thức xấu.
JasonMArcher

@JasonMArcher: Tôi hoàn toàn đồng ý với nhận xét cuối cùng. Nhưng thực sự, bạn mong đợi tôi viết gì trong ví dụ demo? Bên cạnh đó, tùy thuộc vào một kịch bản, ngay cả mã này cũng có thể ổn.
Roman Kuzmin

Về cơ bản, hãy đặt tất cả mã sử dụng $ ie bên trong thử {}. Bằng cách đó, nó sẽ bị bỏ qua nếu có ngoại lệ.
JasonMArcher

2
Sau đó, nó sẽ không phải là mã hiển thị trường hợp khi chúng ta cần kiểm tra $ null.
Roman Kuzmin

10

Điều mà tất cả các câu trả lời này không làm nổi bật là khi so sánh giá trị với $ null, bạn phải đặt $ null ở phía bên trái, nếu không bạn có thể gặp rắc rối khi so sánh với giá trị kiểu tập hợp. Xem: 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"
}

Khối trên được thực thi (không may). Điều thú vị hơn nữa là trong Powershell, giá trị $ có thể là cả $ null và không phải $ null:

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

Vì vậy, điều quan trọng là phải đặt $ null ở phía bên trái để làm cho các so sánh này hoạt động với các bộ sưu tập:

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

Tôi đoán điều này cho thấy một lần nữa sức mạnh của Powershell!


Ngạc nhiên câu trả lời này là không bỏ phiếu tán vì nó chứa rất quan trọng chi tiết đưa $nullvào trái tay bên
sonyisda1

1

Nhập-kiểm tra với toán tử -is trả về false cho bất kỳ giá trị null nào. Trong hầu hết các trường hợp, nếu không phải tất cả, thì $ value -is [System.Object] sẽ đúng với bất kỳ giá trị nào có thể có khác rỗng. (Trong mọi trường hợp, nó sẽ sai đối với mọi giá trị null.)

Giá trị của tôi không là gì nếu không phải là một đối tượng.


1
Hoặc thậm chí $value -is [__ComObject]
Dave_J


0

Trong trường hợp bạn giống tôi và bạn đã hạ cánh ở đây để cố gắng tìm cách biết liệu biến PowerShell của bạn có phải là biến thể không tồn tại cụ thể này hay không:

Không thể sử dụng đối tượng COM đã được tách khỏi RCW bên dưới của nó.

Sau đó, đây là một số mã phù hợp với tôi:

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

cách sử dụng ví dụ:

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

kết hợp với nhau từ những câu trả lời hay hơn của những người khác:

và một số điều thú vị khác cần biết:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.