설치 컨텍스트 확인

애플리케이션은 MsiEnumProducts 또는 MsiEnumProductsEx 함수를 호출하여 시스템에 설치 또는 보급된 제품을 열거할 수 있습니다. 이 함수는 컴퓨터별 설치 컨텍스트에 설치된 모든 제품을 열거할 수 있습니다. 현재 사용자의 사용자별 컨텍스트에 설치된 제품을 열거할 수 있습니다. 애플리케이션은 MsiGetProductInfoEx 또는 MsiGetProductInfo 함수를 호출하여 이러한 제품의 컨텍스트에 대한 정보를 검색할 수 있습니다.

Windows Installer는 관리자가 아닌 사용자에 대해 상승된 권한(시스템)으로 실행할 제품을 설치할 수 있습니다. 이렇게 하려면 관리자 사용자의 권한이 필요합니다. 상승된 권한으로 설치된 제품을 "관리형"이라고 합니다. 컴퓨터별로 설치된 모든 제품이 관리형입니다. 사용자별로 설치된 제품은 로컬 시스템 에이전트가 사용자를 가장하여 보급을 수행하는 경우에만 관리형입니다. 그룹 정책을 통한 소프트웨어 배포에서 사용하는 방법입니다. AlwaysInstallElevated 정책이 설정된 동안 설치된 사용자별 애플리케이션은 관리형으로 간주되지 않습니다. 애플리케이션은 MsiIsProductElevated를 호출하여 특정 제품이 관리형인지 여부를 확인할 수 있습니다.

다음 샘플에서는 MsiEnumProducts, MsiGetProductInfoMsiIsProductElevated를 사용하여 애플리케이션이 컨텍스트를 결정하는 방법을 보여줍니다.

#ifndef UNICODE
#define UNICODE
#endif //UNICODE

#ifndef _WIN32_MSI
#define _WIN32_MSI 200
#endif //_WIN32_MSI

#include <stdio.h>
#include <windows.h>
#include <msi.h>
#pragma comment(lib, "msi.lib")

const int cchGUID = 38;

UINT DetermineContextForAllProducts()
{
    WCHAR wszProductCode[cchGUID+1] = {0};
    WCHAR wszAssignmentType[10] = {0};
    DWORD cchAssignmentType = 
            sizeof(wszAssignmentType)/sizeof(wszAssignmentType[0]);
    DWORD dwIndex = 0;

    DWORD cchProductName = MAX_PATH;
    WCHAR* lpProductName = new WCHAR[cchProductName];
    if (!lpProductName)
    {
        return ERROR_OUTOFMEMORY;
    }

    UINT uiStatus = ERROR_SUCCESS;

    // enumerate all visible products
    do
    {
        uiStatus = MsiEnumProducts(dwIndex,
                          wszProductCode);
        if (ERROR_SUCCESS == uiStatus)
        {
            cchAssignmentType = 
                sizeof(wszAssignmentType)/sizeof(wszAssignmentType[0]);
            BOOL fPerMachine = FALSE;
            BOOL fManaged = FALSE;

            // Determine assignment type of product
            // This indicates whether the product
            // instance is per-user or per-machine
            if (ERROR_SUCCESS == 
                MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_ASSIGNMENTTYPE,wszAssignmentType,&cchAssignmentType))
            {
                if (L'1' == wszAssignmentType[0])
                    fPerMachine = TRUE;
            }
            else
            {
                // This halts the enumeration and fails. Alternatively the error
                // could be logged and enumeration continued for the
                // remainder of the products
                uiStatus = ERROR_FUNCTION_FAILED;
                break;
            }

            // determine the "managed" status of the product.
            // If fManaged is TRUE, product is installed managed
            // and runs with elevated privileges.
            // If fManaged is FALSE, product installation operations
            // run as the user.
            if (ERROR_SUCCESS != MsiIsProductElevated(wszProductCode,
                                         &fManaged))
            {
                // This halts the enumeration and fails. Alternatively the error
                // could be logged and enumeration continued for the
                // remainder of the products
                uiStatus = ERROR_FUNCTION_FAILED;
                break;
            }

            // obtain the user friendly name of the product
            UINT uiReturn = MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProductName,&cchProductName);
            if (ERROR_MORE_DATA == uiReturn)
            {
                // try again, but with a larger product name buffer
                delete [] lpProductName;

                // returned character count does not include
                // terminating NULL
                ++cchProductName;

                lpProductName = new WCHAR[cchProductName];
                if (!lpProductName)
                {
                    uiStatus = ERROR_OUTOFMEMORY;
                    break;
                }

                uiReturn = MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProductName,&cchProductName);
            }

            if (ERROR_SUCCESS != uiReturn)
            {
                // This halts the enumeration and fails. Alternatively the error
                // could be logged and enumeration continued for the
                // remainder of the products
                uiStatus = ERROR_FUNCTION_FAILED;
                break;
            }

            // output information
            wprintf(L" Product %s:\n", lpProductName);
            wprintf(L"\t%s\n", wszProductCode);
                        wprintf(L"\tInstalled %s %s\n", 
                fPerMachine ? L"per-machine" : L"per-user",
                fManaged ? L"managed" : L"non-managed");
        }
        dwIndex++;
    }
    while (ERROR_SUCCESS == uiStatus);

    if (lpProductName)
    {
        delete [] lpProductName;
        lpProductName = NULL;
    }

    return (ERROR_NO_MORE_ITEMS == uiStatus) ? ERROR_SUCCESS : uiStatus;
}

MsiEnumProducts

MsiGetProductInfo

MsiGetProductInfoEx

MsiIsProductElevated

비관리자에 대해 상승된 권한으로 패키지 설치

상승된 권한으로 설치할 사용자 단위 애플리케이션 보급

설치 컨텍스트