You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Uninstall-ChocolateyPackage时因路径非法字符崩溃的问题求助

问题:Chocolatey调用Uninstall-ChocolateyPackage时提示“路径中存在非法字符”但命令行可正常执行

问题背景

为使用InstallShield制作的.exe安装程序创建Chocolatey包时,Chocolatey自动卸载器无法识别该软件,因此自定义了chocolateyUninstall.ps1脚本,使用Uninstall-ChocolateyPackage cmdlet执行卸载。脚本代码如下:

$ErrorActionPreference = 'Stop'

$packageArgs = @{
  packageName    = $env:ChocolateyPackageName
  softwareName   = 'TRACE32*'
  fileType       = 'EXE'
  silentArgs     = '/s'
  validExitCodes = @(0)
}

[array]$key = Get-UninstallRegistryKey -SoftwareName $packageArgs['softwareName']
if ($key.Count -eq 1) {
  $key | % {
    $packageArgs['file'] = "$($_.UninstallString)".Trim()
    Uninstall-ChocolateyPackage @packageArgs
  }
}

调用时packageArgs的内容为:

$packageArgs['packageName'] = trace32
$packageArgs['softwareName'] = TRACE32*
$packageArgs['file'] = "C:\Program Files (x86)\InstallShield Installation Information\{A31FFDB6-5922-4D9E-ADB1-285E5D999D70}\setup.exe" -runfromtemp -l0x0409  -removeonly
$packageArgs['fileType'] = EXE
$packageArgs['silentArgs'] = /s

运行脚本时提示“路径中存在非法字符”,但将$packageArgs['file']的内容直接复制到管理员命令行(CMD/PowerShell)中却能正常完成卸载。当前使用Chocolatey版本1.3.1。

根本原因

Uninstall-ChocolateyPackage cmdlet的file参数仅接受纯可执行文件路径,但你将注册表中UninstallString的完整内容(包含exe路径和卸载参数)都赋值给了file参数。Chocolatey会把整个带参数的字符串当作exe路径解析,其中的空格、短横线等被识别为路径中的非法字符,导致报错。而命令行直接运行时,会自动将带引号的路径和后续参数拆分处理,因此可以正常执行。

解决方案

需要将UninstallString拆分为exe路径和卸载参数两部分,将exe路径赋值给file,将卸载参数与原有的静默参数/s合并后赋值给silentArgs。修改后的脚本如下:

$ErrorActionPreference = 'Stop'

$packageArgs = @{
  packageName    = $env:ChocolateyPackageName
  softwareName   = 'TRACE32*'
  fileType       = 'EXE'
  silentArgs     = ''
  validExitCodes = @(0)
}

[array]$key = Get-UninstallRegistryKey -SoftwareName $packageArgs['softwareName']
if ($key.Count -eq 1) {
  $key | ForEach-Object {
    $uninstallString = $_.UninstallString.Trim()
    # 匹配带引号的路径和后续参数
    if ($uninstallString -match '^"([^"]+)"(.*)$') {
      $packageArgs['file'] = $matches[1]
      # 合并原卸载参数与静默参数
      $packageArgs['silentArgs'] = "$($matches[2].Trim()) /s"
    } else {
      # 处理不带引号的路径(InstallShield生成的卸载字符串一般带引号,此为兼容场景)
      $parts = $uninstallString -split ' ', 2
      $packageArgs['file'] = $parts[0]
      $packageArgs['silentArgs'] = "$($parts[1] ?? '') /s"
    }
    Uninstall-ChocolateyPackage @packageArgs
  }
}

说明

  • 使用正则表达式精准提取带引号的exe路径,避免路径含空格时拆分出错
  • 将注册表中自带的卸载参数(-runfromtemp -l0x0409 -removeonly)与Chocolatey需要的静默参数/s合并,确保卸载过程静默执行
  • 保留了不带引号路径的兼容处理,覆盖更多可能的场景

内容的提问来源于stack exchange,提问作者Joshua Schroijen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 19:13:16