如何在Try-Catch块中处理注册表查询返回的Null值异常?
解决方案
你的问题核心在于:
- 找不到匹配注册表项时,
$AlphaRegistry为空值,调用$AlphaRegistry.PSChildName.trim('{}')会触发非终止错误,而默认Try-Catch仅捕获终止错误;加上你设置了$ErrorActionPreference = "SilentlyContinue",错误被静默但仍会导致后续逻辑失败。 Get-ItemProperty可能返回集合而非单个对象,多匹配场景会引发额外问题。
以下是修正后的代码:
# 保存原始错误偏好,避免全局设置影响其他逻辑 $originalErrorAction = $ErrorActionPreference try { $ErrorActionPreference = "Stop" # 将非终止错误转为终止错误,确保Try-Catch可捕获 # 查找匹配的注册表项,仅取第一个结果避免多版本冲突 $AlphaRegistry = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object { $_.DisplayName -like "*Alpha*" } | Select-Object -First 1 # 提前检查是否找到目标注册表项 if (-not $AlphaRegistry) { Add-LogContent "未找到匹配Alpha软件的注册表项,无法继续卸载" [System.Environment]::Exit(1) } # 安全获取产品代码,用?.避免空值调用方法 $productCode = $AlphaRegistry.PSChildName?.Trim('{}') if (-not $productCode) { Add-LogContent "无法获取有效产品代码,无法识别对应MSI文件" [System.Environment]::Exit(1) } switch ($productCode) { "FB917EA8-1B7F-4347-A05F-7AF03DF0577D" { $InstallerMSI = 'setup17_6.msi' } "C75C2499-0D4D-6789-BEB2-32CA03BF8880" { $InstallerMSI = 'setup17_5.msi' } "68C6A4F3-3422-467D-AAAA-924282DC5365" { $InstallerMSI = 'set17_4_1.msi' } Default { Add-LogContent "无法识别已安装的Alpha版本对应的MSI文件,无法继续" [System.Environment]::Exit(1) } } # 此处执行卸载代码 # msiexec.exe /x "$InstallerMSI" /qn /norestart } catch { $ErrorMessage = " 卸载过程中出错:" + $_.Exception.Message Add-LogContent -LogText $ErrorMessage [System.Environment]::Exit(1) } finally { # 恢复原始错误偏好设置 $ErrorActionPreference = $originalErrorAction }
关键修改说明:
- 错误偏好管理:保存并恢复原始
$ErrorActionPreference,避免全局设置污染;Try块内设为Stop,确保所有错误可被捕获。 - 提前空值校验:在调用属性前检查
$AlphaRegistry是否存在,从根源避免空值调用错误。 - 安全导航操作符:
?.确保当PSChildName为空时不会触发错误,而是返回$null。 - 限制单匹配结果:用
Select-Object -First 1避免多版本匹配导致的逻辑混乱。 - 明确case值格式:给产品代码添加引号,避免PowerShell解析歧义。
另外,你提到移除赋值代码仍报错,大概率是会话中残留了旧的$AlphaRegistry变量,测试前可执行Remove-Variable AlphaRegistry -ErrorAction SilentlyContinue清空变量。
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

