I have created an installer which copies a config.ini and asks the user for values which are then inserted into the ini file. This works fine during a fresh install and major/minor upgrades.
<Component Id="ConfigIni" Guid="GUID-GOES-HERE" DiskId="1">
<File Id="ConfigIniFile"
Name="config.ini"
Source="../../artefacts/etc/template-config.ini"
KeyPath="yes"/>
<IniFile Id="ValueOne"
Action="addLine"
Directory="ETC"
Section="sectionone"
Name="config.ini"
Key="valueone"
Value="[VALUEONEPROPERTY]" />
<IniFile Id="ValueTwo"
Action="addLine"
Directory="ETC"
Section="sectiontwo"
Name="config.ini"
Key="valuetwo"
Value="[VALUETWOPROPERTY]" />
</Component>
However, if a user tries to install the same version of the product which is already installed, the installer enters repair mode. I'm not sure how repair mode works, but in the case of the config.ini file, it seems to be deleting the one with populated values, copying it again, and because it's a repair it's not got any user values to populate the config.ini file with, so the file is blank.
Is there any way of getting the installer to ignore this file on repair, or get the original user values?
The basic problem is the property values not being preserved. There is no magic that automatically saves the values of properties between an install and a repair (or adding new features etc). The problem is not that the file is being replaced because Windows will not replace files that have been modified with user data.
In WiX, use the "remember property" pattern to save the values of properties so that they are restored in these maintenance cases.
Related
My customer wants to see some "version number" in file name of the program's desktop shortcut. For example: "Foobar 10.lnk" or "Foobar 12.lnk".
Therefore, we have the following snippet in one of our .WXS files:
<DirectoryRef Id="DesktopFolder">
<Component Id="..." Guid="...">
<Shortcut Id="...." Name="Foobar_10" ... />
<RegistryValue ... />
</Component>
</DirectoryRef>
Every time we release a new version, we update that .WXS file. There's no issues in this scheme while we are producing major upgrades, because our major upgrades first uninstall existing product, and then install new version.
But now we have to release a minor upgrade. And put "Foobar 10.1.lnk" file into the "Desktop" directory. We have, therefore, one MSI file for version 10, another one for version 10.1 and MSP patch to upgrade the product from version 10 to version 10.1.
According to Changing the Product Code it's legitimate to add or remove new shortcuts using a minor upgrade:
The update can add, remove, or modify the ... shortcuts of components that are not shared by two or more features. ... If the update removes resources, it should also update the RemoveFile and RemoveRegistry tables to remove any unused files, registry keys, or shortcuts that have already been installed.
Had we install the MSP file with shortcut snippet from above, we would end up with two shortcuts in the "Desktop" directory: Foobar_10.lnk and Foobar_10.1.lnk due to transformation applied to the Shortcut table. Therefore, according to the article I already mentioned, we have to update the RemoveFile table:
<DirectoryRef Id="DesktopFolder">
<Component Id="..." Guid="...">
<Shortcut Id="...." Name="Foobar_10.1" ... />
<RemoveFile Id="..." Name="Foobar_10.lnk" On="install" />
<RegistryValue ... />
</Component>
</DirectoryRef>
Now, if one installs that MSP file onto already installed ``Foobar version 10'', he/she gets single .LNK file inside the "Desktop" directory -- Foobar_10.1.lnk.
So far so good.
But if one removes that minor upgrade using the system's "Control panel" (minor upgrade only, therefore, reverting back to ``Foobar version 10''), he/she gets two shortcuts again: Foobar_10.1.lnk "remained" from MSI+MSP, and Foobar_10.lnk created by the CreateShortcuts action from the transformed-back Shortcut table.
My main question is: how I can remove file Foobar_10.1.lnk when the MSP minor upgrade is get uninstalled? What actions/properties should I "check" to catch such un-installation?
By the way, I tried to get log from un-installation of a minor upgrade, but I failed to uninstall an upgrade using the command line. For example, this:
msiexec -uninstall {valid-patch-guid-here} -package foobar.msi
ends up with the maintenance mode for 'foobar.msi'. Both the following commands:
msiexec /I {valid-product-code-guid} MSIPATCHREMOVE={valid-patch-guid}
msiexec -package {valid-product-code-guid} -uninstall {valid-patch-guid}
give the same (these commands are from Uninstalling Patches).
I can remove a minor upgrade using "Control panel" only. Therefore, I can't get un-installation log. Without it I can't see what happens during that process. I know it's a bad idea to ask two question at once, but may be anyone knows how to remove a patch using the command line?
Thanks.
I found a solution -- ``Transitive components''. A minor upgrade: a) adds new transitive component for a shortcut (on the "Desktop" and/or in the "Start menu") with condition evaluated to 'true', and b) modifies conditions of existing "shortcut components" to be evaluated to 'false'.
Inspired by "Minor upgrade fails on removing files" topic on SO. Thanks christopher-painter#.
When uninstalling my application, I'd like to configure the Wix setup to NOT to remove few files that were added as part of the installation. It seems like the uninstaller removes all the files that were originally installed from the MSI file. How do I do that?
Here are my files which I wish to keep it forever
<Binary Id="RootCABinary" SourceFile="Assets\Certificates\RootCA.cer" />
<Binary Id="SubCABinary" SourceFile="Assets\Certificates\SubCA.cer" />
I have used WixIIsExtension.dll to install these certificates to the windows store.
Overwrite: Is it important that the file never gets overwritten? If so, add
"Never Overwrite" to your component. WiX attribute: NeverOverwrite="yes". Remember to test upgrade scenarios!
Permanent Component: As stated by Pavel, you can set a component permanent:
<Component Permanent="yes">
<File Source="License.rtf" />
</Component>
Blank GUID: Another way to do it is to set a blank component GUID. It essentially means "install and then leave alone". No repair or uninstall should be done (remember to add NeverOverwrite="yes" if the file should never be overwritten):
<Component Guid="" Feature="MainApplication">
<File Source="SubCA.cer" KeyPath="yes" />
</Component>
Read-Only Copy: I sometimes install files to a per-machine path (for example somewhere under program files) and then copy them to a per-user location (somewhere in the user-profile) on application launch, and then do operations on them that entail that the files should not be deleted. This is good in cases where you want to do something that change the files in question (they need to be writable). Then it is good to "untangle" them from deployment concerns (files will not be meddled with by installer operations at all - the installer has no knowledge of them). The original read-only copy installed to program files can be uninstalled though (no longer needed?).
Other approaches: You can also create such files using custom actions during installation (usually text files only), you can download the file in question from your web site on application launch (makes the file easy to manage and update / replace? Vulnerable to connection problems - firewalls, etc...) and the application can create the file using "internal defaults" in the main executable on launch. And there are no doubt further approaches that I can't recall.
Put your binaries in a separate WiX component and make it permanent. Have a look at this thread as well
I have a data file that is installed with my application. When it is installed fresh, the data file gets installed properly. When it is upgrading, it was always overwriting the existing instance of the file, which was not wanted. I added the NeverOverwrite="yes" flag, and now for a new install is still the same, but for an existing install, it is deleting the existing file, and not installing the new file either. Have I used the flag incorrectly? This is the snippet in question:
<Component Id="cmp8553E6DDC92DBCDC568FB76CA13E7AF2" Guid="{C94263EB-56AF-4B19-942F-C92998252932}" NeverOverwrite="yes">
<File Id="fil7C9456E83E3FB4618684509DEEF67EBD" KeyPath="yes" Source="$(var.CDWrapper.ProjectDir)..\foo\bar" />
</Component>
Turns out I didn't have a full understanding of the NeverOverwrite flag and our usage of it. I will have to find a different method to preserve the existing file instead of always installing a new copy, but that's a whole different issue that should have reasonable answers elsewhere.
I have a WIX installer set up for my application and it installs correctly and updates correctly except that it re-writes the default user settings (i.e. defined in properties-> settings) that are defined in my application and corresponding dll's. How can I have WIX update the application, but not update the user settings?
Whether it's ini, registry or xml the concept is simple. Only have the installer responsible for installing defaults settings. Then on first run on your application copy the default settings to the user settings one time. Now the installer will never harm user settings because it doesn't even know of their existence.
Properties -> Settings are mapped to the app.config file for your application, so you can setup the install for that particular file to NeverOverwrite, meaning updates will not overwrite your .config file.
Working example:
<Component Id="SPECTRAVIEW.WPF.MAINAPPLICATION.EXE.CONFIG" Win64="$(var.Win64)" Guid="89E2C6C0-18FB-428B-A9EE-C2FAB3418CB2" NeverOverwrite="yes">
<File Id="SPECTRAVIEW.WPF.MAINAPPLICATION.EXE.CONFIG" Name="SpectraView.WPF.MainApplication.exe.config" Source="$(var.MainApplication.TargetDir)\SpectraView.WPF.MainApplication.exe.config" KeyPath="yes" />
</Component>
I created one installer with IzPack. Everything works fine. Now I'm wondering, is there a good way to create one installer that will take care of update the application if this already exists?
I tested running the installer again, but he not recognize that the application is installed.
I have used IzPack for installing and updating. IzPack does not natively tie in with any packaging system so there is no way for IzPack to conclusively know if something has been installed. You might try to interact with registry or some specific flie you create at install time but that is still messy (to me anyway).
IzPack does however check if a file already exists before overwriting it so if you are running an update then an example is that you would want binaries to be updated but user configuration left alone so do something like this inside the packs element:
<packs>
<pack name="CorePack" required="yes" preselected="yes">
<description>The core of the app.</description>
<file src="bin/binaryapp" targetdir="$INSTALL_PATH/bin"
override="true">
<os family="unix" />
</file>
<file src="etc/config.conf" targetdir="/etc/appdir">
<os family="unix" />
</file>
</pack>
</packs>
You see that the binary has override="true" where the config does not (by default override=false). Binary gets updated, config does not.
Jeff
CheckedHelloPanel will do your job, at least for windows. It writes something to the registry and checks this if you try to reinstall.