I have to create a set up file for a client app for LIVE/QA/UAT environments and the only difference between them is the app.config file. Can you please suggest an easy way to accomplish it?
A good approach is modifying a template app.config based on user input:
configure your app.config file to use installer properties: http://wix.sourceforge.net/manual-wix2/wix_xsd_xmlfile.htm
create some custom dialogs which retrieve the element information from the user and save them in your custom properties
If you need to update just certain value in app.config based on user input, then the solution outlined by #Cosmin would work best. There are a couple of other options depending on your requirements:
in case you can define the app.config differences at buildtime, and if it's fine to have 3 different MSI packages (one per environment), it's better to author 3 components holding the app.config for each environment wrapped in the preprocessor logic. As a result, you'll end up with an MSI package for a specific environment depending on how you build
in case the choice depends on a certain user input, you can still author 3 different components with mutual exclusive conditions, and this conditions will depend on the user input
I've solved this before by using something along the lines of this in my main wxs file:
<?include $(sys.CURRENTDIR)Properties$(var.Configuration).wxi?>
(It points to e.g. C:\MyProjectDir\PropertiesDebug.wxi, C:\MyProjectDir\PropertiesUAT.wxi, etc. depending on the active solution configuration).
However, I now prefer using the new Microsoft method of having the web.config and app.config transforms for each platform, because it can help to shift the burden of maintaining these settings onto the developers who create them as they go, rather than just leaving it all to the guy that writes the installer app at the end.
The app.config transforms are not built into VS2010, but there is an add-in available:
http://visualstudiogallery.msdn.microsoft.com/69023d00-a4f9-4a34-a6cd-7e854ba318b5
The web.config transforms are built in already:
http://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx
Related
My program deploys with a configuration option that I've chosen to expose as a feature. This option can be one of two values.
Each configuration changes a set of settings files. They have different input file names (for the sake of example, let's call it option1-config20-lv80.xml), but should be installed to the configuration directory as config20-lv80.xml. Each option has a prefix that should be stripped like that, which also means only one of these options can be selected for install at a time. However, even with conditions preventing the install of one feature when the other is selected, my output is littered with:
LGHT0204: ICE30: The target file 'config20-lv80.xml' is installed in 'path' by to different components... This breaks component reference counting.
How can I give my users the option to choose between these configuration options and get around my ICE30 issues without any negative side effects?
I saw an similar question answered, but I'm not 100% sure how to implement it in wix#, or if there are other ways open to me to achieve my goal without disabling ICE30 validation or creating 2 installers.
A bit rushed, have a look...
Milk & Honey Winnie: In cases like this I prefer to install both files with different names using two different components and then switch between them with an option shown in the application itself. On launch or in the preferences. Makes deployment simpler, it is already complex (section "The Complexity of Deployment"). The linked answer you refer to can work technically, as can more hacky approaches.
Alternatives: I have a long answer here on different ways to install settings files: Create folder and file on Current user profile, from Admin Profile ranging from eliminating the whole file and using internal defaults, to downloading settings files from the network or just relying on clouded web-service settings retrieval from a database. Not 100% match, but maybe give it a skim?
A related issue is when you have a settings file that regular users can't write to. This is a list of approaches for eliminating that condition: System.UnauthorizedAccessException while running .exe under program files.
What is the standard way to handle web.config files during major upgrade.I'm aware how the unversioned files are handled during upgrade,the file will not be replaced if the file has been modified by the user.
Is there a way to deal with the scenario where in there are new entries added to config file bundled with the latest installer that needs to be installed,and also retain the existing entries modified by the user during major upgrade in Wix.
The simple solution that a lot of my customers have liked is to not put user data in the web.config. Instead we use the AppSettings#file and ConnectionStrings#ConfigSource elements to specify an override file and keep the user data there. What MSI doesn't know about it won't tamper with. Now you don't have to be an MSI component rules wizard.
https://msdn.microsoft.com/en-us/library/ms228154(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/system.configuration.sectioninformation.configsource(v=vs.100).aspx
I know the question is for Wix, but just wanted to point out how much time commercial tools can save in such scenarios.
For example, using Advanced Installer you can read and load into an MSI property any XML values and then use the XML Files updater to write dynamic content in the files, at install(upgrade) time. (check the videos at the end of each article for a quicker overview)
Disclaimer: I work on the team building Advanced Installer.
Set the component to always overwrite and write a custom action to add the needed information to the config file.
The only way that seems possible is a custom action to merge the entries in the new file into the existing file, because you want data from the existing a new files. You would also need the upgrade scheduled late (after InstallExecute) so that the upgrade isn't an uninstall of the old product followed by an install of the new product.
If you are doing an upgrade (the WIX_UPGRADE_DETECTED property will be set by a MajorUpgrade element), so update the existing file, otherwise install the new one.
There might be a way to express the updates as an Xml transform, so something in the WiX util:xml tools might help do an update.
As part of my WIX setup project, I am updating some values in the app config for the service I am installing. One of the attributes is a number, this is the number of the location the service is being installed at.
The location is part of the machine name, for example the machine name might be "location16server". I am trying figure out if I can get a substring or otherwise parse the number out of the machine name so that I may use it to update the .config file. I don't see any ways that are part of WIX, but maybe with a custom action?
Thanks
A custom action would be required. I'd provide caution on this though as you are tightly coupling along a machine name. This might work well in a controlled environment but could cause major headaches down the road. I'd look for some other artifact on the machine to determine location numbers and other configuration data. Perhaps even move it out of the installer and into the application if possible.
Another option is to insert a dialog box that allows the user to enter some optional parameters for the program being installed.
Here are some examples:
http://www.merlinia.com/mdt/WiXTutorial3.msl
http://wix.tramontana.co.hu/tutorial/user-interface/new-link-in-the-chain
I am trying to do a custom action at the time of msi installation. But the dll required for my custom action is depends on other dlls. At the time of installtion it is giving the error like "a dll required for this install to complete could not run".How can I load the dependent dll files for this custom action to run properly.
The code that I am using is
<CustomAction Id='CheckingPID' BinaryKey='CheckPID' DllEntry='ValidateKey' />
<Binary Id ='CheckPID' SourceFile='$(sys.CURRENTDIR)\LicenseKeyClient_32d.dll'/>
<Binary Id ='CheckPID2' SourceFile='$(sys.CURRENTDIR)\curllib.dll'/>
<Binary Id ='CheckPID3' SourceFile='$(sys.CURRENTDIR)\libsasl.dll'/>
<Binary Id ='CheckPID4' SourceFile='$(sys.CURRENTDIR)\openldap.dll'/>
The files that you add in binary table usually get extracted with temporary names during the installation, so your DLL will not be able to locate the other DLLs you add next to it.
A workaround is to add those DLLs as normal files in the Temp system folder and delete them when the installation ends. This has the limitation that you need to set your custom action as deferred, so it executes after the files are installed, thus your DLLs get copied to Temp folder.
I don't know if wix has a support for temporary files, similar with the one present in Advanced Installer, but if not you could try to write a custom action to simulate it. Basically what Advanced Installer does is to extract those files in the Temp folder the moment the MSI is launched, and also deletes them when the installation is complete. This has the advantage that you can use the temporary files and in immediate custom actions, i.e. well before the files from your package are installed.
Despite Bogdan's excellent answer, allow me to add my 2 cents:
It looks like you are dealing with some form of license key validation? The best way is generally to deal with your license keys in the application itself, unless you want it written to HKLM instead of HKCU - in which case you might need the temporary admin rights generally acquired during installation.
You can also open a HKLM key for writing during setup, and write it from the application though this is generally frowned upon security-wise. This allows you to write a single license key for all users directly from the application.
The application features more flexibility and control of the process of registering your license key, and crucially an easy way to run the process again. From my perspective this is almost always needed for a serious application - often due to trial versions with the eventual need to register the license key at the end of the trial period from within the application itself - instead of uninstalling the application and reinstalling, or running the setup in repair / maintenance mode - which seems extremely clunky.
I have described this issue previously in some more detail: Reasons to deal with licensing in the application rather than the setup.
I'll also add that WiX DTF .NET custom actions really simplify this problem by allowing you to embed content into the self extracting custom action package and make them available in the current directory at runtime. Very easy.
But yes, Glytzhkof is correct. Any licensing / DRM done inside of an MSI is easily defeated. It's best to do this in the app or both. For example I've worked at companies where it's a share responsibility. You can enter one now or later. I've also worked at companies where the license key had bits embedded in it that drove feature selection. It gets complicated fast so try not to have to go down that road.
To give you a background - I have a 4 MSI's which comes from our vendor and this has to go to our company servers (we are looking at around 3500 servers). As of now, my counterparts are managing this using vbs, ps1 scripts. But the problem with the script is that everytime an update comes we have to worry about uninstalling the existing package before running the new one and a ton of hardcoding.
I want to automate the whole process (with very less hardcoding) by setting up a WIX script to package all the 4 MSI's together. I read about the WIX bundle and used that to create a single MSI. But now there are lot of a variables to be passed to the 4 MSI's, so I thought of using custom actions to set these variables based on the environment/machine where the MSI is running. But I cant make custom action to work? Am i missing something?
A little bit of googling and I saw something like there are no CustomActions in Bundle? can someone confirm?
Also if there are no CA's what are my options? how can I manipulate the variables to be passed on to the 4 MSI's? Most of them needs to be set based on the machine its being run (like install path, user id's, app pool id's etc).
There is a fourth option, a useful lightweight hack, identified by Vijay Kotecha (see http://vijayskotecha.blogspot.com/2013/07/wix-bootstrapper-custom-action.html),...
Essentially, build an <ExePackage> around a pass-through .bat or .cmd batch file. The batch/command file contains the single line '%*' which re-executes all of the command line arguments as a first class command.
Thus:
<ExePackage ... SourceFile="SourcePath\WixCustomAction.cmd"
InstallCommand="my_custom_action.exe my_custom_parameters" />
<ExePackage ... SourceFile="SourcePath\WixCustomAction.cmd"
InstallCommand="my_next_action.exe my_next_parameters" />
Where WixCustomAction.cmd is a file containing only '%*'.
These <ExePackages> can be placed into the <Bundle><Chain> successively as needed using different InstallCommands as needed.
As I see it, you have three options:
Depending on what information you need, you can use the WixUtilExtension to perform simple tasks such as reading registry keys and performing file searches, which you can then pass the results to your installation packages as properties.
Implement custom actions in the individual installation packages themselves (not in the bundle).
Write your own custom bootstrapper application to determine all the properties you need to set, and then pass them to your installation packages. This is more complex than the #1 and #2, but if your interested the following links should get you started:
introducing managed bootstrapper applications and
write a wpf wix installer