修补每用户托管应用程序
从 Windows Installer 3.0 开始,在将修补程序注册为使用提升的权限后,可以将修补程序应用于已在每用户托管上下文中安装的应用程序。
Windows Installer 2.0:不支持。 不能使用版本低于 3.0 的 Windows Installer 将修补程序应用于安装在每用户托管上下文中的应用程序。
在以下情况下,应用程序以按用户管理的状态安装。
- 应用程序的每用户安装是使用部署和组策略执行的。
- 应用程序已播发给指定用户,并通过播发每用户应用程序以使用提升的权限安装中所述的方法进行安装。
在每用户管理的上下文中安装应用程序需要权限;因此将来的 Windows Installer 重新安装或修复应用程序也由安装程序使用提升的权限执行。 这意味着只能将来自受信任源的修补程序应用于应用程序。
从 Windows Installer 3.0 开始,在修补程序注册为具有提升的权限后,可以将修补程序应用于每用户管理的应用程序。 若要将修补程序注册为具有提升的权限,请以提升的权限使用 MsiSourceListAddSourceEx 函数,或者 Patch 对象的 SourceListAddSource 方法。 注册修补程序后,可以通过以下方式来应用修补程序:使用 MsiApplyPatch 或 MsiApplyMultiplePatches 函数,使用 Installer Object 的 ApplyPatch 或 ApplyMultiplePatches 方法,或者使用 /p 命令行选项。
注意
在安装应用程序之前,可以将修补程序注册为具有提升的权限。 注册修补程序后,它将保持注册状态,直到移除此修补程序的最后一个注册应用程序。
如果不移除整个应用程序,则无法移除已应用于每用户托管应用程序的修补程序。 移除应用程序时,将移除每用户托管应用程序的修补程序注册。
还可以使用此方法使非管理员能够修补每台计算机的应用程序,也可以使用用户帐户控制 (UAC) 修补中所述的最低特权修补。
示例 1
以下脚本示例使用 SourceListAddSource 方法将位于 \\server\share\products\patchs\example.msp 的修补程序包注册为具有提升的权限。 然后,该修补程序即可应用于每用户托管产品。
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
示例 2
以下代码示例使用 MsiSourceListAddSourceEx 函数将位于 \\server\share\products\patchs\example.msp 的修补程序包注册为具有提升的权限。 然后,该修补程序即可应用于每用户托管产品。
#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;
}