Disinstallazione di patch

A partire da Windows Installer 3.0, è possibile disinstallare alcune patch dalle applicazioni. La patch deve essere una patch disinstallabile. Quando si usa una versione di Windows Installer minore della versione 3.0, la rimozione delle patch richiede la disinstallazione del prodotto patch e la reinstallazione del prodotto senza applicare la patch.

Windows Installer 2.0: Non supportato. Le patch applicate usando una versione di Windows Installer precedente a Windows Installer 3.0 non sono disinstallabili.

Quando si richiama una disinstallazione di una patch da uno dei metodi seguenti, il programma di installazione tenta di rimuovere la patch dal primo prodotto visibile all'applicazione o all'utente che richiede la disinstallazione. Il programma di installazione cerca prodotti con patch nell'ordine seguente: per utente gestito, per utente non gestito, per computer non gestito.

Disinstallazione di una patch usando MSIPATCHREMOVE in una riga di comando

È possibile disinstallare le patch da un comando usando msiexec.exe e le opzioni della riga di comando. La riga di comando di esempio seguente rimuove una patch disinstallabile, ad esempio.msp, da un'applicazione, example.msi, usando la proprietà MSIPATCHREMOVE e l'opzione della riga di comando /i. Quando si usa /i, l'applicazione con patch può essere identificata dal percorso del pacchetto dell'applicazione (.msi file) o dal codice prodotto dell'applicazione. In questo esempio il pacchetto di installazione dell'applicazione si trova in "\\server\share\products\example\example.msi" e la proprietà ProductCode dell'applicazione è "{0C9840E7-7F0B-C648-10F0-4641926FE463}". Il pacchetto patch si trova in "\\server\share\products\example\patches\example.msp" e il GUID del codice patch è "{EB8C947C-78B2-85A0-644D-86CEEF8E07C0}".

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

Disinstallazione di una patch usando le opzioni della riga di comando standard

A partire da Windows Installer versione 3.0, è possibile usare le opzioni della riga di comando standard usate dal sistema operativo Microsoft Windows Aggiornamenti (update.exe) per disinstallare le patch di Windows Installer da una riga di comando.

La riga di comando seguente è l'equivalente della riga di comando standard della riga di comando di Windows Installer usata per disinstallare una patch usando la proprietà MSIPATCHREMOVE . L'opzione /uninstall usata con l'opzione /package indica la disinstallazione di una patch. La patch può essere fatto riferimento al percorso completo della patch o dal GUID del codice patch.

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

Nota

L'opzione /passivo standard non è un equivalente esatto dell'opzione Windows Installer /qb.

 

Disinstallazione di una patch usando il metodo RemovePatches

È possibile disinstallare le patch dallo script usando l'interfaccia di automazione di Windows Installer. L'esempio di scripting seguente rimuove una patch disinstallabile, ad esempio.msp, da un'applicazione, example.msi, usando il metodo RemovePatches dell'oggetto Installer . Ogni patch disinstallata può essere rappresentata dal percorso completo del pacchetto patch o dal GUID del codice patch. In questo esempio il pacchetto di installazione dell'applicazione si trova in "\\server\share\products\example\example.msi" e la proprietà ProductCode dell'applicazione è "{0C9840E7-7F0B-C648-10F0-4641926FE463}". Il pacchetto patch si trova in "\\server\share\products\example\patches\example.msp" e il GUID del codice patch è "{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, "")

Disinstallazione di una patch con Programmi di aggiunta/rimozione

Con Windows XP è possibile disinstallare le patch usando i programmi Aggiungi/Rimuovi.

Disinstallazione di una patch usando la funzione MsiRemovePatches

Le applicazioni possono disinstallare le patch da altre applicazioni usando Le funzioni di Windows Installer. Nell'esempio di codice seguente viene rimossa una patch disinstallabile, ad esempio.msp, da un'applicazione, example.msi, usando la funzione MsiRemovePatches . Una patch può essere fatto riferimento al percorso completo del pacchetto patch o al GUID del codice patch. In questo esempio il pacchetto di installazione dell'applicazione si trova in "\\server\share\products\example\example.msi" e la proprietà ProductCode dell'applicazione è "{0C9840E7-7F0B-C648-10F0-4641926FE463}". Il pacchetto patch si trova in "\\server\share\products\example\patches\example.msp" e il GUID del codice patch è "{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);

Disinstallazione di una patch da tutte le applicazioni usando la funzione MsiRemovePatches

Una singola patch può aggiornare più di un prodotto nel computer. Un'applicazione può usare MsiEnumProductsEx per enumerare tutti i prodotti nel computer e determinare se è stata applicata una patch a una determinata istanza del prodotto. L'applicazione può quindi disinstallare la patch usando MsiRemovePatches. Ad esempio, una singola patch può aggiornare più prodotti se la patch aggiorna un file in un componente condiviso da più prodotti e la patch viene distribuita per aggiornare entrambi i prodotti.

Nell'esempio seguente viene illustrato come un'applicazione può usare Windows Installer per rimuovere una patch da tutte le applicazioni disponibili per l'utente. Non rimuove la patch dalle applicazioni installate per utente per un altro utente.

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

Sequenziazione di patch

Rimozione di patch

Patch disinstallabili

Patch Disinstalla azioni personalizzate

MSIPATCHREMOVE

MsiEnumapplicationsEx

MsiGetPatchInfoEx

MsiRemovePatches