วิธีที่ดีที่สุดในการตรวจสอบว่ามีวัตถุ PowerShell อยู่หรือไม่


92

ฉันกำลังมองหาวิธีที่ดีที่สุดในการตรวจสอบว่า Com Object มีอยู่จริงหรือไม่

นี่คือรหัสที่ฉันมี ฉันต้องการปรับปรุงบรรทัดสุดท้าย:

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

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

คำตอบ:


115

ฉันจะติดกับ$nullการตรวจสอบตั้งแต่ค่าอื่นใดนอกเหนือจาก''(สตริงว่าง) 0, $falseและจะผ่านการตรวจสอบ:$nullif ($ie) {...}


1
ในการใช้ if ($ val) {... } ดีกว่าสำหรับบูลีนการตรวจสอบอื่น ๆ ทั้งหมดควรเป็น if ($ val -ne $ null) {.. } ทดสอบด้วยตัวเอง TY
@Keith


16

ในตัวอย่างเฉพาะของคุณบางทีคุณไม่จำเป็นต้องทำการตรวจสอบใด ๆเลย เป็นไปได้ไหมที่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) {
    ...
}

1
ถ้าไม่มีประเภท COM Object New-Object จะทำให้เกิดข้อยกเว้น แต่ฉันไม่เห็นว่ามันจะคืนค่าว่างได้อย่างไร นอกจากนี้การละเว้นข้อยกเว้นเพื่อทดสอบค่าว่างเท่านั้นเป็นรูปแบบที่ไม่ดี
JasonMArcher

@JasonMArcher: ฉันเห็นด้วยกับคำพูดสุดท้ายอย่างแน่นอน แต่จริงๆแล้วคุณคาดหวังให้ฉันเขียนอะไรในตัวอย่างสาธิต นอกจากนี้ขึ้นอยู่กับสถานการณ์แม้ว่ารหัสนี้อาจใช้ได้ดี
Roman Kuzmin

โดยพื้นฐานแล้วให้ใส่รหัสทั้งหมดที่ใช้ $ ie ในการลอง {} วิธีนี้จะถูกข้ามไปหากมีข้อยกเว้น
JasonMArcher

2
จากนั้นรหัสจะไม่แสดงกรณีเมื่อเราต้องการตรวจสอบ $ null
Roman Kuzmin

11

สิ่งที่คำตอบเหล่านี้ไม่ได้เน้นคือเมื่อเปรียบเทียบค่ากับ $ 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 ส่งคืนค่าเท็จสำหรับค่าว่างใด ๆ ในกรณีส่วนใหญ่ถ้าไม่ใช่ทั้งหมด $ value -is [System.Object] จะเป็นจริงสำหรับค่าที่ไม่ใช่ค่าว่างที่เป็นไปได้ (ในทุกกรณีค่า null จะเป็นเท็จในทุกกรณี)

คุณค่าของฉันคืออะไรถ้าไม่ใช่วัตถุ


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)}

บดรวมกันจากคำตอบที่ดีกว่าของคนอื่น:

และสิ่งดีๆอื่น ๆ ที่ควรรู้:

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.