使用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
相关产品推荐
相关产品推荐

