[wix-users] saving state in c++ custom actions

Phill Hogland phill.hogland at rimage.com
Mon Mar 28 06:48:22 PDT 2016

I think this sounds like a good candidate for a semi-custom action which creates temporary entries in the Registry Table (possibly followed in the sequence by WixBroadcastEnvironmentChanged).  MSI then handles rollback of the Registry Table by default.
Last I looked at the above link the sample code was dated but I found searching the wix src for similar entries to be very helpful in implementing the concept.

I use something like this (for a different purpose):
        hr = WcaGetRecordString(hRec, eqComponent_, &pwzComponentId);
        ExitOnFailure(hr, "failed to get the Component Id for Id: %ls", pwzId);
        WcaLog(LOGMSG_VERBOSE, "Component Id is %ls.", pwzComponentId);

        // skip adding a temp row if the component isn't being configured
        todoComponent = WcaGetComponentToDo(pwzComponentId);

        if (WCA_TODO_UNKNOWN != todoComponent)
.....    do something here (or earlier) to format my value, and call this code for all situations except if installation status is 'unknown'

        hr = WcaAddTempRecord(&hTempView, &hColumns,
            1,                      // the column number of the key we want "uniquified" (uniqued?)
            6,                      // the number of columns we're adding
            L"MyId",     // primary key (uniquified)
            L"Myregistry",     // I think for System variables will be HKEY_LOCAL_MACHINE\ SYSTEM\ CurrentControlSet\ Control\ Session Manager\ Environment
            L"my value",  
        ExitOnFailure(hr, "failed to add temporary registry row for RdpCddIisPerms. dbError is: %d", dbError);

Another approach that I would investigate since I use an mba (or even a BAFunctions.dll and the WixStdBA) is to read the Environment variable in a Detect handler and parse for a result, then there are several options to conditionally write the details back using an Engine Var passed to a MsiProperty used in a Wix Environment/@Value element, in a conditional Component or MSI package under control of the mba as to whether the Component is applied.

I don't know a specific solution but just thought I would suggests these paths to investigate.
From: wix-users <wix-users-bounces at lists.wixtoolset.org> on behalf of James Burgess <jrb at pixar.com>
Sent: Saturday, March 26, 2016 1:53 PM
To: WiX Toolset Users Mailing List
Subject: [wix-users] saving state in c++ custom actions

This isn't really a WiX question per-se but I’m authoring in WiX and so maybe there is a WiX-specific part that could help me:

My installer needs to inspect a environment variable, do some simple pattern matching on it and if those succeed remove the parts of that variable that match. If the variable doesn’t exist or no matches are found then do nothing on install. The variable uses the standard semi-colon to separate each part (it looks just like PATH).

>From what I can find on msdn about WriteEnvironmentStrings I could almost do it with that but for the pattern matching part. I’m looking for directory paths and although I know the last three directories I don’t know the drive letter of any of the proceeding directories. Could be C:\Program Files\path\I\know or could be E:\My Stuff\in here\path\I\know.

With WiX and a C++ custom action dll doing the pattern match and edit is trivial. What I don’t know is, how or where the best place to save the state for either an uninstall or a rollback. I was thinking my C++ code could discover the Package Id it was being run from and use that as a key in the registry to store the state. Pretty sure I can make that work but maybe there is something much cleaner? Obviously WriteEnvironmentStrings already handles that part and very well.

- James

WiX Toolset Users Mailing List provided by FireGiant http://www.firegiant.com/

More information about the wix-users mailing list