这看起来很奇怪。我安装了一个程序(通过WiX安装程序),我试图以编程方式(使用c#)卸载它,所以我使用msiexec.exe / x {product-code-GUID}。该程序已卸载但仍显示在控制面板中(添加/删除程序)。当我查看注册表时,我看到HKLM \ SOFTWARE \ WOW6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall \下的程序,但它不在此产品的GUID下作为其产品代码。它位于一个看似随机的GUID之下,甚至不存在于.msi中。任何人都知道为什么以及如何判断GUID将会是什么,以便我可以编程删除它?
我想我可以安装我需要卸载的每个版本并检查注册表并使用那里的GUID。这将有效,但我想了解为什么GUID与产品代码不匹配。
更新2-15-19 9:21 am PT:
好的 - 我记录了卸载,这是日志的结尾。它似乎已成功完成,但它仍然出现在控制面板中:
MSI (s) (10:E4) [09:16:22:812]: Note: 1: 1724
MSI (s) (10:E4) [09:16:22:812]: Product: Product Name -- Removal completed successfully.
MSI (s) (10:E4) [09:16:22:812]: Windows Installer removed the product.
Product Name: Product Name. Product Version: 1.21.4. Product Language: 1033.
Manufacturer: . Removal success or error status: 0.
MSI (s) (10:E4) [09:16:22:870]: Deferring clean up of packages/files, if any
exist
MSI (s) (10:E4) [09:16:22:870]: MainEngineThread is returning 0
MSI (s) (10:80) [09:16:22:871]: RESTART MANAGER: Session closed.
MSI (s) (10:80) [09:16:22:871]: No System Restore sequence number for this
installation.
=== Logging stopped: 2/15/2019 9:16:22 ===
MSI (s) (10:80) [09:16:22:892]: User policy value 'DisableRollback' is 0
MSI (s) (10:80) [09:16:22:892]: Machine policy value 'DisableRollback' is 0
MSI (s) (10:80) [09:16:22:892]: Incrementing counter to disable shutdown.
Counter after increment: 0
MSI (s) (10:80) [09:16:22:892]: Note: 1: 1402 2:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2
MSI (s) (10:80) [09:16:22:894]: Note: 1: 2265 2: 3: -2147287035
MSI (s) (10:80) [09:16:22:894]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2
MSI (s) (10:80) [09:16:22:894]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1
MSI (s) (10:80) [09:16:22:894]: Post-install cleanup: removing installer file 'C:\Windows\Installer\c8de6843.msi'
MSI (s) (10:80) [09:16:22:896]: Post-install cleanup: removing installer file 'C:\Windows\Installer\{2DE751D3-33F4-4C3E-BD12-63E7F7F0A3C9}\icon.ico'
MSI (s) (10:80) [09:16:22:896]: Post-install cleanup: removing installer folder 'C:\Windows\Installer\{2DE751D3-33F4-4C3E-BD12-63E7F7F0A3C9}\' (if empty)
MSI (s) (10:80) [09:16:22:896]: Note: 1: 2318 2:
MSI (s) (10:80) [09:16:22:897]: Destroying RemoteAPI object.
MSI (s) (10:B4) [09:16:22:897]: Custom Action Manager thread ending.
MSI (c) (78:7C) [09:16:22:898]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1
MSI (c) (78:7C) [09:16:22:898]: MainEngineThread is returning 0
=== Verbose logging stopped: 2/15/2019 9:16:22 ===
实际解决方案(调试后):
运行:
C:\ProgramData\Package Cache{Product-GUID}\ProductSetup.exe /uninstall /quiet
重复安装:您可能有重复安装。除非您在卸载期间意外地将“添加/删除程序”小程序保持打开状态,否则您应关闭并重新打开它以验证该条目是否仍然存在。
“噪音”:您可能还有一个问题,包含太多的软件包,以确保您的setup.exe已安装为两个单独的MSI文件。要防止出现这种情况,请在干净的虚拟机上进行测试,并检查其他相关条目的“添加/删除程序”列表。
产品代码:您可以使用下面介绍的方法之一找到所有安装产品的产品代码和产品名称:How can I find the product GUID of an installed MSI setup?也许可以尝试PowerShell单线程或VBScript。
回滚:请注意,如果在卸载期间自定义操作失败,则MSI可以回滚其卸载。这意味着回滚将成为重新安装或至少恢复卸载的文件。因此,在这种情况下,看起来卸载已运行,但由于自定义操作失败,产品已恢复。所以卸载永远不会“提交”。
卸载:以下是几种卸载MSI软件包的方法:Uninstalling an MSI file from the command line without using msiexec。当您卸载所有条目时,我希望ARP条目消失。这是你自己的套餐吗?在诸如快速测试周期的副产品的情况下,重复安装是非常常见的。
打包的GUID:您在注册表中找到的GUID通常是打包的,换句话说,其格式与MSI中的格式不同。
示例GUID转换:
HKEY_CLASSES_ROOT\Installer\Products
Packed GUID: 0076C0A639AEC2738817CDFC311D064A
Normal GUID: {6A0C6700-EA93-372C-8871-DCCF13D160A4}
这里有更多细节:
后一个链接有一个VBScript,用于将Packed GUID转换为普通GUID。
LocalPackage:安装MSI时,所有系统上都有一个本地程序包缓存。它将位于%SystemRoot%\Installer
。您可以使用它来找到该文件,然后您可以在Windows资源管理器中右键单击它并选择“卸载”。
这里的想法不是将此作为您的主要方法,而是确定是否还有一个隐藏的MSI,您还需要卸载以摆脱ARP中的所有内容。
这是一个显示LocalPackage路径的VBScript(在桌面上创建VB脚本文件,保存并双击。查找输出msiinfo.csv
- 双击并导入到Excel或等效的 - 或记事本):
' Retrieve all ProductCodes (with ProductName and ProductVersion)
Set fso = CreateObject("Scripting.FileSystemObject")
Set output = fso.CreateTextFile("msiinfo.csv", True, True)
Set installer = CreateObject("WindowsInstaller.Installer")
output.writeline ("Product Code,Product Name,Product Version,Local Package")
On Error Resume Next ' we ignore all errors
For Each product In installer.ProductsEx("", "", 7)
productcode = product.ProductCode
name = product.InstallProperty("ProductName")
version=product.InstallProperty("VersionString")
local=product.InstallProperty("LocalPackage")
output.writeline (productcode & ", " & name & ", " & version & ", " & local)
Next
output.Close
类似的答案:
解决方案是运行C:\ ProgramData \ Package Cache {Product-GUID} \ ProductSetup.exe / uninstall / quiet。虽然斯坦因没有直接回答他在another post上面做的事情所以我正在“关闭”这个并给予他信任。