In my WIX project I have a directory structure something like this:
I don't have time to test the options I list below, but they should be viable, technical possibilities. Hopefully one of the options will be satisfactory.
But, first of all: I dislike this approach of setting secondary, top-level directories - is it really needed? Can you explain the scenario? Maybe there is a more reliable way?
See the "Alternatives?" section towards the bottom for what I deem to be a better approach than to "fiddle around" with directory properties. If I were you I would read this "Alternatives?" section first - maybe it saves you a whole lot of trouble?
But the first section deals with various technical options to do what you ask:
There are many ways to set a directory property, off the top of my head. As I said, I haven't had time to test these options - and it is always mad to post untested advice, but you seem like someone who can help yourself with some pointers:
[ROOTDRIVE]MyFolder
.
[WindowsVolume]MyFolder
- may actually work, but I don't like it personally. I want nothing installed to a top-level folder on the system drive in the first place.SetDirectory Element
for this "set property" purpose. I think it does all the custom action work for you. Some auto-magic. I am however not sure if this feature allows PUBLIC PROPERTIES to be overridden from the command line?D:\MyFolder
you have to be aware that this path could at some point be missing unexpectedly (drive removed from system, new drive added (?), new DVD drive added (?), drive letter manually changed, etc...).
PersonalFolder
(My Documents) and then redirect this to D:\ in Windows itself. I believe Windows will then assign a new value to PersonalFolder
if it can't be found on boot. Windows Installer will then still be able to enumerate the target folders and not just get stuck or crash.Set directory as a feature directory exposed in the custom dialog in the installer GUI.
ConfigurableDirectory
attribute of the FeatureElement
in your WiX source equal to the PUBLICPROPERTY holding the directory path.<UIRef Id="WixUI_Mondo" />
) - from the "Custom" dialog. There is a step-by-step sample using Visual Studio to update a WiX source file to use Mondo here: WiX installer msi not installing the Winform app created with Visual Studio 2017.ConfigurableDirectory
for the feature.A regular, immediate mode custom action (not a set property custom action) which sets a property with a call to Session.Property = "SomeValue" somewhere in the code. Each type of custom action type does this "property set" slightly differently (custom action types: VBScript, C++, DTF / C#, etc... See documentation from Advanced Installer for how this can be done).
Some people even hard code paths in the property table, or using a set property custom action to assign C:\
to a property at runtime - not at all acceptable. This will break - it is merely a question of time. On computers without a C:\ drive it will not install at all - for starters.
Not sure if such a property, set in the property table would be overridden during directory resolution
and costing
- I have never bothered to try - it is not a solution and I just want to state that to prevent its use.
A set property custom action assigning C:\
or similar to a property will appear to work, but will blow up in unexpected ways. Guaranteed.
Again: if you can help it, don't deploy to a separate, top-level folder.
I have heard some people - in corporate, standardized environments - use an environment variable to define such installation folders. I have never used it for production, never tried it for testing and don't like it as an option.
Keep in mind that public properties can be set at the command prompt - and hence potentially override whatever logic you add to set it yourself. Maybe add a custom action to check for values coming in from the command line, and either accept it or abort the setup if it is wrong.
Here is the GUI screenshot of a WiX installer with configurable feature directory:
The browse button seen above is only available for features that has the ConfigurableDirectory
attribute specified pointing to a custom directory property (ignore the C:\
entry in the screenshot above - just a hiccup):
<!-- A standard feature -->
<Feature Id="ProductFeature" Title="MinimalShortcutTester" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!-- A configurable directory feature -->
<Feature Id="FeatureDirectory" Title="FeatureDirectory" ConfigurableDirectory="MYCUSTOMDIR">
<!-- your stuff here -->
</Feature>
And elsewhere in the WiX source, the actual configurable directory:
<Directory Id="MYCUSTOMDIR">
<!-- Mock-up GUID that MUST be changed, custom target directories do not function with auto-GUIDs -->
<Component Id="MyFile.exe" Guid="{00000000-0000-0000-0000-000000000000}" Feature="FeatureDirectory">
<File Source="C:\SourceControl\MyFile.exe" />
</Component>
</Directory>
I would use an extra custom action to default this MYCUSTOMDIR
directory well, or to inspect the choice made by the user for validity. This is not entirely straight forward, but must be dealt with in each case.
On second thought, I might use a set property custom action
to default the MYCUSTOMDIR directory to a sub-folder of PersonalFolder
, then allow the user to override it on install. Now you have to read back the user choice on modify and repair (and other installation modes), or else you will default to PersonalFolder
and whatever sub-folder you specified in other installation modes. You can persist the user folder selection in the registry, and read it back using AppSearch
(the preference of most of the pros I think) or do it all in a custom action. It can be challenging to make this work right in all installation modes. Do test well.
Technical challenge: if you persist your original folder selection for MYCUSTOMDIR
in the registry and read it back with AppSearch
, you must make sure to condition your set property custom action (used to set a default value to MYCUSTOMDIR
if no value is set) so that it does not run if the property already has a value retrieve from the registry. Not rocket science, but can be fiddly to get right - and be nitpicking about testing in all installation modes. If you rely on standard constructs and not custom actions you generally benefit once you understand "the moving parts" involved - first you default on first install since no value is set yet (unless a value is set via the command line), then you allow it to be overridden in the GUI (or by command line), then you persist in the registry during installation, on next launch (repair, modify, self-repair, upgrade, patch) you read back the persisted value and don't let the default value be set via condition, etc...
Throwing in a link for safe-keeping: Wix : Disable control in built-in dialog.
As stated above these secondary top-level directory hierarchies may often be avoided by a better understanding of alternatives.
Some questions to check for alternatives: