失败的 MsiConfigureFeature 属性 抑制重启

failing MsiConfigureFeature with property suppress reboot

我正在尝试卸载我的功能并想禁止重新启动,但失败并出现错误 1618

   MsiOpenProductA(productCode, &handle))

    MsiSetPropertyA(handle, "REBOOT", "ReallySuppress");
    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);

    Ret = MsiConfigureFeatureA(
                            productCode,
                            feature,
                            INSTALLSTATE_ABSENT);
    if (ERROR_SUCCESS == Ret) {
        std::cout << "myFeature is uninstalled\n";
    }
    else {
        std::cout << "myFeature is not uninstalled "<<Ret<<std::endl;
    }

它失败并出现错误 1618,即另一个安装已经在进行中。在继续此安装之前完成该安装 我怀疑这是因为我打开了句柄。

任何人遇到这将是很大的帮助

简答:您不需要先打开产品,它启动两把锁而不是一把。以下是您可以用来测试的 Visual Studio 2019 样本。


过程:在运行下面的例子之前,请按如下操作:

  1. 运行 以管理员身份(以管理员身份启动 Visual Studio)。
  2. 将下面的产品代码更新为您自己的。 (vbscript).
#define WIN32_LEAN_AND_MEAN // Minimize includes from Windows.h
#include <iostream>
#include <windows.h>
#include <msi.h> // Windows Installer

#pragma comment(lib, "msi.lib") // To make code link

int main()
{
   // NB! RUN CODE WITH ADMIN RIGHTS

    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);

    // Put your own MSI's product code as the first parameter below:
    int r = MsiConfigureFeature(TEXT("{00000000-0000-0000-0000-000000000000}"), 
                                TEXT("FeatureName"), INSTALLSTATE_ABSENT);

    if (ERROR_SUCCESS == r) {
        std::cout << "myFeature is uninstalled\n";
    }
    else {
        std::cout << "myFeature is not uninstalled " << r << std::endl;
    }
}

Mutex: 只有一个 MSI InstallExecuteSequence can run at a time. A Mutex 在这个序列开始时被设置,然后没有其他那种序列可以开始直到第一个被释放。换句话说,OpenProduct 和 MsiConfigureFeature 都会尝试设置互斥量,但第二次尝试失败。

请参阅我的其他回答,了解导致您 error 1618 - and while we are at it, check this site to look up strange error codes: https://www.magnumdb.com/) 的技术细节。


新版本:这里是另一个版本的代码。它使用 ConfigureProductEx with a command line set to remove the feature. There might be better ways. Please test that this does not remove more features than it should. Please double check the documentation here(有限测试):

步骤:在运行下面的例子之前,请按如下操作:

  1. 运行 以管理员身份(以管理员身份启动 Visual Studio)。
  2. 将下面的产品代码更新为您自己的。 (vbscript).
#define WIN32_LEAN_AND_MEAN // Minimize includes from Windows.h
#include <windows.h>
#include <msi.h> // Windows Installer
#include <tchar.h> 

#pragma comment(lib, "msi.lib") // To make code link

int main()
{
    // NB! RUN CODE WITH ADMIN RIGHTS

    MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);

    // The below command line suppresses reboot and removes the specified feature
    const TCHAR commandline[] = _T("REBOOT=ReallySuppress REMOVE=FeatureNameToRemove");
    const TCHAR prodcode[39] = _T("{00000000-0000-0000-0000-000000000000}");

    UINT res = MsiConfigureProductEx(prodcode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, commandline);

    return res; // Error Codes: https://msdn.microsoft.com/en-us/library/windows/desktop/aa376931(v=vs.85).aspx
}

链接:

  • What does WIN32_LEAN_AND_MEAN实际上呢?
  • Uninstalling an MSI file from the command line without using msiexec(第 14 节在底部)