Удаление исправлений

Начиная с установщика Windows 3.0, можно удалить некоторые исправления из приложений. Исправление должно быть удаляемым. При использовании установщика Windows версии ниже версии 3.0 для удаления исправлений требуется удалить продукт исправления и переустановить продукт без применения исправления.

Установщик Windows 2.0: Не поддерживается. Исправления, примененные с помощью версии установщика Windows, более ранней, чем установщик Windows 3.0, не могут быть удалены.

При вызове удаления исправления с помощью любого из следующих методов установщик пытается удалить исправление из первого продукта, видимого приложению или пользователю, запрашивающим удаление. Установщик ищет продукты с исправлениями в следующем порядке: для каждого пользователя, для каждого пользователя неуправляемого, для каждого компьютера.

Удаление исправления с помощью MSIPATCHREMOVE в командной строке

Удалить исправления из команды можно с помощью msiexec.exe и параметров командной строки. В следующем примере командной строки удаляется удаляемое исправление example.msp из приложения example.msi с помощью свойства MSIPATCHREMOVE и параметра командной строки /i. При использовании /i исправленное приложение можно определить по пути к пакету приложения (.msi файл) или коду продукта приложения. В этом примере пакет установки приложения находится в папке "\\server\share\products\example\example.msi", а свойство ProductCode приложения — "{0C9840E7-7F0B-C648-10F0-4641926FE463}". Пакет исправлений находится в папке "\\server\share\products\example\patches\example.msp", а GUID кода исправления — "{EB8C947C-78B2-85A0-644D-86CEEF8E07C0}".

Msiexec /I {0C9840E7-7F0B-C648-10F0-4641926FE463} MSIPATCHREMOVE={EB8C947C-78B2-85A0-644D-86CEEF8E07C0} /qb

Удаление исправления с помощью стандартных параметров командной строки

Начиная с установщика Windows версии 3.0, для удаления исправлений установщика Windows из командной строки можно использовать стандартные параметры командной строки, используемые Обновления операционной системы Microsoft Windows (update.exe).

Следующая командная строка является стандартным эквивалентом командной строки установщика Windows, используемой для удаления исправления с помощью свойства MSIPATCHREMOVE . Параметр /uninstall, используемый с параметром /package, обозначает удаление исправления. На исправление можно ссылаться по полному пути к исправлению или по GUID кода исправления.

Msiexec /package {0C9840E7-7F0B-C648-10F0-4641926FE463} /uninstall {EB8C947C-78B2-85A0-644D-86CEEF8E07C0} /passive

Примечание

Стандартный параметр /passive не является точным эквивалентом параметра /qb установщика Windows.

 

Удаление исправления с помощью метода RemovePatches

Вы можете удалить исправления из скрипта с помощью интерфейса автоматизации установщика Windows. В следующем примере скрипта удаляется удаляемое исправление example.msp из приложения, example.msi с помощью метода RemovePatches объекта Installer . Каждое удаляемое исправление может быть представлено полным путем к пакету исправлений или GUID кода исправления. В этом примере пакет установки приложения находится в папке "\\server\share\products\example\example.msi", а свойство ProductCode приложения — "{0C9840E7-7F0B-C648-10F0-4641926FE463}". Пакет исправлений находится в папке "\\server\share\products\example\patches\example.msp", а GUID кода исправления — "{EB8C947C-78B2-85A0-644D-86CEEF8E07C0}".

const msiInstallTypeSingleInstance = 2
const PatchList = "{EB8C947C-78B2-85A0-644D-86CEEF8E07C0}"
const Product = "{0C9840E7-7F0B-C648-10F0-4641926FE463}"

Dim installer
Set installer = CreateObject("WindowsInstaller.Installer")

installer.RemovePatches(PatchList, Product, msiInstallTypeSingleInstance, "")

Удаление исправления с помощью функции "Установка и удаление программ"

В Windows XP можно удалять исправления с помощью команды Установка и удаление программ.

Удаление исправления с помощью функции MsiRemovePatches

Приложения могут удалять исправления из других приложений с помощью функций установщика Windows. В следующем примере кода удаляется удаляемое исправление example.msp из приложения, example.msi с помощью функции MsiRemovePatches . На исправление можно ссылаться с помощью полного пути к пакету исправлений или GUID кода исправления. В этом примере пакет установки приложения находится в папке "\\server\share\products\example\example.msi", а свойство ProductCode приложения — "{0C9840E7-7F0B-C648-10F0-4641926FE463}". Пакет исправлений находится в папке "\\server\share\products\example\patches\example.msp", а GUID кода исправления — "{EB8C947C-78B2-85A0-644D-86CEEF8E07C0}".

    UINT uiReturn = MsiRemovePatches(
          /*szPatchList=*/TEXT("\\server\\share\\products\\example\\patches\\example.msp"),
          /*szProductCode=*/  TEXT("{0C9840E7-7F0B-C648-10F0-4641926FE463}"),
          /*eUninstallType=*/ INSTALLTYPE_SINGLE_INSTANCE,
          /*szPropertyList=*/ NULL);

Удаление исправления из всех приложений с помощью функции MsiRemovePatches

Одно исправление может обновить несколько продуктов на компьютере. Приложение может использовать MsiEnumProductsEx для перечисления всех продуктов на компьютере и определения того, применено ли исправление к конкретному экземпляру продукта. Затем приложение может удалить исправление с помощью MsiRemovePatches. Например, одно исправление может обновить несколько продуктов, если оно обновляет файл в компоненте, совместно используемом несколькими продуктами, и это исправление распространяется для обновления обоих продуктов.

В следующем примере показано, как приложение может использовать установщик Windows для удаления исправления из всех приложений, доступных пользователю. Исправление не удаляется из приложений, установленных для каждого пользователя для другого пользователя.

#ifndef UNICODE
#define UNICODE
#endif //UNICODE

#ifndef _WIN32_MSI
#define _WIN32_MSI 300
#endif //_WIN32_MSI

#include <stdio.h>
#include <windows.h>
#include <msi.h>

#pragma comment(lib, "msi.lib")

const int cchGUID = 38;

///////////////////////////////////////////////////////////////////
// RemovePatchFromAllVisibleapplications:
//
// Arguments:
//    wszPatchToRemove - GUID of patch to remove
//
///////////////////////////////////////////////////////////////////
//
UINT RemovePatchFromAllVisibleapplications(LPCWSTR wszPatchToRemove)
{
    if (!wszPatchToRemove)
        return ERROR_INVALID_PARAMETER;

    UINT uiStatus = ERROR_SUCCESS;
    DWORD dwIndex = 0;
    WCHAR wszapplicationCode[cchGUID+1] = {0};

    DWORD dwapplicationSearchContext = MSIINSTALLCONTEXT_ALL;
    MSIINSTALLCONTEXT dwInstallContext = MSIINSTALLCONTEXT_NONE;

    do
    {
        // Enumerate all visible applications in all contexts for the caller.
        // NULL for szUserSid defaults to using the caller's SID
        uiStatus = MsiEnumProductsEx(/*szapplicationCode*/NULL,
         /*szUserSid*/NULL,
         dwapplicationSearchContext,
         dwIndex,
         wszapplicationCode,
         &dwInstallContext,
         /*szSid*/NULL,
         /*pcchSid*/NULL);

        if (ERROR_SUCCESS == uiStatus)
        {
            // check to see if the provided patch is
            // registered for this application instance
            UINT uiPatchStatus = MsiGetPatchInfoEx(wszPatchToRemove,
             wszapplicationCode,
             /*szUserSid*/NULL,
             dwInstallContext,
             INSTALLPROPERTY_PATCHSTATE,
             NULL,
             NULL);

            if (ERROR_SUCCESS == uiPatchStatus)
            {
                // patch is registered to this application; remove patch
                wprintf(L"Removing patch %s from application %s...\n",
                 wszPatchToRemove, wszapplicationCode);
                                
                UINT uiRemoveStatus = MsiRemovePatches(
                 wszPatchToRemove,
                 wszapplicationCode,
                 INSTALLTYPE_SINGLE_INSTANCE,
                 L"");

                if (ERROR_SUCCESS != uiRemoveStatus)
                {
                    // This halts the enumeration and fails. Alternatively
                    // you could output an error and continue the
                    // enumeration
                     return ERROR_FUNCTION_FAILED;
                }
            }
            else if (ERROR_UNKNOWN_PATCH != uiPatchStatus)
            {
                // Some other error occurred during processing. This
                // halts the enumeration and fails. Alternatively you
                // could output an error and continue the enumeration
                 return ERROR_FUNCTION_FAILED;
            }
            // else patch was not applied to this application
            // (ERROR_UNKNOWN_PATCH returned)
        }

        dwIndex++;
    }
    while (uiStatus == ERROR_SUCCESS);

    if (ERROR_NO_MORE_ITEMS != uiStatus)
        return ERROR_FUNCTION_FAILED;

    return ERROR_SUCCESS;
}

Секвенирование исправлений

Удаление исправлений

Удаляемые исправления

Исправление удаления пользовательских действий

MSIPATCHREMOVE

MsiEnumapplicationsEx

MsiGetPatchInfoEx

MsiRemovePatches