卸载软件 [英] Uninstall software

查看:105
本文介绍了卸载软件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的产品具有帮助程序可执行文件,用于卸载所有相关的子产品.我根据所有子产品的升级代码进行卸载.

首先,我使用 MsiEnumRelatedProducts从升级代码中获取产品代码. /a>函数.然后,我尝试使用 MsiConfigureProductEx 函数来卸载产品. /p>

问题是MsiConfigureProductEx返回错误.

调用的函数:MsiConfigureProductsEx
返回码:1605(0x00000645)
说明:此操作仅对当前安装的产品有效.

为什么MsiEnumRelatedProducts返回无效的产品代码?我在Windows注册表中进行了搜索,以查看是否存在此类产品代码.没有如何调试问题?

添加了重现问题的最小代码.

// UpgradeCodes is an array having upgrade codes of all modules.

TCHAR lpProductCode[GUID_STR_LENGTH];
const TCHAR tszNoReboot[] = _T("REMOVE=ALL REBOOT=ReallySuppress DISABLE_REBOOT_PROMPT=1");

for (size_t i = 0; i < sizeof(UpgradeCodes) / sizeof(UpgradeCodes[0]); i++)
{
   tstring tstrUpgradeCode = UpgradeCodes[i];

   DWORD dwIndex = 0;
   size_t status;

   // for each of the upgrade code, get all the products
   do
   {
       status = MsiEnumRelatedProducts(UpgradeCodes[i], 
                                       0, 
                                       dwIndex, 
                                       lpProductCode);
       if (ERROR_SUCCESS == status)
       {
          UINT uiReturn = MsiConfigureProductEx(lpProductCode, 
                                                INSTALLLEVEL_DEFAULT, 
                                                INSTALLSTATE_DEFAULT, 
                                                tszNoReboot);

          if (ERROR_SUCCESS_REBOOT_REQUIRED == uiReturn)
          {
               // prompt for reboot at the end of all modules uninstallation.
          }

          if (ERROR_SUCCESS != uiReturn)
          {
              // log message with return code.

              // Error Code: 1605 is coming from here.
          }
       }
   }while (ERROR_NO_MORE_ITEMS != status);
}

解决方案

您产品的先前卸载很可能在卸载时留下了一些注册信息,这引起了所有问题.我会尝试使用脚本检查系统上注册了什么.

在这里找到了有关使用VBScript检索产品信息的很好的讨论,这是两个非常好的脚本-推荐.转到站点查找脚本,它们在此处的格式设置很差,并且堵塞了答案.

Windows Installer数据库大多位于此处:

  • HKEY_CLASSES_ROOT \ Installer \
  • 升级代码部分:HKEY_CLASSES_ROOT \ Installer \ UpgradeCodes

您绝不能直接触摸Windows Installer数据库注册表中的任何内容.它具有极强的互连性,并且容易损坏.仅通过API.请注意,注册表中的GUID是打包的,因此您无法从注册表中的程序包中找到GUID.

  • 打包的GUID :03B1692A57845354EA63AD602436AB05
  • 常规GUID :{A2961B30-4875-4535-AE36-DA064263BA50}

使用上面的VBScript和注册表数据直接进行检查,您应该能够确定Windows Installer数据库中正在发生的事情.

My product has a helper executable to uninstall all related sub-products. I uninstall based on upgrade codes of all sub-products.

First, I fetch the product code from upgrade code using MsiEnumRelatedProducts function. Then I try to uninstall the product using MsiConfigureProductEx function.

The problem is MsiConfigureProductEx is returning error.

Invoked Function: MsiConfigureProductsEx
Return Code: 1605 (0x00000645)
Description: This action is only valid for products that are currently installed.

Why is MsiEnumRelatedProducts returning a invalid product code ? I searched through the windows registry to see if such product code exists. There isn't any. How to debug the issue ?

Edit: Added minimum code that reproduces issue.

// UpgradeCodes is an array having upgrade codes of all modules.

TCHAR lpProductCode[GUID_STR_LENGTH];
const TCHAR tszNoReboot[] = _T("REMOVE=ALL REBOOT=ReallySuppress DISABLE_REBOOT_PROMPT=1");

for (size_t i = 0; i < sizeof(UpgradeCodes) / sizeof(UpgradeCodes[0]); i++)
{
   tstring tstrUpgradeCode = UpgradeCodes[i];

   DWORD dwIndex = 0;
   size_t status;

   // for each of the upgrade code, get all the products
   do
   {
       status = MsiEnumRelatedProducts(UpgradeCodes[i], 
                                       0, 
                                       dwIndex, 
                                       lpProductCode);
       if (ERROR_SUCCESS == status)
       {
          UINT uiReturn = MsiConfigureProductEx(lpProductCode, 
                                                INSTALLLEVEL_DEFAULT, 
                                                INSTALLSTATE_DEFAULT, 
                                                tszNoReboot);

          if (ERROR_SUCCESS_REBOOT_REQUIRED == uiReturn)
          {
               // prompt for reboot at the end of all modules uninstallation.
          }

          if (ERROR_SUCCESS != uiReturn)
          {
              // log message with return code.

              // Error Code: 1605 is coming from here.
          }
       }
   }while (ERROR_NO_MORE_ITEMS != status);
}

解决方案

It is possible that a previous uninstall of that product of yours left something registered upon uninstall, and this is causing all the problems. I would try to check with scripts what is registered on the system.

Found good discussions of retrieving product info with VBScript here, a couple of really good scripts - recommended. Go to the sites to find the scripts, they format pretty poorly here and clog the answer.

The Windows Installer database is mostly located here:

  • HKEY_CLASSES_ROOT\Installer\
  • The upgrade code section: HKEY_CLASSES_ROOT\Installer\UpgradeCodes

You must never touch anything in the Windows Installer Database Registry directly. It's extremely interconnected and easy to corrupt. Only go through the APIs. Note that the GUIDs in the registry are packed, so you won't find the GUIDs from the package in the registry.

  • Packed GUID: 03B1692A57845354EA63AD602436AB05
  • Regular GUID: {A2961B30-4875-4535-AE36-DA064263BA50}

Using the VBScripts above and the registry data directly for inspection you should be able to determine what is happening in the Windows Installer database.

这篇关于卸载软件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆