Domanda

I'm trying to make my setup to support both per-user and per-machine installations. I want user to choose from UI via radio buttons whether software will be installed per-user or per-machine and based on that choice to select different custom actions and different files to be copied.

I found out that I can just use util:XmlFile element to change some files that are different based on installation scope, but problem is that this component is run before property is changed by UI. Here are code fragments:

    <Property Id='ADXLoaderPrivileges' Value='bla' />
    <Directory Id="TARGETDIR" Name="SourceDir">
        <Component Id="adxloader.dll.manifest" Guid="51FC65CB-BEAD-4423-A840-49C9CB22E191">
            <File Id="adxloader.dll.manifest" Source="$(var.ExcelProjectDir)\Loader\adxloader.dll.manifest" DiskId="1" KeyPath="yes" />
            <util:XmlFile Id="ModifyAdxLoaderManifest" Action="setValue"
                          ElementPath="/configuration/loaderSettings/@privileges" File="[TARGETDIR]\adxloader.dll.manifest" Value="[ADXLoaderPrivileges]" />
        </Component>
    </Directory>

    <Dialog Id='AllUsersChoice' X='50' Y='50' Width='373' Height='287' Title='[ProductName]' TrackDiskSpace='yes'>
       <Control Id='NextButton' Type='PushButton' X='300' Y='261' Width='66' Height='18' Text='{\VSI_MS_Sans_Serif13.0_0_0}&amp;Next &gt;' TabSkip='no' Default='yes'>
         <Publish Property='TARGETDIR' Value='[%ProgramFiles]\Manufacturer\ProductName\'><![CDATA[ALLUSERS=2]]></Publish>
         <Publish Property='TARGETDIR' Value='[%APPDATA]\Manufacturer\ProductName\'><![CDATA[ALLUSERS=1]]></Publish>
         <Publish Property='ADXLoaderPrivileges' Value='administrator'><![CDATA[ALLUSERS=2]]></Publish>
         <Publish Property='ADXLoaderPrivileges' Value='user'><![CDATA[ALLUSERS=1]]></Publish>
       </Control>
    </Dialog>

Files are installed in folder based on ALLUSERS property value, but XmlFile executes with 'bla' value instead of 'administrator' or 'user'.

Also, how can I specify custom actions to be executed based on this choice?

È stato utile?

Soluzione

The problem has to do with the scope of properties used by the installer. If you want the user to be able to pass the installer a property which is available during the execution phase of the installation, you have to make that property public. It's very easy to make a property public, you just have to write it ALLCAPS. In your case you have to transform ADXLoaderPrivileges into ADXLOADERPRIVILEGES.

Your second problem can be solved rather simply as well. Have a look at the installer database after you have compiled your project with a suitable programme such as orca or instedit. Inspect the InstallUISequence and the InstallExecuteSequence tables. Here you can see all standard and custom actions. The order in which each action is executed is determined by the entry in the Sequence column. You might have guessed it already: The entry in the Condition column decides if the action gets executed at all based on the condition listed here.

To specify a condition for a CustomAction use the following reference:

  1. Determine the condition you want to evaluate, in your case it's ADXLOADERPRIVILEGES
  2. Write your CustomAction
  3. Insert your CustomAction into the installer Database. You can do this in two different manners: Either create the CustomAction element nested under the Product element or nest it under a Fragment element. If you nest it under a Fragment you have to add a CustomActionRef element to your Product element. The last rule only applies if you don't directly Schedule your CustomAction. This is the case, when a CustomAction gets executed by a buttonclick in the UI, for example.
  4. Schedule your CustomAction. Create Custom elements either under the InstallUISequence or under the InstallExecuteSequence elements in your Product element. The Action attribute of the Custom element is the name of the CustomAction specified by the Id attribute in the CustomAction element. To determine when a CustomAction gets executed use either the Sequence attribute of the Custom element, which is absolute, or use either of the Before or After attributes, in which you specify the name of another Action (standard or custom), which are relative.
  5. Add the Condition to your CustomAction. The Custom element can have one child element which is a textual representation of a condition. Either use plain text or embed your text in CDATA tags.

Here is some code in which the concepts above are used:

The CustomAction Fragment

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Fragment>
    <Binary Id="AlterSqlStringTable.DLL" SourceFile="$(var.AlterSqlStringTable.TargetDir)AlterSqlStringTable.CA.dll" />
    <CustomAction Id="AlterSqlStringTable" BinaryKey="AlterSqlStringTable.DLL" DllEntry="AlterSqlStringTable" Execute="immediate" Return="check" />
    </Fragment>
</Wix>

The Product with the Custom element:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*" Name="!(loc.Name)" Codepage="1252" Language="!(loc.Lang)" Version="YO.UR.VERS.ION" Manufacturer="!(loc.Manufacturer)" UpgradeCode="PUT-YOUR-GUID-HERE">
        ...
        <InstallExecuteSequence>
          <Custom Action="AlterSqlStringTable" Before="InstallFiles"><![CDATA[ADXLOADERPRIVILEGES = "administrator"]]></Custom>
        </InstallExecuteSequence>
        ...
    </Product>
</Wix>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top