(Note: I originally wrote the table using InstallShield but decided to re implement it in WiX since it's easier to read without visualization. But it sure is more difficult to author. In InstallShield it only took a few clicks and fill in the form typing in the schema wizard. )
The goal is to query the Math table and process math statements with conditions that evaluate to true. Using C#, DTF and AXLibrary it's as simple as this block of code:
The result is a log file like this:
Wow, is that easy or what? I'd love it if someone would write the same functionality in C++ and show what it would look like. BTW, even though DTF comes from WiX, this CA was actually executed via InstallShield. After all, it is just a Type 1 exported stdcall function.
Excluding the boilerplate for EXPORTS, return codes, etc., the C++ would look something like the code below. Checking return codes would probably add about one line per ::Msi call, although it may be hidden in a macro.
ReplyDeleteUINT ProcessMath(MSIHANDLE hInstall)
{
PMSIHANDLE hDatabase = ::MsiGetActiveDatabase(hInstall);
PMSIHANDLE hView, hRec;
::MsiOpenView(_T("SELECT `Property`, `Condition`, `Expression` FROM `Math`"), &hView);
::MsiViewExecute(hView, NULL);
while (ERROR_SUCCESS == ::MsiViewFetch(hView, &hRec))
{
TCHAR szProperty[BUF], szCondition[BUF], szExpression[BUF];
DWORD cchBuf;
::MsiRecordGetString(hRec, 1, szProperty, &(cchBuf = BUF));
::MsiRecordGetString(hRec, 2, szCondition, &(cchBuf = BUF));
::MsiRecordGetString(hRec, 3, szExpression, &(cchBuf = BUF));
if (::MsiRecordIsNull(hRec, 2) || MSICONDITION_TRUE == ::MsiEvaluateCondition(hInstall, szCondition))
{
TCHAR szResult[BUF];
AXParser parser;
parser.Parse(szExpression);
ltot(parser.Evaluate(), szResult, 10);
::MsiSetProperty(hInstall, szProperty, szResult);
}
}
return ERROR_SUCCESS;
}
So algorithmically it's no worse, but as usual there's a lot more line noise.