首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >卸载软件

卸载软件
EN

Stack Overflow用户
提问于 2013-10-31 01:22:22
回答 3查看 2.2K关注 0票数 8

我的产品有一个可执行的助手来卸载所有相关的子产品.我卸载基于升级代码的所有子产品.

首先,我使用MsiEnumRelatedProducts函数从升级代码中获取产品代码。然后我尝试使用MsiConfigureProductEx函数卸载该产品。

问题是MsiConfigureProductEx正在返回错误。

被调用的函数: MsiConfigureProductsEx 返回代码: 1605 (0x00000645) 描述:此操作仅对当前已安装的产品有效。

为什么MsiEnumRelatedProducts返回无效的产品代码?我在windows注册表中搜索,以确定是否存在这样的产品代码。根本就没有。如何调试此问题?

编辑:添加了复制问题的最小代码。

代码语言:javascript
运行
复制
// 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);
}
EN

回答 3

Stack Overflow用户

发布于 2014-03-18 03:32:53

一些年过去了,我想添加两个可以用于导出MSI包信息的启动程序:如何找到已安装的MSI安装程序的产品GUID? - in 第2节。 请访问上面的链接,但是这里有指向脚本的直接链接:1) html导出版本2) 更简单的文本输出

免责声明:以下信息非常“隐藏”。无论何时,请使用API调用来访问MSI数据库。此外,请记住在虚拟机上运行所有MSI测试,这样您就可以轻松地恢复到“干净状态”。在MSI开发过程中,可能会发生奇怪的事情。

这是可能的,以前卸载您的产品留下了一些注册在卸载,这是导致所有的问题。我会试着用脚本来检查系统上注册的内容。

在这里找到了关于用recommended.检索产品信息的很好的讨论,这里有一些非常好的脚本-- VBScript。去网站找脚本,它们在这里的格式很差,并堵塞了答案。

  • http://forum.installsite.net/index.php?act=ST&f=26&t=14035
  • http://www.dwarfsoft.com/blog/2010/06/22/msi-package-code-fun/

Windows数据库主要位于以下位置:

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

你绝不能直接接触中的任何东西。非常互联,很容易被破坏。只需要通过API。注意,注册表中的GUID是打包的,所以您不会从注册表中的包中找到GUID。

  • 包装GUID:03B1692A57845354EA63AD602436AB05
  • 正则GUID:{A2961B30-4875-4535-AE36-DA064263BA50}

使用上面的VBScripts和注册表数据直接进行检查,您应该能够确定Windows数据库中发生了什么。

票数 5
EN

Stack Overflow用户

发布于 2014-03-18 01:47:52

我绝不会在C++中直接测试这一点。相反,我可以通过尝试PowerShellVBScript来确定卸载例程的问题,从而消除一些复杂性。您可以在这条线中找到有关如何使用这些脚本工具的信息。而这里是另一个线程。

  • 现在还不清楚是否有一些卸载工作,是否有一个失败,或者卸载操作是否完全失败?这是第一个问题。
  • 您是否尝试过手动卸载添加/删除中的所有产品,以确保它们都手动正确卸载?其中一个产品可能在卸载过程中触发一个错误返回代码,该代码会被编程捕获,但在手动安装过程中会被忽略。通常情况下,这些可以来自InstallFinalize.之后放置的自定义操作在这种情况下,需要重新设计一些设置。在最简单的情况下,它将涉及禁用自定义操作的错误检查,但在我看来,这个修复还不够好。
  • 这是可能的产品安装,但每个用户的.换句话说,它可能只安装在机器上的单个用户,而不是机器上(这是由阿卢塞尔斯属性控制的)。如果是这样的话,我不知道这个功能是如何工作的--它甚至可以按照广告的方式报告产品(可以通过快捷方式按需安装,但没有实际安装)。再一次,我没有尝试这个,卸载可能仍然有效。从我头上跳下来给你指点。
  • 作为产品安装的一部分,您是否执行过现有MSI文件的主要升级

还有一个问题:您是运行在Windows8上的吗?这些MSI文件是用WIX或其他工具生成的吗?有一些关于看起来至少有点相似的问题的间歇性报道。

票数 2
EN

Stack Overflow用户

发布于 2014-03-19 18:38:10

如果您有包安装程序(如Microsoft ),则它可以在安装阶段安装大量其他项。

稍后,当您卸载大型包安装程序时,理论上应该删除安装程序添加到系统中的所有项。

因此,尝试卸载您的应用程序,停止,然后查看其他较小的应用程序是否还在系统上。

如果是,则需要在启动自定义卸载脚本时卸载这些单独的应用程序( first )。

我想您已经有了一个System.Configuration.Install.Installer类。在安装应用程序(1、2、3等)时,遵循一组步骤,然后在卸载应用程序(3、2、1)时按相反顺序执行这些步骤。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19696828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档