错误1402,无法打开注册表项UNKNOWN\Components故障原因,及Install Clean Up原理剖析
很多人遇到windows安装程序msi安装包类型的软件错误时,喜欢用Windows Install Clean Up解决。
但这个软件存在一个缺点,就是会导致“错误 1402。无法打开注册表项:UNKNOWN\Components”。

原因是Windows Install Clean Up把注册表项:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components
里某些子项的所有者改成SYSTEM,并删除了所有控制权限,从而导致了这个故障。
解决方法比较简单,用NSudo软件启用全部特权运行regedit,将Components的所有者和控制权限替换所有子对象。
故障原因和解决方法说过了,下面来介绍下Windows Install Clean UP原理。
Windows Install Clean Up只是一个枚举msi软件的工具,实际完成删除软件功能的是msizap.exe。
Install Clean Up的功能类似下面vbs代码:
Set objShell = Wscript.CreateObject("Wscript.Shell")
Set objWindowsInstaller = Wscript.CreateObject("WindowsInstaller.Installer")
Set colProducts = objWindowsInstaller.Products
For Each product In colProducts
strProductName = objWindowsInstaller.ProductInfo (product, "ProductName")
msgbox product+" "+strProductName
Next
枚举出ProductCode和对应的ProductName,当用户选中ProductName删除时,工具调用msizap.exe执行下面两个命令:
msizap.exe TAW! ProductCode
msizap.exe TW! ProductCode
导致1402错误的是第一条命令的A参数。虽然Windows Install Clean Up用了很旧的msizap.exe版本,但是我测试过用SDK v7.1A自带的msizap替换也会导致一样的错误,除非去掉A参数。
ProductCode除了用上面vbs那种com组件枚举外,还可以用MsiEnumProducts等Win32 API枚举,或者powershell的Get-WmiObject -class Win32_Product。又或者是注册表项HKEY_CLASSES_ROOT\Installer\Products等地方的子项转换而来。
举个例子:
HKEY_CLASSES_ROOT\Installer\Products\FEC5EBE9E06E2C33A8922EF94F2F9386
把FEC5EBE9E06E2C33A8922EF94F2F9386按序号0-31标记:
按下面序号重新组合:
“7,6,5,4,3,2,1,0,11,10,9,8,15,14,13,12,17,16,19,18,21,20,23,22,25,24,27,26,29,28,31,30”
得到ProductCode:{9EBE5CEF-E60E-33C2-8A29-E29FF4F23968}

就扯这么多,剩下有兴趣的自己研究。

