Aplicação de patch em aplicativos gerenciados por usuário
A partir do Windows Installer 3.0, é possível aplicar patches a um aplicativo que foi instalado em um contexto gerenciado por usuário depois que o patch é registrado como tendo privilégios elevados.
Windows Installer 2.0: sem suporte. Não é possível aplicar patches aos aplicativos instalados em um contexto gerenciado por usuário usando versões do Windows Installer anteriores ao Windows Installer 3.0.
Um aplicativo é instalado no estado por usuário gerenciado nos casos a seguir.
- A instalação por usuário do aplicativo foi executada por meio da implantação e da Política de Grupo.
- O aplicativo foi anunciado para um usuário especificado e instalado pelo método descrito em Como anunciar um aplicativo por usuário a ser instalado com privilégios elevados.
Os privilégios são necessários para instalar um aplicativo no contexto gerenciado por usuário. Portanto, reinstalações ou reparos futuros do Windows Installer do aplicativo também são executados pelo instalador usando privilégios elevados. Isso significa que somente patches de fontes confiáveis podem ser aplicados ao aplicativo.
A partir do Windows Installer 3.0, você pode aplicar um patch a um aplicativo gerenciado por usuário depois que o patch é registrado como tendo privilégios elevados. Para registrar um patch como tendo privilégios elevados, use a função MsiSourceListAddSourceEx ou o método SourceListAddSource do objeto Patch, com privilégios elevados. Depois de registrar o patch, você pode aplicar o patch usando as funções MsiApplyPatch ou MsiApplyMultiplePatches, os métodos ApplyPatch ou ApplyMultiplePatches do objeto Installer ou a opção de linha de comando /p.
Observação
Um patch pode ser registrado como tendo privilégios elevados antes que o aplicativo seja instalado. Quando um patch é registrado, ele permanece registrado até que o último aplicativo registrado desse patch seja removido.
Os patches que foram aplicados a um aplicativo gerenciado por usuário não podem ser removidos sem a remoção de todo o aplicativo. Os registros de patch para um aplicativo gerenciado por usuário são removidos após a remoção do aplicativo.
Use também esse método para permitir a um não administrador aplicar um patch a um aplicativo por computador ou use a aplicação de patch de privilégios mínimos descrita em Aplicação de patch do UAC (Controle de Conta de Usuário).
Exemplo 1
O exemplo de script a seguir usa o método SourceListAddSource para registrar um pacote de patch localizado em \\server\share\products\patches\example.msp como tendo privilégios elevados. Em seguida, esse fica pronto para ser aplicado a um produto gerenciado por usuário.
const msiInstallContextUserManaged = 1
const msiInstallSourceTypeNetwork = 1
const PatchCode = "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
const UserSid = "S-X-X-XX-XXXXXXXXX-XXXXXXXXX-XXXXXXXXX-XXXXXXX"
const PatchPath = "\\server\share\products\patches\"
const PatchPackageName = "example.msp"
Dim installer
Set installer = CreateObject("WindowsInstaller.Installer")
Set patch = installer.Patch(PatchCode, "", UserSid, msiInstallContextUserManaged)
patch.SourceListAddSource msiInstallSourceTypeNetwork, PatchPath, 0
patch.SourceListInfo("PackageName") = PatchPackageName
Exemplo 2
O exemplo de código a seguir usa a função MsiSourceListAddSourceEx para registrar um pacote de patch localizado em \\server\share\products\patches\example.msp como tendo privilégios elevados. Em seguida, esse fica pronto para ser aplicado a um produto gerenciado por usuário.
#ifndef UNICODE
#define UNICODE
#endif // UNICODE
#ifndef _WIN32_MSI
#define _WIN32_MSI
#endif // _WIN32_MSI
#include <windows.h>
#include <msi.h>
/////////////////////////////////////////////////////////////////
// RegisterElevatedPatch
//
// Purpose: register a patch elevated from a network location
//
// Arguments:
// wszPatchCode <entity type="ndash"/> GUID of patch to be registered
// wszUserSid - String SID that specifies the user account
// wszPatchPath <entity type="ndash"/> Network location of patch
// wszPatchPackageName <entity type="ndash"/> Package name of patch
//
/////////////////////////////////////////////////////////////////
UINT RegisterElevatedPatch(LPCWSTR wszPatchCode,
LPCWSTR wszUserSid,
LPCWSTR wszPatchPath,
LPCWSTR wszPatchPackageName)
{
// wszUserSid can be NULL
// when wszUserSid is NULL, register patch for current user
// current user must be administrator
if (!wszPatchCode || !wszPatchPath || !wszPatchPackageName)
return ERROR_INVALID_PARAMETER;
UINT uiReturn = ERROR_SUCCESS;
uiReturn = MsiSourceListAddSourceEx(
/*szPatchCode*/ wszPatchCode,
/*szUserSid*/ wszUserSid,
/*dwContext*/ MSIINSTALLCONTEXT_USERMANAGED,
/*dwOptions*/ MSISOURCETYPE_NETWORK+MSICODE_PATCH,
/*szSource*/ wszPatchPath,
/*dwIndex*/ 0);
if (ERROR_SUCCESS == uiReturn)
{
uiReturn = MsiSourceListSetInfo(
/*szPatchCode*/ wszPatchCode,
/*szUserSid*/ wszUserSid,
/*dwContext*/ MSIINSTALLCONTEXT_USERMANAGED,
/*dwOptions*/ MSISOURCETYPE_NETWORK+MSICODE_PATCH,
/*szProperty*/ L"PackageName",
/*szValue*/ wszPatchPackageName);
if (ERROR_SUCCESS != uiReturn)
{
// Function call failed, return error code
return uiReturn;
}
}
else
{
// Function call failed, return error code
return uiReturn;
}
return ERROR_SUCCESS;
}