From MSI to WiX, Part 24 - DLL Custom Actions - Get property value and obtaining/changing session information

In previous post we looked at how to set propery's value.  Getting property value is more involved because we need to make sure that provided memory buffer for property value is big enough to hold the value.  Function MsiGetProperty is used to get a property value.  Description for MsiGetProperty function has a very good sample on how to get value of a property.

WiX API has a set of functions to get value of a property:

  • WcaGetProperty - returns value of a property.
  • WcaGetIntProperty - returns an integer value of a property.
  • WcaGetFormattedProperty - returns formatted value of a property.  This function is using WcaGetFormattedString function which we will mention again when we will discuss Record Functions.

Here are samples of how to use these functions:

HRESULT hr = S_OK;

LPWSTR pwzPropertyData = NULL;

hr = WcaGetProperty( L"MyProperty", &pwzPropertyData);

ExitOnFailure(hr, "Failed to get MyProperty");

int iAllUsers = 0;

hr = WcaGetIntProperty(L"ALLUSERS", &iAllUsers);

ExitOnFailure(hr, "Failed to get value of ALLUSERS property");

LPWSTR pwzFormattedPropertyData = NULL;

hr = WcaGetFormattedProperty( L"MyFormattedProperty", &pwzFormattedPropertyData);

ExitOnFailure(hr, "Failed to get MyFormattedProperty");

To determine the length of value property is holding, we initially pass an empty string and zero as a length of the buffer for value.  When property is set and property's value is not an empty string, MsiGetProperty function's return value is ERROR_MORE_DATA.  If property is not set or its value is an empty string, return value is ERROR_SUCCESS.  WiX API WcaIsPropertySet function returns TRUE if the length of the property's value is more than zero.  You can use this helper function to check if property is set.

if (WcaIsPropertySet("CustomActionData"))

{

}

 

    Installation session information

To get or set installation session variables we can use the following functions.

    MsiGetLanguage 

Returns the language ID of currently running installation.  This is a very simple function and does not have wrapper function in WiX API.

LANGID langid = ::MsiGetLanguage(WcaGetInstallHandle());

    MsiGetMode

Use this function to determine current mode for installation.  Most often this function will be used to determine if custom action is running as scheduled, rollback, or commit custom action.  We can also check for conditions like administartive install, product advertising install, or maintenace install in addition to other modes.  To get the full list of modes we can verify look at MsiGetMode function description.

BOOL fRollback = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK);

    MsiSetMode

To request immediate or after successful installation reboot, use MsiSetMode function.

DWORD er = ERROR_SUCCESS;

er = ::MsiSetMode(WcaGetInstallHandle(), MSIRUNMODE_REBOOTATEND, TRUE);

    MsiSetInstallLevel

To change the installation level, use MsiSetInstallLevel function.  For more information on installation level, INSTALLLEVEL property, and how it affects features to be installed, see Part 4 in this blog.

UINT er = ::MsiSetInstallLevel(WcaGetInstallHandle(), 100);

    MsiGetSourcePath

This function returns the full source path for a folder listed in the Directory table (or Directory element in WiX).

DWORD cchPath = MAX_PATH + 1;

TCHAR* szPath = new TCHAR[cchPath];

UINT err = ::MsiGetSourcePath(WcaGetInstallHandle(), TEXT("INSTALLLOCATION"), szPath, &cchPath);

if(ERROR_SUCCESS == err)

{

WcaSetProperty(L"INSTALLFROMPATH", szPath);

}

delete [] szPath;

 

    MsiGetTargetPath

This function returns the full target path for a folder listed in the Directory table (or Directory element in WiX).

DWORD cchPath = MAX_PATH + 1;

TCHAR* szPath = new TCHAR[cchPath];

UINT err = ::MsiGetTargetPath(WcaGetInstallHandle(), TEXT("INSTALLLOCATION"), szPath, &cchPath);

if(ERROR_SUCCESS == err)

{

WcaSetProperty(L"INSTALLTOPATH", szPath);

}

delete [] szPath;

WiX API has a helper function - WcaGetTargetPath.  This function checks first the size of the target folder and allocates enough memory to hold the target path.  Allocated string must be released by using ReleaseStr function:

LPWSTR pwzTargetPath = NULL;

HRESULT hr = WcaGetTargetPath(L"INSTALLLOCATION", &pwzTargetPath);

if(SUCCEEDED(hr))

{

    WcaSetProperty(L"INSTALLFROMPATH", pwzTargetPath);

}

ReleaseStr(pwzTargetPath);

    MsiSetTargetPath

This function sets the full target path for a folder listed in the Directory table (or Directory element in WiX).

::MsiSetTargetPath(WcaGetInstallHandle(), TEXT("INSTALLLOCATION"), TEXT("c:\\CAIntro\\"));

    MsiVerifyDiskSpace

This function checks to see if sufficient disk space is present for the current installation.

switch(::MsiVerifyDiskSpace(WcaGetInstallHandle()))

{

case ERROR_SUCCESS:

    WcaLog(LOGMSG_STANDARD, "We have enough of disk space to complete installation.");

    break;

case ERROR_DISK_FULL:

    WcaLog(LOGMSG_STANDARD, "We don't have enough of disk space to complete installation.");

    break;

default:

    WcaLog(LOGMSG_STANDARD, "Failed to call MsiVerifyDiskSpace.");

    break;

}

No attachments this time.