SelectionTree Hide options - wix

I read lots about how to show or remove installation options for features in
the SelectionTree.
Will be installed on local hard drive.
Entire feature will be unavailable.
I don't have any subfeatures, still option 2 i.e. Entire feature will be unavailable. is getting displayed.
For e.g.
<Feature Id="ABC" Title="ABC ShortCut" Level="1">
<ComponentRef Id="ApplicationShortcut" />
</Feature>
Is there any way to hide option 2, show only "Will be installed on local hard drive".
I have checked this thread, but not get any proper answer there.

You can't if you deploy as .MSI
The only option is to deploy with an .EXE (that calls MsiSetExternalUI and takes care of the UI) like Burn.

Related

Wix Toolset - File for admin not appearing when installer is an admin

I am trying to use a component condition for an admin manual pdf. If the installer is in the administrators group I want the admin manual to be installed. Here's how I'm setting this up but it's not being installed even if installer is an administrator. What am I missing?
Requirement:
InstallScope="perUser" />
<Condition>Privileged</Condition>
Find below:
<Component Id="cmp_ManualForAdmins.pdf" Guid="4C28B047-74D2-4642-A180-0039B4C2C5BC">
<File Id="fil_ManualForAdmins.pdf" Name="ManualForAdmins.pdf" Source="$(var.WindowsFormsApp1_TargetDir)ManualForAdmins.pdf">
<Shortcut Id="startMenuAdminManual" Directory="ProgramMenuSubFolder" Name="AdminManual"></Shortcut>
</File>
<Condition>Privileged</Condition>
</Component>
I just spent an hour investigating this and there really aren't any good answers. Because the MSI is invoked from a standard user process and doesn't require elevation, MSI never knows the user can elevate so the Privileged property isn't set.
I figured a custom action might help to work around this but searching up C# Detect Admin revealed various classes and API calls that all had the same behavior.
If I install a protoype MSI from an elevated command prompt the condition evaluates to true and the 'admin.txt' file is installed. From a non elevated it is not installed.
So what would I do? One of two things:
1) Make a second Docs MSI that is a permachine install that requires elevation
or
2) Build and deploy a docs.exe which is manifested to require admin. If the program successfully elevates then have it extract the PDF from an embedded resource to the temp directory and do a ShellExecute to launch the default PDF viewer with that file.
Administrative Installation: Admins typically perform an administrative installation (file extraction) of a setup - at least if they work in big companies that do application packaging. Hence I tend to try to make files like that easily visible on the extracted source media - instead of installing them during normal installation (or both or either, doesn't matter which).
Sample administrative installation (glorified file extraction):
msiexec /a Test.msi TARGETDIR=D:\ExtractedFiles\
More about Administrative Installations.
Admin.pdf: Here is a quick hack that I haven't tested extensively. The admin.pdf will show up during file extraction and not during installation:
<..>
<Feature Id="MainApplication" Title="MainApplication" Level="1">
<Feature Id="SomeFiles" Title="SomeFiles" Level="1" />
<!-- Remove "Display" attibute to show Admin feature in normal setup GUI -->
<Feature Id="Admin" Title="Admin" Level="1001" Display="hidden" />
</Feature>
<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="AdminManual" Feature="Admin" Guid="{00000000-0000-0000-0000-0000DBFB0000}">
<File Source="D:\Admin.pdf" />
</Component>
<..>
Running administrative installation will extract the admin.pdf to the top level extraction directory:
msiexec /a Test.msi TARGETDIR=D:\ExtractedFiles\
The Admin feature is hidden from the normal installation GUI. Change the attribute "Display" to change this. Just remove it for example - for testing purposes.

How to restrict user to change feature in case modify and upgrade in installer?

I have a installer which asks the user to select feature. Whatever user selects, it will never be changed in case of modify and upgrade the installation. For example:
There are three features in my installer which are below:
<Feature Id="Standalone" Title="Standalone" Level="2">
</Feature>
<Feature Id="CentralCase" Title="Central case" Level="2" >
</Feature>
<Feature Id="MiddleEF" Title="Middle Ef" Level="2" Display="expand">
<Feature Id="GUI" Title="Client" Level="3"></Feature>
<Feature Id="AppServer" Title="Application Server" Level="3">
</Feature>
</Feature>
Now suppose user starts the installation and select the first feature which is standalone and install it. Now if user wants to modify, he should not allowed to change feature or even if user wants to upgrade, user should also not allowed to change feature. He can only upgrade what he selected at first time. Is there any way to do this?
ARPNOMODIFY: I guess it depends how critical it is that these features never change. You can set the ARPNOMODIFY in the MSI to
1 and there will be no button to invoke Modify from:
<Property Id="ARPNOMODIFY" Value="1" Secure="yes" />
Disclaimer below. Here be dragons.
msiexec.exe: However, you can still invoke modify by launching the MSI file itself (the default dialog sets should correctly disable the modify button though), but worse: you can go via the msiexec.exe command line and change anything you want:
msiexec /i "MySetup.msi" ADDLOCAL=MyFeature
This might be OK since it would appear to be seldomly used. However, you should be aware that remote management systems often rely on the msiexec.exe command line to handle MSI deployment, and as such the deployment system could be used to change feature state easily (via the deployment tool GUI, no command lines to deal with).
Custom Action: I don't know of an auto-magic way to abort setup if the user tries to modify the feature structure invoked via the msiexec.exe command line, but I suppose you can use a custom action maybe right before InstallInitialize in the InstallExecuteSequence to abort the installation if ADDLOCAL, REMOVE or ADVERTISE are set? If you do not condition this custom action properly, it could cause a package that won't uninstall at all or upgrade properly.
Some unverified conditioning suggestions: How to execute conditional custom action on install and modify only?
MigrateFeatureStates: For a major upgrade the GUI will not run as if it is running modify, but a fresh installation (since the product GUID is new). Hence the original installation GUI is shown and not the modify one. Accordingly you might need to disable some GUI controls or hide whole dialogs to prevent feature selection (not sure in WiX default dialogs). Added a link for that below. The standard action MigrateFeatureStates will take care of preserving the feature installation states between versions, provided you haven't done anything drastic to the feature structure. You enable this standard action to run in the Upgrade table. Should be default to run in WiX MSIs I think.
UPDATE:
Preselected Property: There is a special property called Preselected that is to automatically hide feature selection. You can try to set it or check whether it is set automatically by WiX to see if it hides feature selection. I have honestly never tried it.
Some Further Resources:
Hiding whole dialogs: Wix, custom dialog when previous version exists

Conditional inclusion of files based on an Environment variable in a WIX file

So I have a deployment project based on WIX. I notice that you can include features and files in there. However I only want to deploy a particular file if the DEV/QA environment is selected. If they select Production I want it to ignore this particular file.
Is there a way in the .wxi file to conditionally include a feature / directory & files based on a particular value of a variable?
ie. I want to have something like the below - potentially the componentRef included dynamically? (I have sanitised the values).
<Feature Id="MyApplication" Title="MyApp" Description="My Application" ConfigurableDirectory="MYAPP" Level="1">
<ComponentRef Id="AppEmailTemplatesDir" />
</Feature>
and then further down
<Directory Id="EmailTemplatesDir" Name="EmailTemplates">
<Component Id="AppEmailTemplatesDir" Guid="{A-GUID}">
<File Id="EmailTemplate1.htm" Name="EmailTemplate1.htm" DiskId="1" Source="..\..\EmailTemplates\EmailTemplate1.htm" />
</Component>
</Directory>
Any ideas? We do have custom Actions code (VB.NET) but I'm not sure how that could be used apart from writing code to include files.
There seem to be a variety of ways to do this ... this is what worked for me in Visual Studio 2013.
In the WiX project Properties / Tool Settings add this to Additional parameters / Compiler::
-dReleaseType=$(ReleaseType)
Create a component group containing only the additional file (this is left as an exercise for the reader)
In the main .wxs file add something like this where PDBFile is the id of the component group in step 2:
<!-- Installs a PDB file for daily builds -->
<?if $(var.ReleaseType) = daily ?>
<ComponentGroupRef Id="PDBFile"/>
<?endif?>
Run devenv to build the WiX project with ReleaseType set in the environment
Looks like I can use a Component NeverOverwriteOption="yes" option to ensure the installer doesn't overwrite the files when they exists.
Unless the environment conditional stuff was easy to figure out - this seems to achieve what I need which is to not overwrite the file on production.
I also found that on uninstall it was deleting all the folders (as expected) but to keep the template path I could use the Permanent="yes" attribute.
After discussion we've decided to keep all the files in source control and deploy them. But at least I learnt about NeverOverwriteOption and Permanent :)

wix setup does not install VS 2005 merge module files

it might be a stupid question, but i've spent few hours testing various possibilities and didn't find the answer.
I have one standard merge module prepared in VS 2005 (its probably fine, i've prepared standard VS 2005 setup project, included the merge module and it worked properly)
Wix project(mainly because GUI reasons) to take care about the installation. Code samples(shortened for brevity)
Directories part:
<Directory Id="INSTALLLOCATION" Name="sth">
<Merge Id='MyModule3' Language='1033' SourceFile='MergeModule.msm' DiskId='1' />
</Directory>
Feature part:
<Feature Id="ProductFeature3" Title="Tit" Level="1" Description='Yeah' ConfigurableDirectory='INSTALLLOCATION' Display='expand'
AllowAdvertise='no'>
<MergeRef Id='MyModule3' />
<ComponentGroupRef Id="Product.Generated" />
</Feature>
After building WIX project it throws errors like:
ICE83: Both MsiPublishAssemblies AND MsiUnpublishAssemblies actions MUST be present in InstallExecuteSequence table.
ICE83: The MsiPublishAssemblies action MUST be present in AdvtExecuteSequence table.
I've added lines:
<InstallExecuteSequence>
<Custom Action="PreventDowngrading"
After="FindRelatedProducts">NEWPRODUCTFOUND</Custom> //i suppose it doesnt influence nothing here
<MsiPublishAssemblies Sequence="1502" />
<MsiUnpublishAssemblies Sequence="1501" />
</InstallExecuteSequence>
And:
<AdvertiseExecuteSequence>
<MsiPublishAssemblies Sequence="1502" />
</AdvertiseExecuteSequence>
After that buildling process doesn't return any errors, but despite installing the feature (selected on feature list) there are no feature files on the HDD. I think it might be caused by Sequence numbers but i haven't got any ideas how to fix them, anyone can help?
If more info is needed i'll surely provide it.
I can think of a number of things that can go wrong. I'd look at the install log to see if the files got installed, just not where you were expecting them to get installed. I've known VDPROJ MSM's to have a great many problems including authoring their directory tables incorrectly.
You might want to look at an open source project that I created called IsWiX (CodePlex.com). It's designed be a UI authoring tool for WiX Merge Module projects that also allows you the raw ability to add additional metadata using traditional WiX XML. The result is a very clean merge module that can be consumed by InstallShield, WiX, VDPROJ, et al.

Can you set a conditional uninstall in Wix?

The installer sets up a default DB (if one doesn't already exist) and I want to exclude that from the uninstall process (Or have the user option to remove it or not, once I take the time to figure out customizing the GUI)
Seems like best practice would be to just create the DB at runtime rather than install time, but for the sake of argument, is this possible and how?
I know how to set it up to install it conditionally like this:
<Feature Id="Database" Display="hidden" Level="1">
<ComponentRef Id="DatabaseComponent"/>
<!-- Cancels installing of new DB if it already exists-->
<Condition Level="0">DBEXISTS</Condition>
</Feature>
But I'm not sure about how to put a conditional on an uninstall.
Make the Component permanent (Component#Permanent="yes").