I'm in the process of upgrading an old Visual Studio setup project installer to a WiX installer.
I have a problem with the new installer though - it keeps removing a config file that was installed with the old installer.
The component in the .wxs file looks like this:
<Component Id="MyConfig" NeverOverwrite="yes" Permanent="yes">
<File Id="MyApp.exe.config" Name="MyApp.exe.config" />
</Component>
I tried setting the component Id and Guid to the same as they were in the old installer, but then it replaces the existing config file with the new one - which I don't want, as the config file may have been modified since the initial installation.
What I want, is if MyApp.exe.config is already installed it should not be removed or replaced.
Make sure your RemoveExistingProducts is scheduled after InstallExecute, eg: afterInstallExecute. GUID and Keypath of the component need to be the same as they were in your previous installer. MSI will only overwrite the old config file if it's modified date is equal to its create date. If the modified date is after the create date the config file was modified and MSI will not overwrite. You shouldn't need the Permanent attribute, that makes this file leaked on uninstall. Don't use NeverOverwrite either: per the docs this is only for registry.
Related
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
After successful upgrade of the product, one file were not replaced for unknown reason (MSI log is missing). This is not a DLL file where the problem would probably be version. It is some custom binary file that (important note) during lifetime of older version was manually overwritten with newer file. Is there way to force file replacement?
This is how file node looks like:
<Component Win64="yes" Id="cmpSOMEFILE" Guid="*">
<File Id="filSOMEFILE" KeyPath="yes" Source="SOMEFILE.dll.sig" /></Component>
If you need the file to always be replaced, then how about using a <RemoveFile> in the same component to cleanup the file first.
The RemoveF0iles action should be scheduled before the InstallFiles and the file will be removed and replaced with the newer copy every time.
Refer this:
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Using-wix-how-to-always-overwrite-a-file-td6904118.html
We have a MSI built with wix that installs our ruby based product. When we released the first version there was a bug. Upgrades would overwrite changes to a ruby config file (gemrc), effectively breaking the product in some cases.
I've been trying to get MSI to not remove or replace the config file on upgrades, without success.
What i have now is:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallExecuteAgain" />
</InstallExecuteSequence>
<Directory Id="embeddedDir" Name="embedded">
<Directory Id="embeddedEtcDir" Name="etc">
<Component Id="gemrcComponent" Guid="uuid..." NeverOverwrite='yes' Permanent='yes'>
<File Id='gemrc' Name='gemrc'
Source='$(var.ProjectSourceDir)\embedded\etc\gemrc.default' Vital='yes' KeyPath='yes' />
</Component>
</Directory>
</Directory>
However, going from the current version (1.0) to the new version (1.1) will leave the installation with no gemrc at all. Going forward it works, so going from 1.1 to 1.2 it leaves the existing (modified) file.
I'm assuming, that the reason it doesn't work is because it uses the old 1.0 MSI to remove the existing installation, and that version has the gemrc file marked as part of the product that needs to be removed.
This means the only way i could get around this is using custom actions (copy the file to a temp path before installation, and then move it back afterwards.
Or something similar). Is there a better/easier way?
Some of the reasons you may be seeing this are as follows, but there's not enough information to say which might apply in your cases:
If you originally had a major upgrade scheduled "early" (InstallInitialize or sooner) then the upgrade would completely uninstall the older product and then install the new one. This would look like an overwrite of the config file, but strictly speaking it's not. You do not say if you ever identified the actual root cause of this issue or if the major upgrade was scheduled differently.
In a major upgrade scheduled after InstallExecuteAgain, the upgrade installs on top of the old product and follows file replacement rules. So if the config file had really been updated after install it would not be replaced.
If the component id of the config file changed between any of the setups then you'd see it removed (even in an InstallExecuteAgain upgrade). File sharing is ref counted by component id, so if the upgrade has a component id for the config file that is not the same as the previous installs then you'd see strange behavior because the ref count of the previous file means it would be removed, but you're attempting to install another of the same name with different id.
You should do your upgrades with verbose MSI logging enabled to see what happens to the config file. If it's not clear from that, then post it somewhere accessible for others to look at.
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.
Good time,
I'm trying to create the uninstallable patch (msp file) which should contain the newly added files. The file is added in following maner:
<Directory Id="Some Dir">
<Directory Id="MYDIR" Name="Some Name">
<Component Id="Some Component" Guid="{GUID}" KeyPath="yes">
<File Id="README.txt" Name="README.txt" Source="to_install\README.txt" KeyPath="no"/>
<File Id="default.cfg" Name="default.cfg" Source="to_install\default.cfg" KeyPath="no"/>
... // some more files
</Component>
...
...
I've also tried using the DirectoryRef but got the same results.
The "MYDIR" directory is used in other places also and several other files are already installed there, but the patch is adding new files, and the installation log shows that the CreateDirectory table becomes modified and the uninstallation for patch becomes disabled.
What is a correct way to do it using WiX?
KeyPath :
This value points to a file or folder belonging to the component that the installer uses to detect the component.
It is creating entry in CreateFolder of MSI because of KeyPath is provide at component level that is taking installation folder as its key so your patch become not uninstallable.
Provide KeyPath at one of the file of component that is the most important for that component. So it does not make entry into CreatFolder table of MSI and your patch become uninstallable.
Whether a patch is uninstallable isn't really related to a piece of WiX source like that. One thing you definitely need for an uninstallable patch is a PatchMetadata table that says that the patch is uninstallable, as here:
http://wixtoolset.org/documentation/manual/v3/patching/patch_building.html
or here, see PatchMetadata table if you use a PCP file, AllowRemoval:
https://msdn.microsoft.com/en-us/library/aa370344(v=vs.85).aspx
So there are some things you need to do during patch creation to make the patch uninstallable that are nothing to do with your WiX source. It's not clear from your question how you are creating the patch correctly.
Even if you get the patch generation working, there are some rules that must be followed, described here:
https://msdn.microsoft.com/en-us/library/aa367850(v=vs.85).aspx
where it says (for example) that you can't change the component ids of any existing installed items. Create a verbose log when installing the patch and look for messages like SELMGR and entries saying removl of components is not supported, and if that has happened it means the patch will not apply correctly.