Uso di un'interfaccia utente incorporata
Un'interfaccia utente personalizzata può essere incorporata nel pacchetto di Windows Installer.
Il file DLL contenente l'interfaccia utente personalizzata e tutti i file di risorse usati dall'interfaccia utente personalizzata devono essere elencati nella tabella MsiEmbeddedUI . Ad esempio, questa tabella MsiEmbedededUI contiene una riga per il file DLL contenente l'interfaccia utente incorporata e una riga per un file bitmap usato dall'interfaccia utente.
MsiEmbeddedUI | FileName | Attributi | Messagefilter | Dati |
---|---|---|---|---|
EmbeddedUI | embedui.dll | 3 | 201359327 | [Dati binari] |
CustomBitmap | custom.bmp | 0 | [Dati binari] |
La DLL dell'interfaccia utente personalizzata, in questo esempio embedui.dll, deve esportare le funzioni InitializeEmbeddedUI, EmbeddedUIHandler e ShutdownEmbeddedUI definite dall'utente. Il codice di esempio seguente illustra queste funzioni.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <msi.h>
#include <msiquery.h>
#include <Aclapi.h>
#include <strsafe.h>
#pragma comment(lib, "msi.lib")
#define cchGUID 38
int __stdcall InitializeEmbeddedUI(MSIHANDLE hInstall,
LPCWSTR szResourcePath, LPDWORD pdwInternalUILevel)
{
// The hInstall handle is only valid within this function and
// can be used to get or set properties. The handle
// does not need to be explicitly closed.
WCHAR szProductCode[cchGUID+1];
DWORD cchProductCode = ARRAYSIZE(szProductCode);
UINT uiStat = MsiGetProperty(hInstall, L"ProductCode",
szProductCode, &cchProductCode);
UNREFERENCED_PARAMETER(szResourcePath);
if (ERROR_SUCCESS != uiStat)
{
// The installation should fail.
return ERROR_INSTALL_FAILURE;
}
WCHAR* szReinstall = NULL;
DWORD cchReinstall = 0;
uiStat = MsiGetProperty(hInstall, TEXT("REINSTALL"),
szReinstall, &cchReinstall);
if (ERROR_MORE_DATA == uiStat)
{
++cchProductCode; // Add 1 for terminating null character.
szReinstall = new WCHAR[cchReinstall];
if (szReinstall)
{
uiStat = MsiGetProperty(hInstall, L"REINSTALL",
szReinstall, &cchReinstall);
}
}
if (ERROR_SUCCESS != uiStat)
{
if (szReinstall != NULL)
delete [] szReinstall;
// This installation should fail.
return ERROR_INSTALL_FAILURE;
}
if (INSTALLSTATE_DEFAULT != MsiQueryProductState(szProductCode))
{
if (INSTALLUILEVEL_BASIC == *pdwInternalUILevel)
{
// Insert the custom UI used by basic installation here.
}
else
{
// Insert the custom UI used by full installation here.
}
}
else if (szReinstall && szReinstall[0])
{
// Reinstall the UI sequence.
}
else
{
// This is a maintenance installation. Remove the UI sequence.
MsiSetProperty(hInstall, TEXT("REMOVE"), TEXT("ALL"));
}
if (szProductCode)
delete [] szReinstall;
// Setting the internal UI level to none specifies that
// no authored UI should run.
*pdwInternalUILevel = INSTALLUILEVEL_NONE;
return 0;
}
DWORD __stdcall ShutdownEmbeddedUI()
{
// ShutdownEmbeddedUI is optional. It can allow the embedded UI
// to perform any cleanup. After this call, the embedded UI
// should not receive any additional callbacks.
return 0;
}
INT __stdcall EmbeddedUIHandler(UINT iMessageType, MSIHANDLE hRecord)
{
// This function is similar to the MsiSetExternalUIRecord callback.
INSTALLMESSAGE mt;
UINT uiFlags;
UNREFERENCED_PARAMETER(hRecord);
mt = (INSTALLMESSAGE) (0xFF000000 & (UINT) iMessageType);
uiFlags = 0x00FFFFFF & iMessageType;
switch (mt)
{
case INSTALLMESSAGE_FATALEXIT:
{
return IDOK;
}
case INSTALLMESSAGE_ERROR:
{
return IDOK;
}
case INSTALLMESSAGE_WARNING:
{
return IDOK;
}
case INSTALLMESSAGE_FILESINUSE:
{
return IDOK;
}
case INSTALLMESSAGE_RESOLVESOURCE:
{
return IDOK;
}
case INSTALLMESSAGE_USER:
{
return IDOK;
}
case INSTALLMESSAGE_INFO:
{
return IDOK;
}
case INSTALLMESSAGE_OUTOFDISKSPACE:
{
return IDOK;
}
case INSTALLMESSAGE_ACTIONSTART:
{
return IDOK;
}
case INSTALLMESSAGE_ACTIONDATA:
{
return IDOK;
}
case INSTALLMESSAGE_PROGRESS:
{
return IDOK;
}
case INSTALLMESSAGE_SHOWDIALOG:
{
return IDOK;
}
case INSTALLMESSAGE_COMMONDATA:
{
return IDOK;
}
case INSTALLMESSAGE_INSTALLSTART:
{
// This message is sent when the Install begins.
// Record contains the ProductName and ProductCode
return IDOK;
}
case INSTALLMESSAGE_INSTALLEND:
{
// This message is sent when the Install ends.
// Record contains the ProductName and ProductCode
// and return value of the installation.
return IDOK;
}
default:
{
return 0;
}
}
}