How to make wix installer install a specific folder based off reg key value at run time

70 views Asked by At

I'm developing a WiX installer that will install 1 of 2 folders based on a reg key value.

I stupidly overlooked the fact that the way I have done, it will check the reg key value and change the heat source path at build time - meaning it will only package 1 of the 2 folders.

I would like to package both folders , but, want the .msi itself to check the reg key value of the machine it is run on and decide which folder to install. However i dont know how to do this :).

Any help is appreciated!

code that currently handles this condition:

<PropertyGroup >
    <HarvestFolder Condition="$(registry:...\...\...\@Key) == 'Value1'">C:\WiX\Folder1</HarvestFolder>
    <HarvestFolder Condition="$(registry:...\...\...\@Key) != 'Value1'">C:\WiX\Folder2</HarvestFolder>
    <DefineConstants>HarvestPath=$(HarvestFolder)</DefineConstants>
  </PropertyGroup>
<Target Name="BeforeBuild">
    <HeatDirectory 
    Directory="$(HarvestFolder)" 
    PreprocessorVariable="var.HarvestPath" 
...
/>

Attempt within .wxs:

    <Property Id="REGISTRY_VALUE" Secure="yes">
    <RegistrySearch Id="RegistrySearchId"
                    Root="HKLM"
                    Key="..\..\...@key"
                    Name="InstallType"
                    Type="raw" />
</Property>

<SetProperty Id="REGKEYVALUE" Value="[REGISTRY_VALUE]" After="AppSearch"/>

<SetProperty Action="Set0" Id="NEWSOURCEPATH" After="AppSearch" Value="value1"><![CDATA[REGKEYVALUE ='#1']]></SetProperty>
<SetProperty Action="Set1" Id="NEWSOURCEPATH" After="AppSearch" Value="value2"><![CDATA[REGKEYVALUE != '#1']]></SetProperty>

<Feature Id="ProductFeature" Title="MyInstaller" Level="1" >
    <!-- Reference the components here -->
    <?if [NEWSOURCEPATH] == "value1"?>
        <ComponentGroupRef Id="HeatGenerated" />
<?endif?>

    <?if [NEWSOURCEPATH] != 'value1'?>
    <ComponentGroupRef Id="HeatGenerated2" />
    <?endif?>
    
</Feature>
2

There are 2 answers

0
Rob Mensching On

The <? ?> syntax defines preprocessing instructions. Preprocessing instructions are evaluated when the compiler loads your source code. That means the build does not include any code in an < if?> where the condition is false. Also, the preprocessing instructions operate on preprocessor variables like those you defined in the <DefineConstants> MSBuild property. None of that will get you closer to your goal.

Instead, you want to use install time Conditions to evaluate the result of the registry search. Features and Components can both be conditioned in the way you want.

I forget exactly which episode it is in, but Deployment Dojo S1:E8 - Variables End to End - Putting it all together in WiX v4 probably exposes you to the necessary constructs... and if not, there is an episode around there that explains the concepts.

0
DemolitionDude77 On

Credit to @RobMensching - many helpful videos in the deployment dojo series

SOLUTION:

I've created a custom action to take the string value of my registry key and assign it to a property :

 public static ActionResult CustomAction1(Session session)
{
session.Log("Begin CustomAction1");

 var keyvar = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\...\....\keyloc","key", null);

 session["REG_VALUE"] = keyvar as string;

 return ActionResult.Success; 
}

continuing this in the wxs ive used a solution found in (Set property value based on condition in WiX) along with setting the custom action:

<Property Id="REG_VALUE" Secure="yes"/>

<Binary Id="CustomActionBinary" SourceFile="$(var.TESTCustomAction.TargetDir)$(var.TESTCustomAction.TargetName).CA.dll" />
<CustomAction Id="TESTCustomAction" Impersonate="no" BinaryKey="CustomActionBinary" DllEntry="CustomAction1" Return="check" />

<CustomAction Id="SET_VALUE1" Property="TEST_PROPERTY" Value="[REG_VALUE]" />
<CustomAction Id="SET_VALUE2" Property="TEST_PROPERTY" Value="[REG_VALUE]" />

<InstallExecuteSequence>

<Custom Action ="TESTCustomAction" After="AppSearch"/>

<Custom Action="SET_VALUE1" After="TESTCustomAction"> (REG_VALUE="value1")</Custom>
<Custom Action="SET_VALUE2" After="SET_VALUE1"> (REG_VALUE="value2")</Custom>
</InstallExecuteSequence>

then finally used this in a condition:

<Feature Id="ProductFeature" Title="MyInstaller" Level="1">

<!--CONDITION: if reg key = value1 - dont install component group'HeatGenerate'-->

<Condition Level="0">REG_VALUE="value1"</Condition> 
    <ComponentGroupRef Id="HeatGenerated" />
    </Feature>

simply add another component group ref, and a condition to evaluate'value2', if you need to evaluate multiple folders as i do

probably not the cleanest wix project but does the job