修補Per-User受控應用程式
從 Windows Installer 3.0 開始,可以在修補程式註冊為具有提高許可權之後,將修補程式套用至已安裝于每個使用者管理內容中的應用程式。
Windows Installer 2.0: 不支援。 您無法使用 Windows Installer 3.0 之前的 Windows Installer 版本,將修補程式套用至安裝在每個使用者受控內容中的應用程式。
在下列案例中,應用程式會以每個使用者管理的狀態安裝。
- 應用程式的每個使用者安裝是使用部署和群組原則來執行。
- 應用程式已公告給指定的使用者,並由 Advertising a Per-User Application To Be Install with Elevated Privileges中所述的方法安裝。
需要有許可權,才能在每個使用者管理的內容中安裝應用程式;因此,未來的 Windows Installer 重新安裝或修復應用程式也會由安裝程式使用提高的許可權來執行。 這表示只有來自受信任來源的修補程式可以套用至應用程式。
從 Windows Installer 3.0 開始,您可以在修補程式註冊為具有提高許可權之後,將修補程式套用至每個使用者受控應用程式。 若要將修補程式註冊為具有提高許可權,請使用MsiSourceListAddSourceEx函式或Patch物件的SourceListAddSource方法,並具有提高的許可權。 註冊修補程式之後,您可以使用Installer 物件的MsiApplyPatch或MsiApplyMultiplePatches函式、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;
}