wixtoolset / issues

WiX Toolset Issues Tracker
http://wixtoolset.org/
130 stars 24 forks source link

Before/After Sequencing 'helper' (for Custom Actions) #8668

Closed bevanweiss closed 3 months ago

bevanweiss commented 3 months ago

User story

As a setup developer, I shouldn't need to open the WiX source code (or even know that it exists) to successfully configure the sequencing of CustomAction items with regards to each other.

Proposal

Preface: I've got no idea how the backend logics of this could work.

As a setup developer, I will often encounter a situation where I need to schedule actions related to other actions. I likely don't even know what are/are not custom actions.

An example of how I would like to naively author a particular custom action (SetProperty) against another custom action (RemoveFolderEx).

<SetProperty Id="REMOVEFOLDEREXTESTDIR"
             Before="RemoveAllTheFolders"
             Value="[CommonAppDataFolder]\RemoveFolderExText"/>

<Component Id="RemoveFolderTestComponent" Guid="{2BFD07F8-6154-4BBF-B5A1-AEB31E9CBC60}">
    <util:RemoveFolderEx Id="RemoveAllTheFolders" 
                         Property="REMOVEFOLDEREXTESTDIR"
                         On="both"  />
</Component>

Instead I currently get this error:

  RemoveFolderExTest failed with 2 error(s) (1.1s)
    ...\RemoveFolderExTests\RemoveFolderExTest\Package.wxs(3): error WIX0094: The identifier 'WixAction:InstallUISequence/RemoveAllTheFolders' could not be found. Ensure you have typed the reference correctly and that all the necessary inputs are provided to the linker.
    ...\RemoveFolderExTests\RemoveFolderExTest\Package.wxs(3): error WIX0094: The identifier 'WixAction:InstallExecuteSequence/RemoveAllTheFolders' could not be found. Ensure you have typed the reference correctly and that all the necessary inputs are provided to the linker.

So that would be the ideal situation... if an ID is specified, we just look at the element, hopefully identify the Custom Action associated with it, and substitute it in. We should ideally be able to match the Sequence itself (i.e. UI, Execute) also. If there's multipart custom actions, and we care about which one is referenced, then perhaps if it's not specified it would throw up an error, and prompting the setup author... e.g.

<Component ...>
   <util:User Id="CreateSteve" Name="Steve" />
   <SetProperty Id="AfterSteve" After="CreateSteve" />
</Component>

would produce an error "Custom Action Sequencing of "AfterSteve" was scheduled After "CreateSteve", however "CreateSteve" is a multipart execution, did you mean "CreateSteve:ConfigureUsers", "CreateSteve:AddUser", or "CreateSteve:RemoveUser"?

This comes up, because I've just been tripped up with it, and going through the build cycle each time was painful to finally work out that my lowercase x86 apparently wasn't a match for the uppercase X86 that it was wanting. And that was already after me knowing:

  1. That the RemoveFoldersEx element was actually calling a RemoveFoldersEx custom action
  2. That the version of that custom action was likely x86, and that this suffix had an underscore (I was pretty sure.. but the failures made me question if I was wrong)
  3. That the WiX version this was introduced in was prior to WiX v4, but that the code base got updated for Wix4 at that time, so Wix4 was the right prefix
  4. .. but without an underscore
  5. And not with a capital X (i.e. it must be Wix4RemoveFoldersEx_X86, not WiX4RemoveFoldersEx_X86)

Considerations

Lots of issues... Many extensions will have several custom actions used to represent one authored element, e.g. util:User may do nothing if it's not under a Component, otherwise it has a ConfigureUsers CA, and AddUsers, and RemoveUsers which are scheduled in different phases of the installation. What might the setup author mean when they say 'Before="CreateUserSteve"', would it mean before the ConfigureUsers? Perhaps.. since maybe they want to set things up before any user activity occurs. After="CreateUserSteve" probably means after the AddUsers (but maybe it could mean after the RemoveUsers.. which is all the way in the Commit phase..).

barnson commented 3 months ago

This breaks down when an extension has more than one custom action---which is very common with needing different custom actions for install and uninstall. $(sys.BUILDARCHSHORT) is one solution to the suffix. Otherwise, it's down to documentation when you're at the lower level of messing around with scheduling.