1
votes

I have a custom action in a C# custom action assembly I want to run at the end of the install, or at least after the files have been copied. I need to update a config file with information that was entered in the dialogs during the first part of the install. It's a remoting config file, so there are several lines that have to be updated. Currently I have XmlFile entries for each of the line items, but I want to generically replace localhost:8001 with [servername]:[serverport]. I have not found a generic search and replace in WiX, so I wrote a custom action to do it. Problem is I cannot get it to run. I am using a custom UI (UI Sequence XML bellow), so that might be why the After="InstallFiles" does not work.

    <InstallUISequence>
        <Custom Action="SetInstallFolder" Sequence="1" />
        <!--<Custom Action="UpdateRemotingConfigFile" After='InstallFiles' />-->
        <Show Dialog="UserExitForm" OnExit="cancel" />
        <Show Dialog="FatalErrorForm" OnExit="error"><![CDATA[NOT HideFatalErrorForm]]></Show>
        <Show Dialog="MaintenanceForm" Sequence="999"><![CDATA[Installed <> ""]]></Show>
        <Show Dialog="ResumeForm" Sequence="998"><![CDATA[Installed="" AND RESUME]]></Show>
        <Show Dialog="FinishedForm" OnExit="success" />
        <Show Dialog="WelcomeForm" Sequence="1001"><![CDATA[Installed="" AND NOT RESUME]]></Show>
        <Custom Action="VSDCA_AllUsers" After="CostInitialize"><![CDATA[Installed="" AND NOT RESUME AND ALLUSERS=1]]></Custom>
    </InstallUISequence>

    <AdminUISequence>
        <Custom Action="SetInstallFolder" Sequence="1" />
        <!--<Custom Action="UpdateRemotingConfigFile" After='InstallFiles' />-->
        <Show Dialog="UserExitForm" OnExit="cancel" />
        <Show Dialog="FatalErrorForm" OnExit="error"><![CDATA[NOT HideFatalErrorForm]]></Show>
        <Show Dialog="MaintenanceForm" Sequence="999"><![CDATA[Installed<>""]]></Show>
        <Show Dialog="ResumeForm" Sequence="998"><![CDATA[Installed="" AND RESUME]]></Show>
        <Show Dialog="FinishedForm" OnExit="success" />
        <Show Dialog="WelcomeForm" Sequence="1001"><![CDATA[Installed="" AND NOT RESUME]]></Show>
    </AdminUISequence>

If I uncomment the custom action above, I get the following error:

error LGHT0094: Unresolved reference to symbol 'WixAction:InstallUISequence/InstallFiles' in section 'Product:{...

If I change it to "FinishedForm", I get the following error:

error LGHT0177: The AdminUISequence table contains an action 'UpdateRemotingConfigFile' that is scheduled to come before or after action 'FinishedForm', which is a special action which only occurs when the installer terminates. These special actions can be identified by their negative sequence numbers. Please schedule the action 'UpdateRemotingConfigFile' to come before or after a different action.

Update: I have the custom action defined as follows:

<Binary Id="WebApiSetupHelper" SourceFile="..\WebApiSetupHelper\bin\$(var.Configuration)\WebApiSetupHelper.CA.dll" />
<CustomAction Id="UpdateRemotingConfigFile" BinaryKey="WebApiSetupHelper" DllEntry="UpdateRemotingConfigFile" Return="check" />

What do I need to change to get the custom action to run?

Thanks.

1

1 Answers

0
votes

There are two parts to each installation. The first is the UI portion (InstallUISequence and AdminUISequence) and the execute portion where the installer runs the install script to put all the files in place (after you click Install). These sequences are the InstallExecuteSequence and AdminExecuteSequence.

I don't think you need to use the AdminUISequence and AdminExecuteSequence for the fast majority of installations.

What you need to do is schedule your custom action in the InstallExecuteSequence. Since you are modifying the contents of a file, you'll have to make this custom action deferred so that you have elevated privileges and can modify files in secure locations (if you are modifying a file in program files location for example).

When you need a property value from the UI portion of the install in a deferred custom action, you need to use a special pattern to save the value in a way that the custom action can read it.

You need to use a custom action in the form:

<CustomAction Id="SetUpdatingRemotingConfigFile" Property="UpdateRemotingConfigFile" Value="ServerName=[ServerName];ServerPort=[ServerPort]" />

It is very important that the property is the exact same as name the custom action's id that will be accessing the properties defined in the Value. Schedule this action as Before="UpdateRemotingConfigFile" so that the values are set before you will run the custom action that needs them.

Now, in the custom action you need to update

string ServerName = session["ServerName"];

to

string ServerName = session.CustomActionData["ServerName"];

then you should be able to load the value of these properties that were set during the UI portion of the install in your custom action and modify the contents of that config file.