#include "stdafx.h"
#include <windows.h>
#include <conio.h>
//#include <ostream.h>
//#include <fstream>
#include <msi.h>
#pragma comment(lib,"msi.lib")
class MsiProductsChecker
{
virtual void CheckProductID(GUID prodId) = 0;
public:
void DoCheck()
{
int i=0;
WCHAR guid_str[255] = {0};
while(ERROR_SUCCESS == MsiEnumProductsW(i++,guid_str))
{
GUID guid = {0};
::IIDFromString(guid_str,&guid);
CheckProductID(guid);
}
}
};
class OfficeProductChecker : public MsiProductsChecker
{
virtual void CheckProductID(GUID prodId)
{
CheckOffice2000(prodId);
CheckOfficeXP(prodId);
CheckOffice2003(prodId);
CheckOffice2007(prodId);
}
bool IsOffice2000_XP_2003_Family(GUID prodId, LPOLESTR patternStr)
{
GUID pattern;
::IIDFromString(patternStr,&pattern); //{xxyyzzzz-????-????-????-????????????}
pattern.Data1 = prodId.Data1;
return 0 != IsEqualGUID(pattern,prodId);
}
void CheckOffice2000(GUID prodId)
{
if (!IsOffice2000_XP_2003_Family(prodId,L"{00000000-78E1-11D2-B60F-006097C998E7}"))
return;
//KB 230848
//{xxyyzzzz-78E1-11D2-B60F-006097C998E7}
//Characters Definition values
// -------------------------------------------------------------
// xx The version of the product 00-FF
// yy The SKU of the product 00-FF
// zzzz The language identifier of the product any required
long sku = (prodId.Data1 >> 16) & 0xFF;
switch(sku)
{
case 0x00: //Microsoft Office 2000 Premium Edition CD1
case 0x01: //Microsoft Office 2000 Professional Edition
case 0x02: //Microsoft Office 2000 Standard Edition
case 0x03: //Microsoft Office 2000 Small Business Edition
case 0x04: //Microsoft Office 2000 Premium CD2
case 0x05: //Office CD2 SMALL
m_Office2000Installed = true;
break;
default:
;
}
}
void CheckOfficeXP(GUID prodId)
{
if (!IsOffice2000_XP_2003_Family(prodId,L"{00000000-6000-11D3-8CFE-0050048383C9}"))
return;
//KB 302663
//{WXYYZZZZ-6000-11D3-8CFE-0050048383C9}
//Characters Definition Hex values
// ------------------------------------------------------------------
// W Release type 0-9, A-F
// X Edition type 0-2
// YY SKU of the product 10-35
// ZZZZ Language identifier of the product any required
long release = (prodId.Data1 >> (8*3 + 4)) & 0xF;
long sku = (prodId.Data1 >> 16) & 0xFF;
if (release < 9)
return; //it's beta or RC
switch(sku)
{
case 0x11: //Microsoft Office XP Professional
case 0x12: //Microsoft Office XP Standard
case 0x13: //Microsoft Office XP Small Business
case 0x28: //Microsoft Office XP Professional with FrontPage
case 0x29: //Microsoft Office XP Professional Subscription
case 0x2A: //Microsoft Office XP Small Business Edition Subscription
case 0x33: //Microsoft Office XP PIPC1 (Pre Installed PC) (JPN Only)
case 0x34: //Microsoft Office XP PIPC2 (Pre Installed PC) (JPN Only)
m_OfficeXPInstalled = true;
break;
default:
;
}
}
void CheckOffice2003(GUID prodId)
{
if (!IsOffice2000_XP_2003_Family(prodId,L"{00000000-6000-11D3-8CFE-0150048383C9}"))
return;
//KB 832672
//{WXYYZZZZ-6000-11D3-8CFE-0150048383C9}
//Characters Definition Hex values
// ------------------------------------------------------------------
// W Release type 0-9, A-F
// X Edition type 0-2
// YY SKU of the product 10-35
// ZZZZ Language identifier of the product any required
long release = (prodId.Data1 >> (8*3 + 4)) & 0xF;
long sku = (prodId.Data1 >> 16) & 0xFF;
if (release < 9)
return; //it's beta or RC
switch(sku)
{
case 0x11: //Microsoft Office Professional Enterprise Edition 2003
case 0x12: //Microsoft Office Standard Edition 2003
case 0x13: //Microsoft Office Basic Edition 2003
case 0xCA: //Microsoft Office Small Business Edition 2003
case 0xE3: //Microsoft Office Professional Edition 2003 (with InfoPath 2003)
m_Office2003Installed = true;
break;
default:
;
}
}
void CheckOffice2007(GUID prodId)
{
//KB 928516
//{BRMMmmmm-PPPP-LLLL-p000-0000000FF1CE}
//Characters Definition Hexadecimal values
// ------------------------------------------------------------------
// B Release version 0-9, A-F
// R Release type 0-9, A-F
// MM Major version 0-9
// mmmm Minor version 0-9
// PPPP Product ID 0-9, A-F
// LLLL Language Identifier 0-9, A-F
// p 0 for x86, 1 for x64 0-1
// 000 Reserved for future use, currently 0 0
// D 1 for debug, 0 for ship 0-1
// 000000FF1CE Office Family ID 0-9
GUID pattern;
::IIDFromString(L"{00000000-0000-0000-0000-0000000FF1CE}",&pattern);
if (0 != memcmp(pattern.Data4,prodId.Data4,sizeof(pattern.Data4)))
return;
long releaseVer = (prodId.Data1 >> (8*3 + 4)) & 0xF;
if (releaseVer < 9)
return; //it's beta or RC
switch(prodId.Data2)
{
case 0x0011: //Microsoft Office Professional Plus 2007
case 0x0012: //Microsoft Office Standard 2007
case 0x0013: //Microsoft Office Basic 2007
case 0x0014: //Microsoft Office Professional 2007
case 0x002E: //Microsoft Office Ultimate 2007
case 0x002F: //Microsoft Office Home and Student 2007
case 0x0030: //Microsoft Office Enterprise 2007
case 0x00CA: //Microsoft Office Small Business 2007
m_Office2007Installed = true;
break;
default:
;
}
}
bool m_OfficeXPInstalled;
bool m_Office2000Installed;
bool m_Office2003Installed;
bool m_Office2007Installed;
public:
OfficeProductChecker()
{
m_OfficeXPInstalled = false;
m_Office2000Installed = false;
m_Office2003Installed = false;
m_Office2007Installed = false;
}
bool OfficeXPInstalled() const { return m_OfficeXPInstalled; }
bool Office2000Installed() const { return m_Office2000Installed; }
bool Office2003Installed() const { return m_Office2003Installed; }
bool Office2007Installed() const { return m_Office2007Installed; }
bool OfficeInstalled() const{
return OfficeXPInstalled() || Office2000Installed() || Office2003Installed() || Office2007Installed();
}
bool IsOfficeProductId(const wchar_t* prodID)
{
GUID pid;
::IIDFromString((LPOLESTR)prodID,&pid);
CheckProductID(pid);
return OfficeInstalled();
}
};
void Test(PCWSTR prodId)
{
OfficeProductChecker checker;
wprintf(L"%s is offfice: %s\n", prodId, checker.IsOfficeProductId(prodId) ? L"Yes" : L"No");
}
int _tmain(int argc, _TCHAR* argv[])
{
OfficeProductChecker checker;
checker.DoCheck ();
wprintf(L"Office installed: %s\n", checker.OfficeInstalled() ? L"Yes" : L"No");
//Office 2k
Test(L"{00000409-78E1-11D2-B60F-006097C998E7}");
//Office XP beta ?
Test(L"{20280409-6000-11D3-8CFE-0050048383C9}");
//Office XP + FrontPage
Test(L"{90280409-6000-11D3-8CFE-0050048383C9}");
//Office XP Pro RUS
Test(L"{91110419-6000-11D3-8CFE-0050048383C9}");
//Office 2k3 Prof
Test(L"{90110409-6000-11D3-8CFE-0150048383C9}");
//Office 2k3 Std
Test(L"{91120409-6000-11D3-8CFE-0150048383C9}");
//Office 2k3 Rus
Test(L"{90110419-6000-11D3-8CFE-0150048383C9}");
//Office 2k7 Enterprise
Test(L"{90120000-0030-0000-0000-0000000FF1CE}");
//Office 2k7 Professional
Test(L"{90120000-0014-0000-0000-0000000FF1CE}");
//Office 2k7 Professional Plus
Test(L"{90120000-0011-0000-0000-0000000FF1CE}");
//Office 2k7 Small Business
Test(L"{90120000-00CA-0000-0000-0000000FF1CE}");
//Office 2k7 Standard
Test(L"{90120000-0012-0000-0000-0000000FF1CE}");
return 0;
}