某所(?)で話題になっていたWindows Installerで外部UIを使って
インストールを行うためのクラスです。
---
#pragma once
#include <Msi.h>
#pragma comment(lib, "Msi.lib")
#include "MsiHelper.h"
///////////////////////////////////////////////////////////////////
// MSI MessageMap
// Handling Progress Messages Using MsiSetExternalUI
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/handling_progress_messages_using_msisetexternalui.asp
// ms-help://MS.MSDNQTR.2003FEB.1041/msi/setup/installui_handler.htm
#define BEGIN_MSI_MESSAGE_MAP(T) \
public: \
int CALLBACK InternalInstallUIHandler(UINT iMessageType, LPCTSTR szMessage) \
{ \
T* pT = static_cast(this); \
\
INSTALLMESSAGE currentMsg = (INSTALLMESSAGE)(0xFF000000 & iMessageType); \
UINT uiFlags = 0x00FFFFFF & iMessageType;
#define MSI_MESSAGE_HANDLER(msg, func) \
if (currentMsg == msg) \
{ \
return pT->func(szMessage); \
}
#define END_MSI_MESSAGE_MAP() \
return 0; \
}
///////////////////////////////////////////////////////////////////
// CMsiExternalUI
template
class CMsiExternalUI
{
public:
CMsiExternalUI()
{
}
~CMsiExternalUI()
{
}
public:
// 製品のインストール (MSI)
HRESULT InstallProduct(
LPCTSTR szPackagePath,
LPCTSTR szCommandLine = NULL,
DWORD dwMessageFilter = CMsiExternalUI::GetDefaultMessageFilter())
{
T* pT = static_cast(this);
// UIを表示しないように設定
CRestoreMsiUILevel uiLevel(INSTALLUILEVEL_NONE);
// 外部からUIを制御するように設定
::MsiSetExternalUI(T::InstallUIHandler, dwMessageFilter, pT);
// 製品のインストール (MSI)
UINT nr = ::MsiInstallProduct(szPackagePath, szCommandLine);
if (nr != ERROR_SUCCESS)
{
if (nr == ERROR_INSTALL_USEREXIT)
{
// ユーザー キャンセル
return S_FALSE;
}
return E_FAIL;
}
return S_OK;
}
// パッチの適用 (MSP)
HRESULT ApplyPatch(
LPCTSTR szPatchPackage,
LPCTSTR szInstallPackage = NULL,
INSTALLTYPE eInstallType = INSTALLTYPE_DEFAULT,
LPCTSTR szCommandLine = NULL,
DWORD dwMessageFilter = CMsiExternalUI::GetDefaultMessageFilter())
{
T* pT = static_cast(this);
// UIを表示しないように設定
CRestoreMsiUILevel uiLevel(INSTALLUILEVEL_NONE);
// 外部からUIを制御するように設定
::MsiSetExternalUI(T::InstallUIHandler, dwMessageFilter, pT);
// パッチの適用 (MSP)
UINT nr = ::MsiApplyPatch(szPatchPackage, szInstallPackage, eInstallType, szCommandLine);
if (nr != ERROR_SUCCESS)
{
if (nr == ERROR_INSTALL_USEREXIT)
{
// ユーザー キャンセル
return S_FALSE;
}
return E_FAIL;
}
return S_OK;
}
static DWORD GetDefaultMessageFilter()
{
DWORD dwMessageFilter =
INSTALLLOGMODE_PROGRESS | INSTALLLOGMODE_FATALEXIT | INSTALLLOGMODE_ERROR |
INSTALLLOGMODE_WARNING | INSTALLLOGMODE_USER | INSTALLLOGMODE_INFO |
INSTALLLOGMODE_RESOLVESOURCE | INSTALLLOGMODE_OUTOFDISKSPACE |
INSTALLLOGMODE_ACTIONSTART | INSTALLLOGMODE_ACTIONDATA |
INSTALLLOGMODE_COMMONDATA | INSTALLLOGMODE_PROGRESS | INSTALLLOGMODE_INITIALIZE |
INSTALLLOGMODE_TERMINATE | INSTALLLOGMODE_SHOWDIALOG;
return dwMessageFilter;
}
protected:
static int CALLBACK InstallUIHandler(LPVOID pvContext, UINT iMessageType, LPCTSTR szMessage)
{
T* pT = static_cast(pvContext);
return pT->InternalInstallUIHandler(iMessageType, szMessage);
}
};
---