问题与失败的MSI包卸载导致进一步的安装尝试返回错误2908在MSI日志(msiexec返回1603)已经出现在很多不同的论坛,所以我只是想给我的解决方案,因为我们已经出现了它现在和然后多年来,我从来没有见过一个程序化的解决方案。
一般原因是MSI卸载程序在SOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Components下的LOCALMACHINE hive的注册表中创建了"孤立键"
典型的MSIEXEC日志错误如下所示:
MSI (s) (2C:0C)[14:52:21:49]:注:1:14 01 2:UNKNOWNComponentsB44598ECC622C01BD780AEC8E234E3E1 3:5调试:错误2908:无法注册组件{CE89544B-226C-B10C-7D08-EA8C2E433E1E}。MSI (s) (2C:0C) [14:52:21:523]: Product: Some software 3.7——安装程序在安装此软件包时遇到意外错误。这可能表明这个包有问题。错误码为2908。参数为:{CE89544B-226C-B10C-7D08-EA8C2E433E1E},,
正如其他帖子所指出的,您可以从MSI日志文件中找到密钥并使用Regedit编辑它们,执行"属性"one_answers"高级",将其所有者从"无法显示当前所有者"(或类似文本)更改为"管理员",并最终设置其访问权限,如此链接所示:
https://kb.acronis.com/content/33458然而,这很麻烦,你可以得到数百个破碎的物品。更糟糕的是,上面的手动过程似乎在Windows 10中有问题,并且没有更多的"Windows修复"工具可用。
那么如何自动修复这个呢?这些"损坏"的注册表项很难更改,即使作为高级管理员导致各种错误,因此为了确保成功,我在SYSTEM帐户中将其作为服务运行。
因此,我在visual studio中创建了一个windows服务项目,运行为SYSTEM (SID S-1-5-18),然后我们打开违规条目的父键:
RegistryKey hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey regParent = hklm.OpenSubKey(
"SOFTWAREMicrosoftWindowsCurrentVersionInstallerUserDataS-1-5-18Components",
RegistryKeyPermissionCheck.ReadWriteSubTree,
RegistryRights.FullControl);
当使用
打开每个子密钥时,可以通过安全异常检测损坏的密钥。regKey = regParent.OpenSubKey(
registryKeyName,
RegistryKeyPermissionCheck.Default,
RegistryRights.TakeOwnership | RegistryRights.ReadPermissions | RegistryRights.ReadKey))
对我来说,msiexec似乎已经添加了一个"管理用户"的问题,更糟糕的是,规则继承已经完全停止工作,出于某种原因,我认为这是这regedit不能显示密钥的所有者,这实际上仍然是系统,所以密钥并不是真正孤儿在第一位。它也不能帮助删除这个奇怪的Admin用户条目的RegistryAccessRule。解决方案是在regParent中为用户重新应用规则,因为这似乎也会更新和"治愈"所有子节点。
这样做就足够了:
security = regParent.GetAccessControl(AccessControlSections.All);
security.AddAccessRule(new RegistryAccessRule(
new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
RegistryRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, // Self+Children
AccessControlType.Allow));
security.AddAccessRule(new RegistryAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
RegistryRights.FullControl,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, // Self+Children
AccessControlType.Allow));
security.AddAccessRule(new RegistryAccessRule(
new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),
RegistryRights.ReadPermissions | RegistryRights.ReadKey | RegistryRights.EnumerateSubKeys | RegistryRights.QueryValues,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None, // Self+Children
AccessControlType.Allow));
regParent.SetAccessControl(security);
这应该足以使Regedit工作,并且Msiexec再次更改其键。你现在可以修复/删除你的失败的卸载。
此外,我还创建了一个简单的包装器应用程序,它在SYSTEM帐户中安装并启动服务,然后在清理过程结束时卸载它。
希望这能帮助那些和我们有同样问题的人!