Deinstallieren von Patches

Ab Windows Installer 3.0 ist es möglich, einige Patches aus Anwendungen zu deinstallieren. Der Patch muss ein deinstallierbarer Patch sein. Wenn Sie eine ältere Windows Installer-Version als 3.0 verwenden, müssen Sie zum Entfernen von Patches das Patchprodukt deinstallieren und das Produkt erneut installieren, ohne den Patch anzuwenden.

Windows Installer 2.0: Nicht unterstützt. Patches, die mit einer früheren Version von Windows Installer als Windows Installer 3.0 angewendet werden, können nicht deinstalliert werden.

Wenn Sie eine Deinstallation eines Patch mit einer der folgenden Methoden aufrufen, versucht das Installationsprogramm, den Patch aus dem ersten Produkt zu entfernen, das für die Anwendung oder den*die Benutzer*in sichtbar ist, der bzw. die die Deinstallation anfordert. Das Installationsprogramm sucht in der folgenden Reihenfolge nach gepatchten Produkten: verwaltet pro Benutzer*in, nicht verwaltet pro Benutzer*in, pro Computer.

Deinstallieren eines Patch mithilfe von MSIPATCHREMOVE über eine Befehlszeile

Sie können Patches über einen Befehl mithilfe von „msiexec.exe“ und den Befehlszeilenoptionen deinstallieren. Die folgende Beispielbefehlszeile entfernt mithilfe der Eigenschaft MSIPATCHREMOVE und der Befehlszeilenoption „/i“ einen deinstallierbaren Patch (example.msp) aus einer Anwendung (example.msi). Bei Verwendung von „/i“ kann die gepatchte Anwendung anhand des Pfads zum Anwendungspaket (MSI-Datei) oder anhand des Produktcodes der Anwendung identifiziert werden. In diesem Beispiel befindet sich das Installationspaket der Anwendung unter „\\server\share\products\example\example.msi“, und die ProductCode-Eigenschaft der Anwendung lautet „{0C9840E7-7F0B-C648-10F0-4641926FE463}“. Das Patchpaket befindet sich unter „\\server\share\products\example\patches\example\example.msp“, und die Patchcode-GUID lautet „{EB8C947C-78B2-85A0-644D-86CEEF8E07C0}“.

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

Deinstallieren eines Patch mithilfe der Standardbefehlszeilenoptionen

Ab Windows Installer Version 3.0 können Sie die standardmäßigen Befehlszeilenoptionen verwenden, die von Microsoft Windows-Betriebssystemupdates (update.exe) zum Deinstallieren von Windows Installer-Patches über eine Befehlszeile verwendet werden.

Die folgende Standardbefehlszeile entspricht der Windows Installer-Befehlszeile, die zum Deinstallieren eines Patches mithilfe der MSIPATCHREMOVE-Eigenschaft verwendet wird. Die Option „/uninstall“, die mit der Option „/package“ verwendet wird, kennzeichnet die Deinstallation eines Patches. Auf den Patch kann durch den vollständigen Pfad zum Patch oder durch die Patchcode-GUID verwiesen werden.

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

Hinweis

Die Standardoption „/passive“ entspricht nicht exakt der Option „/qb“ von Windows Installer.

 

Deinstallieren eines Patch mithilfe der RemovePatches-Methode

Sie können Patches über das Skript deinstallieren, indem Sie die Automatisierungsschnittstelle von Windows Installer verwenden. Im folgenden Skriptbeispiel wird mithilfe der RemovePatches-Methode des Installer-Objekts ein deinstallierbarer Patch (example.msp) aus einer Anwendung (example.msi) entfernt. Jeder zu deinstallierende Patch kann entweder durch den vollständigen Pfad zum Patchpaket oder die Patchcode-GUID dargestellt werden. In diesem Beispiel befindet sich das Installationspaket der Anwendung unter „\\server\share\products\example\example.msi“, und die ProductCode-Eigenschaft der Anwendung lautet „{0C9840E7-7F0B-C648-10F0-4641926FE463}“. Das Patchpaket befindet sich unter „\\server\share\products\example\patches\example\example.msp“, und die Patchcode-GUID lautet „{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, "")

Deinstallieren eines Patches mithilfe von „Software“

Unter Windows XP können Sie Patches mithilfe von „Software“ deinstallieren.

Deinstallieren eines Patch mithilfe der MsiRemovePatches-Funktion

Ihre Anwendungen können Patches aus anderen Anwendungen mithilfe der Windows Installer-Funktionen deinstallieren. Im folgenden Codebeispiel wird mithilfe der MsiRemovePatches-Funktion ein deinstallierbarer Patch (example.msp) aus einer Anwendung (example.msi) entfernt. Auf einen Patch kann durch den vollständigen Pfad zum Patchpaket oder durch die Patchcode-GUID verwiesen werden. In diesem Beispiel befindet sich das Installationspaket der Anwendung unter „\\server\share\products\example\example.msi“, und die ProductCode-Eigenschaft der Anwendung lautet „{0C9840E7-7F0B-C648-10F0-4641926FE463}“. Das Patchpaket befindet sich unter „\\server\share\products\example\patches\example\example.msp“, und die Patchcode-GUID lautet „{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);

Deinstallieren eines Patch aus allen Anwendungen mithilfe der MsiRemovePatches-Funktion

Ein einzelner Patch kann mehrere Produkte auf dem Computer aktualisieren. Eine Anwendung kann MsiEnumProductsEx verwenden, um alle Produkte auf dem Computer aufzulisten und zu bestimmen, ob ein Patch auf eine bestimmte Instanz des Produkts angewendet wurde. Die Anwendung kann dann den Patch mithilfe von MsiRemovePatches deinstallieren. Beispielsweise kann ein einzelner Patch mehrere Produkte aktualisieren, wenn der Patch eine Datei in einer Komponente aktualisiert, die von mehreren Produkten gemeinsam genutzt wird, und der Patch verteilt wird, um beide Produkte zu aktualisieren.

Im folgenden Beispiel wird veranschaulicht, wie eine Anwendung Windows Installer verwenden kann, um einen Patch aus allen Anwendungen zu entfernen, die dem*der Benutzer*in zur Verfügung stehen. Der Patch wird nicht aus Anwendungen entfernt, die pro Benutzer*in für einen anderen Benutzer bzw. eine andere Benutzerin installiert werden.

#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;
}

Patchsequenzierung

Entfernen von Patches

Deinstallierbare Patches

Benutzerdefinierte Aktionen für die Patchdeinstallation

MSIPATCHREMOVE

MsiEnumapplicationsEx

MsiGetPatchInfoEx

MsiRemovePatches