I tried to use your post, but I have an error on InstanceTransformGuid XML
Tag.
I probably missing something, but what ?
Best regards,
CrazyHT
Josh Rowe wrote:
>
> Okay, I've figured out a lot about multiple instance transforms and the
> sorts of contortions you have to go through to make them work. I even
> figured out how to make a single MSI drive multiple instance transforms
> without the need for a bootstrapping program, relying on the fact that the
> InstallUISequence executes indepently from the InstallExecuteSequence.
> But one thing remains in WiX to make this a lot easier: automatic
> GUID-changing of components. In this message, I discuss how to create a
> multiple instance transform, how to make a single MSI drive multiple
> instance transforms, a common pitfall, and a feature request for WiX.
>
> I want a user, when they double-click an MSI file, to by default install a
> new instance. First, obviously, we will need to define some instance
> transforms:
>
> <Property Id="MYINSTANCE"
> Value="DontUseThis"
> Secure="yes"
> />
>
> <InstanceTransforms Property="MYINSTANCE">
> <Instance ProductCode="444e8aa6-c034-4294-b460-07c2d3262f72"
> ProductName="Instance 1"
> Id="Instance1"/>
> <Instance ProductCode="ff0a0580-bc5d-4562-83ec-2edb3511254b"
> ProductName="Instance 2"
> Id="Instance2"/>
> </InstanceTransforms>
>
> So far, so good. What if the new instance ProductName should be driven by
> user selection items? No problem:
>
> <CustomAction Id="SetProductName"
> Property="ProductName"
> Value="[[ProductNamePropertyPrefix][MYINSTANCE]]"
> />
>
> <Property Id="ProductNamePropertyPrefix"
> Value="ProductName_"
> />
>
> <Property Id="ProductName_DefaultInstance"
> Value="Multiple Instance Transforms - Default instance"
> />
>
> <Property Id="ProductName_Instance1"
> Value="Multiple Instance Transforms - Instance #1"
> />
>
> <Property Id="ProductName_Instance2"
> Value="Multiple Instance Transforms - Instance #2"
>
> <InstallExecuteSequence>
> <Custom Action="SetProductName"
> Before="ValidateProductID"/>
> </InstallExecuteSequence>
>
> Obviously, use whatever algorithm you want in the SetProductName custom
> action. You will probably want a different install location, too:
>
> <Directory Id="INSTALLLOCATION"
> Name="TestMultipleInstanceTransformUi">
> <Directory Id="InstanceDirectory">
> </Directory>
> </Directory>
>
> <CustomAction Id="SetInstanceDirectory"
> Property="InstanceDirectory"
> Value="[INSTALLLOCATION][MYINSTANCE]\"/>
>
> <InstallExecuteSequence>
> <Custom Action="SetInstanceDirectory"
> Before="CostFinalize"><![CDATA[InstanceDirectory =
> ""]]></Custom>
> </InstallExecuteSequence>
>
> Okay, looking good. Now, the user can specify MSINEWINSTANCE=1
> TRANSFORMS=Instance1 on the msiexec command line to install a new
> instance, right? But that seems a little in-depth for users to have to
> worry about. For example, how do they know which instance names are
> available? How can they reliably choose the next available instance id?
> We can obviously do better. It turns out that the MSI system works in two
> phases when a UI is presented. First, the InstallUISequence is executed
> in the user's space. Second, the InstallExecuteSequence is executed in a
> system process. The two sequences act completely independently; the
> InstallUISequence's ExecuteAction just passes a set of property names to
> the system msiexec service. So, we can make our parent process pass in
> the right transform as follows:
>
> <CustomAction Id="SetTransforms"
> Property="TRANSFORMS"
> Value="{:[MYINSTANCE];}[TRANSFORMS]"
> />
>
> <CustomAction Id="SetMsiNewInstance"
> Property="MSINEWINSTANCE"
> Value="1"/>
>
> <InstallUISequence>
> <Custom Action="SetTransforms"
> Before="ExecuteAction"><![CDATA[ACTION =
> "INSTALL"]]></Custom>
> <Custom Action="SetMsiNewInstance"
> Before="ExecuteAction"><![CDATA[ACTION =
> "INSTALL"]]></Custom>
> </InstallUISequence>
>
> Now we need a reliable way of setting MYINSTANCE. That's pretty simple,
> too. We make our install register each instance id during the install,
> and look for the first not-yet-registered instance:
>
> <Property Id="INSTANCE1INSTALLEDPRODUCTCODE">
> <RegistrySearch Id="LookForInstance1InstalledProductCode"
> Key="[InstancesKey]\Instance1"
> Name="ProductCode"
> Root="HKLM"
> Type="raw"/>
> </Property>
>
> <Property Id="INSTANCE2INSTALLEDPRODUCTCODE">
> <RegistrySearch Id="LookForInstance2InstalledProductCode"
> Key="[InstancesKey]\Instance2"
> Name="ProductCode"
> Root="HKLM"
> Type="raw"/>
> </Property>
>
> <Property Id="InstancesKey"
> Value="Software\Manufacturer\TestMultipleInstance"
> />
>
> Now we have information about each registered instance. (More on actually
> getting this registration information into the registry later.) A little
> more tricky custom action work sets MYINSTANCE to the first unused
> instance id:
>
> <CustomAction Id="SetMyInstance_Instance1"
> Property="MYINSTANCE"
> Value="Instance1"
> />
>
> <CustomAction Id="SetMyInstance_Instance2"
> Property="MYINSTANCE"
> Value="Instance2"
> />
>
> <InstallUISequence>
> <Custom Action="SetMyInstance_Instance1"
> Before="SetTransforms"><![CDATA[ACTION = "INSTALL" AND
> MYINSTANCE = "DontUseThis" AND INSTANCE1INSTALLEDPRODUCTCODE =
> ""]]></Custom>
> <Custom Action="SetMyInstance_Instance2"
> After="SetMyInstance_Instance1"><![CDATA[ACTION = "INSTALL"
> AND MYINSTANCE = "DontUseThis" AND INSTANCE2INSTALLEDPRODUCTCODE =
> ""]]></Custom>
> </InstallUISequence>
>
> Now, when the ACTION = "INSTALL", just before the SetTransforms action is
> called that sets the TRANSFORMS property, the MYINSTANCE property will be
> set to the value of the first unused instance id. Assuming, that is, that
> we actually got the instance information into the registry. This is where
> it gets tricky.
>
> Multiple Instance Transforms don't really work out-of-the-box the way most
> people would want to use them. MSI does not uninstall non-file-data for
> components that are used by multiple product codes until the final client
> product is uninstalled; MSI assumes that non-file data is shared. This
> is, of course, bunk, but that's the way it works. If your component GUID
> is shared by multiple product installs, then all but the last uninstall
> will get an Action: FileAbsent for the shared components, thus not
> uninstalling things other than files. So, if you perform multiple
> installs of your wonderful multiple-instance transform that includes the
> instance id in registry key names and then uninstall them, the registry
> keys from all but the last package to be uninstalled will continue to
> exist. Ditto for ServiceInstall elements, etc. So, each of your
> instances needs a new GUID for each component that contains non-file-data
> that must be uninstalled. Further, these components need to be installed
> only with that particular instance. One naive way of doing this is to
> declare multiple components with conditions on them:
>
> <Component Id="Registry_Instance1"
> Guid="54412340-1f29-44f5-a733-157efb25c8a6">
> <Condition><![CDATA[MYINSTANCE = "Instance1"]]></Condition>
> <RegistryKey Root="HKLM"
> Key="[InstancesKey]\[MYINSTANCE]"
> >
> <RegistryValue Id="Presence_Instance1"
> Action="write"
> Name="ProductCode"
> Value="[ProductCode]"
> Type="string"
> KeyPath="yes"
> />
> </RegistryKey>
> </Component>
>
> <Component Id="Registry_Instance2"
> Guid="ffe23417-09ba-485f-912b-c063bebbac2a">
> <Condition><![CDATA[MYINSTANCE = "Instance2"]]></Condition>
> <RegistryKey Root="HKLM"
> Key="[InstancesKey]\[MYINSTANCE]"
> >
> <RegistryValue Id="Presence_Instance2"
> Action="write"
> Name="ProductCode"
> Value="[ProductCode]"
> Type="string"
> KeyPath="yes"
> />
> </RegistryKey>
> </Component>
>
> That's just for registration data. Also add any ServiceInstall,
> ServiceControl, other stuff, etc., and you'll see that this gets out of
> hand very rapidly.
>
> Here is we get to the feature request for WiX. Wouldn't it be nice if the
> InstanceTransforms element interacted with the Component element to
> produce transformed rows for each component. For example, imagine if you
> could specify:
>
> <Component Id="MyDisparateComponent"
> Guid="fa6d4980-8780-4cff-b52c-5c3f57e05f48"
> GenerateGuidForInstanceTransform="yes">
> <RegistryKey></RegistryKey>
> </Component>
>
> Since component GUIDs are only referenced in the Component table and
> nowhere else (except possibly ComponentSearch, but you have that problem
> anyway), there isn't any reason InstanceTransforms shouldn't output rows
> to change the GUIDs for those components that contain non-file-data that
> the user would like to have uninstalled. This dramatically reduces the
> amount of code necessary to go into a multiple instance installer file.
>
> Feel free to change the mechanism. You want explicit guids? How about:
>
> <Component Id="MyDisparateComponent"
> Guid="fa6d4980-8780-4cff-b52c-5c3f57e05f48">
> <InstanceTransformGuid TransformId="Instance1"
> Guid="dd2e906b-0192-43ce-86c2-9e9cec8b1049"/>
> <InstanceTransformGuid TransformId="Instance2"
> Guid="8a493697-8fdb-455c-a542-5bd4667e8473"/>
> </Component>
>
> I thought a nice deterministic algorithm for computing the next GUID
> requested by the GenerateGuidForInstanceTransform attribute would be nice
> so that you wouldn't need to maintain this list on each component if you
> didn't want to.
>
> Thoughts?
>
> jmr
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
> Don't miss this year's exciting event. There's still time to save $100.
> Use priority code J8TL2D2.
> http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
> _______________________________________________
> WiX-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/wix-users
>
>
--
View this message in context:
http://n2.nabble.com/Multiple-Instance-Transforms-Walkthrough%2C-Proposed-Simple-Addition-to-WiX-to-Make-Them-Easier-tp708828p3329391.html
Sent from the wix-users mailing list archive at Nabble.com.
------------------------------------------------------------------------------
_______________________________________________
WiX-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wix-users