インストール コンテキストを決定する
アプリケーションは、MsiEnumProducts または MsiEnumProductsEx 関数を呼び出して、システムにインストールまたはアドバタイズされている製品を列挙できます。 この関数は、コンピューターごとのインストール コンテキストでインストールされているすべての製品を列挙できます。 現在のユーザーのユーザーごとのコンテキストでインストールされている製品を列挙できます。 アプリケーションでは、MsiGetProductInfoEx または MsiGetProductInfo 関数を呼び出すことによって、これらの製品のコンテキストに関する情報を取得できます。
Windows インストーラーは、管理者以外のユーザーのために昇格された (システム) 特権で実行するように製品をインストールできます。 これには、管理者ユーザーのアクセス許可が必要です。 昇格された特権でインストールされる製品は、"管理対象" と呼ばれます。コンピューターごとにインストールされるすべての製品が管理対象になります。 ユーザーごとにインストールされる製品は、ローカル システム エージェントがユーザーを偽装している間にアドバタイズを実行した場合にのみ管理対象になります。 これは、グループ ポリシーによるソフトウェアの展開で使われる方法です。 AlwaysInstallElevated ポリシーが設定されている間にインストールされたユーザーごとのアプリケーションは、管理対象とは見なされません。 MsiIsProductElevated を呼び出すことで、アプリケーションは特定の製品が管理対象かどうかをチェックできます。
次の例では、アプリケーションで MsiEnumProducts、MsiGetProductInfo、MsiIsProductElevated を使ってコンテキストを決定する方法を示します。
#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;
}
関連トピック