Table | Purpose |
Class | Information about COM servers installed by this product. Links one-to-one to Component. |
Component | Information about components installed by this product. |
Feature | Information about features installed by this product. |
FeatureComponents | Mapping from Feature to Component. This is a many-to-many relationship. That is, a single component can be shared among multiple features, and a single feature can be composed of multiple components. |
File | Information about files installed by this product. Links many-to-one to Component, each file is part of only one component. |
InstallExecuteSequence | List of actions to be performed to install this product. |
InstallUISequence | List of user interface items to show prior to installing this product. This could be used to collect user information, installation options, and so on. |
Property | List of property values for the product. Properties can be used as conditions and can be changed during installation to record events. |
PublishComponent | Used for qualified components. Links to Component. |
Registry | Information about registry entries to be written when a component is installed. Links many-to-one to Component, each registry entry is part of only one component. |
RemoveFile | Files that should be removed when a component is installed. Links many-to-one to Component. |
RemoveRegistry | Registry entries that should be removed when a component is installed. Links many-to-one to Component. |
SelfReg | For backwards compatibility with components that do not do their COM registration through Class (the preferred route). Links many-to-one to Component. |
Shortcut | Shortcuts that should be created for a component. Links many-to-one to Component. |
TypeLib | Visual Basic type library registration. Links many-to-one to Component. |
State | Meaning |
INSTALLSTATE_LOCAL | The feature is installed on the local machine; that is, the feature's files live in C:\Program Files\MyProduct. |
INSTALLSTATE_SOURCE | The feature is installed and runs from the source installation media (a CD or network server). |
INSTALLSTATE_ABSENT | The feature is not installed. |
INSTALLSTATE_ADVERTISED | The feature is advertised, meaning it is available but not installed. |
Column | Type | Description |
ComponentID | GUID | The category GUID with which this published component is associated. |
Qualifier | Text | A text string that qualifies the value in the ComponentID column. A qualifier is used to distinguish multiple forms of the same component, such as a component that is implemented in multiple languages. This qualifier is referred to by the MsiProvideQualifiedComponent function and the MsiEnumComponentQualifiers function. |
AppData | Text | An optional localizable text string, owned and often parsed by the application. This can be retrieved with the MsiEnumComponentQualifiers function in the lpApplicationDataBuf buffer. |
Feature_ | Identifier | Together, the Se two columns provide the information for installing the component referred to by this qualifier. Both a Feature and a Component are needed because a component cannot be installed; the Owning feature must be installed. The Component ID identifies the particular file or path within the feature. |
Component_ | Identifier |
UINT MsiEnumComponentQualifiers(
LPTSTR szComponent, // component ID GUID (as a string)
DWORD iIndex, // 0-based index into component qualifiers
LPTSTR lpQualifierBuf, // buffer to return qualifier
DWORD *pcchQualifierBuf // in/out qualifier buffer character count
LPTSTR lpApplicationDataBuf, // buffer to return application data
DWORD *pcchApplicationDataBuf // in/out app data character count
)
UINT MsiProvideQualifiedComponent(
LPCTSTR szComponent, // component ID
LPCTSTR szQualifier, // specifies which component to access
DWORD dwInstallMode, // the install mode
LPTSTR lpPathBuf, // in/out returned path, NULL if not needed
DWORD *pcchPathBuf // in/out buffer character count
)
#include <windows.h>
#include <msi.h>
// --------------------------------------------------------------------------
// FindPerLangComponent()
// Locates and provides the required per-language component using
// MsiProvideQualifiedComponent. It first tries the LCID passed in as
// a qualifier; if that fails, it tries the primary language of that LCID.
// If neither succeeds, it returns the error code from
// MsiProvideQualifiedComponent for the last attempt, else ERROR_SUCCESS.
// The path to the component is returned in szPath if successful. The
// szComponentCode is the GUID of the qualified component as a string:
// TCHAR szComponent[]=TEXT("{5CB2D5F5-19DD-11d1-9A9D-006097C4E489}");
UINT FindPerLangComponent (
LPCTSTR szComponentCode, // GUID of the qual. Component
LCID lcid, // Requested language
LPTSTR szPath, // Buffer for returned path
DWORD *pcchPath) // size of buffer
{
DWORD cchPathInitial = *pcchPath;
TCHAR szQualifier[MAX_PATH];
UINT iResult;
*szPath = 0;
for (UINT i = 0; i < 2 ; i++)
{
wsprintf(szQualifier, TEXT("%4.4x"), i == 0 ?
LANGIDFROMLCID(lcid) :
PRIMARYLANGID(LANGIDFROMLCID(lcid)));
*pcchPath = cchPathInitial;
iResult = MsiProvideQualifiedComponent(szComponentCode,
szQualifier, INSTALLMODE_DEFAULT, szPath, pcchPath);
if ( iResult == ERROR_SUCCESS ||
iResult == ERROR_INSTALL_USEREXIT ||
iResult == ERROR_INSTALL_FAILURE)
break;
}
return iResult;
}
#include <windows.h>
#include <msi.h>
// --------------------------------------------------------------------------
// FGetFilePath()
// Returns the path to a setup-provided file using the Windows installer
// API. Handles both key and non-key files from a component. If the
// file is not installed, will install it if fInstall is TRUE. The
// szComponentCode is the GUID of the component as a string, e.g.:
// TCHAR szComponent[]=TEXT("{5CB2D5F5-19DD-11d1-9A9D-006097C4E489}");
// The product code for this application. This would be initialized when
// the application starts using MsiGetProductCode.
TCHAR vszProductCode[39] = {0}; // Room for a GUID string.
UINT FGetFilePath (
LPCTSTR szFeature, // Feature this component is part of
LPCTSTR szComponentCode, // GUID of the particular component
LPCTSTR szFileName, // File within component; can be NULL
// for key file of component.
BOOL fInstall, // TRUE to install if not present
BOOL fFix, // TRUE to reinstall even if present.
LPTSTR szPath, // Buffer for returned path
DWORD *pcchPath) // size of buffer
{
UINT cchPath = *pcchPath; // remember size of buffer
UINT is; // install state of component
DWORD er = ERROR_SUCCESS;
*szPath = 0;
is = MsiGetComponentPath(vszProductCode,
szComponentCode, szPath, pcchPath);
switch (is)
{
case INSTALLSTATE_DEFAULT:
case INSTALLSTATE_LOCAL:
case INSTALLSTATE_SOURCE:
// component is there
if (!fFix)
break;
// fall through to fix the component
case INSTALLSTATE_UNKNOWN:
// component is not there
// look up a level to determine installation state
// of the feature for this component.
is = MsiQueryFeatureState(vszProductCode, szFeature);
// if the feature is disabled, we can't install it. Note
// this is a convention: we use INSTALLSTATE_ABSENT to
// mean not installed and not available to be installed
// and INSTALLSTATE_ADVERTISED to mean not installed, but
// available to be installed.
if (is == INSTALLSTATE_ABSENT)
return INSTALLSTATE_ABSENT;
// Setting install state to default makes this
// feature be installed either locally or to run from
// the install source, depending on the authored affinity.
if (fInstall || fFix)
er = MsiConfigureFeature(vszProductCode, szFeature,
INSTALLSTATE_DEFAULT);
if (!fFix && er == ERROR_SUCCESS)
{
// Let's now try to get the installed path of
// the component. If that fails, we need to
// fix it.
is = MsiGetComponentPath(vszProductCode,
szComponentCode, szPath, pcchPath);
if (is == INSTALLSTATE_LOCAL ||
is == INSTALLSTATE_DEFAULT ||
is == INSTALLSTATE_SOURCE)
break;
}
// Fall through to fix this component.
case INSTALLSTATE_BROKEN:
case INSTALLSTATE_INCOMPLETE:
// Feature is broken, try reinstalling it, verifying
// files and registry data (both HKEY_LOCAL_MACHINE
// and HKEY_CURRENT_USER)
if (fInstall || fFix)
er = MsiReinstallFeature(vszProductCode,
szFeature,
(REINSTALLMODE_FILEVERIFY |
REINSTALLMODE_REPAIR |
REINSTALLMODE_USERDATA |
REINSTALLMODE_MACHINEDATA));
if (er == ERROR_SUCCESS)
{
// OK, reinstall succeeded, let's try to
// get the component path again..
is = MsiGetComponentPath(vszProductCode,
szComponentCode, szPath, pcchPath);
if (is == INSTALLSTATE_LOCAL ||
is == INSTALLSTATE_DEFAULT ||
is == INSTALLSTATE_SOURCE)
break;
else
return is; // can't fix component.
}
}
// If we've been able to install or reinstall the component,
// get the path to the particular file we're interested in.
// If we want the keyfile, we've already got that.
if (er == ERROR_SUCCESS && szFileName != NULL)
{
TCHAR *pchSlash = NULL;
TCHAR *pch;
for (pch = szPath; *pch != 0; pch++)
if (*pch == '\\')
pchSlash = pch;
if (pchSlash++ &&
(pchSlash-szPath)+lstrlen(szFileName) < cchPath)
{
lstrcpy(pchSlash, szFileName);
}
else
{
er = ERROR_MORE_DATA; // buffer too small.
}
}
SetLastError(er);
return er == ERROR_SUCCESS ? is : INSTALLSTATE_BROKEN;
}