WiX: keep (rename) file on uninstall - wix

My application has a settings file which I need to keep when user uninstalls the app. Can I do this using components, or do I need to use custom actions?
This is what I have so far (not working):
<Directory Id="INSTALLLOCATION" Name="_MyApp">
<Component>
<File KeyPath="yes" Source="$(var.Source)\settings.ini" />
</Component>
<Component Id="Backup" Guid="SOME-GUID">
<Condition>REMOVE=ALL</Condition>
<CopyFile Id="settings.ini" Delete="no" SourceProperty="INSTALLLOCATION" DestinationProperty="INSTALLLOCATION" SourceName="settings.ini" DestinationName="settings.ini.bak" />
</Component>
</Directory>
If it matters, these components belong to:
<Feature Id="Default" Level="1">
<ComponentRef Id="settings.ini" />
<ComponentRef Id="Backup" />
</Feature>
I suspected this does not work because action MoveFiles runs after RemoveFiles and then there's nothing left to move, so I removed settings.ini from installer and copied it manually after installation. I was thinking this way the ini file is still there after RemoveFiles and it will be renamed. Well, the ini file is there indeed but it doesn't get renamed. Any idea why?

Windows Installer doesn't have a built-in mechanism for backing up and restoring files. Usually the solution is to use a custom action which copies the file.
I removed settings.ini from installer
and copied it manually after
installation. I was thinking this way
the ini file is still there after
RemoveFiles and it will be backed-up.
Well, the ini file is there indeed but
it doesn't get backed-up.
Try creating an uninstall log and see what happens when MoveFiles is executed. As a side note, I don't see how copying the file manually after install is better than a backup custom action.

Related

Hot ti Install File just in the first time with WIX

I have a component
<Component Id="ProductComponent" Guid="7935315f-4242-4c7a-a02c-6fd256805356">
<CreateFolder/>
<File
Id="propFile"
Name="aaa.properties"
DiskId="1"
Source="$(var.Project.TargetDir)"
Vital="yes"
KeyPath="yes" ></File>
<?endif?>
</Component>
I want to copy the file just on install , not upgrade.
But I can't find how to do it.
Any idea?
Have you tried using Condition element. I think you can provide a Condition inside Component element to check whether product is already installed or not. If not installed, then create file.
<Component Id="ProductComponent" Guid="7935315f-4242-4c7a-a02c-6fd256805356">
<Condition> NOT Installed </Condition>
<CreateFolder/>
<File
Id="propFile"
Name="aaa.properties"
DiskId="1"
Source="$(var.Project.TargetDir)"
Vital="yes"
KeyPath="yes" ></File>
</Component>
This is a weak spot of MSI (which WiX uses).
MSI installs a file
User modifies the file
MSI goes to install the file. Should it:
a) overwrite and lose user data
b) not overwrite and lose new applciation data
c) merge --- MSI doesn't support this.
If the user data is only one or few attributes there are tricks with custom actions to harvest the user data and reapply it but this is very tricky stuff.
IMO, the best way to approach this is never keep user data in a file installed by the installer. Take app.config appSettings element as an example. It was an atttribute that allows you to extend the file with another file that overrides the settings in the first file. Using this pattern the installer can lay down the app config and the application can create the override file and everything just works because MSI doesn't have to deal with the problem at all.

How to update INI file that is marked as read-only (WiX toolset)

I have a small installer project in Wix Toolset. One of the INI files I need to modify might be marked as read-only and the installer refuses to modify it.
Is there any way to force installer to do the INI modification? All I found was permission setting during file installation, however this file is not part of the installation.
My component looks like this:
<Component Id="FooBar.ini" Guid="GUID" KeyPath="yes" Permanent="yes">
<IniFile Id="FooBar.ini" Directory="FOOBARDIR" Name="FooBar.ini"
Action="addLine" Section="Foo" Key="Bar" Value="1" />
</Component>

Why are logs left after removal of an application has occurred?

I am struggling against the issue with wix toolset: why after I uninstall an application some folders including the "logs" are not deleted? is it a bug or not?
<Directory Id="logs" Name="logs">
<Component Id="logs" Guid="0A4D0A3F-2E0D-1B1A-1C6D-1A0F8FAAABC6" Win64="$(var.is64)">
<CreateFolder Directory="logs">
<Permission GenericAll="yes" User="Everyone" />
</CreateFolder>
<RemoveFolder Id="logs" On="uninstall"></RemoveFolder>
</Component>
</Directory>
Sometimes if the application you install generates files or folders after the installation, that can prevent WiX from removing the parent folder during uninstall.
If there are log files created after install, you can purge them by adding this to your existing component:
<RemoveFile Id="RemoveLogFiles" Name="*.*" On="uninstall" />
If your application also creates subdirectories and RemoveFile doesn't get rid of them, I would look into using RemoveFolderEx(http://wixtoolset.org/documentation/manual/v3/xsd/util/removefolderex.html). This would require you to to create a Property and write the directory path to a place in the registry so you can set the Property before RemoveFolderEx runs. You can't just use the Directory Id because RemoveFileEx runs before the MSI creates the Directory properties. Read the link I provided if my explanation didn't make sense to you.
Hope this helps!

WiX: Managed to not overwrite config file during upgrade, however shortcuts are removed

I have a similar problem like forki23 by bring Wix to not overwrite a configuration file during upgrade. I have a config file that should not be overwritten during upgrade, but it should be removed during uninstall. However every solution I find, breaks something else.
If I set NoOverwrite=yes and move the RemoveExistingProducts to InstallFinalize the config file is handled as I wished. However, in this case the shortcut is removed during upgrade for some reason. If I leave RemoveExistingProducts at InstallInitialize, the config file is actually removed during upgrade, however the shortcuts are present.
Why is this happening and is there are way to fix it?
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
<!-- InstallInitialize causes config-file to disappear during upgrade -->
<!-- InstallFinalize causes shortcuts to disappear during upgrade -->
...
<Property Id="DISABLEADVTSHORTCUTS" Value="1" />
...
<Directory Id="INSTALLLOCATION" Name="MyApp">
<Component Id="MYAPP.EXE" DiskId="1" Guid="...">
<File Id="MYAPP.EXE" Name="MyApp.exe" Source="..." Vital="yes" KeyPath="yes">
<Shortcut Id="startmenuShortcut"
Directory="ProgramMenuDir"
Name="!(loc.ProductName)"
WorkingDirectory='INSTALLLOCATION'
Icon="Icon.ico"
IconIndex="0"
Advertise="yes" />
</File>
<RegistryValue Root="HKLM"
Name="InstallLocation"
Key="$(var.InstallLocationRegistryKey)"
Type="string"
Value="[INSTALLLOCATION]">
</RegistryValue>
</Component>
<Component Id="MYAPP.EXE.CONFIG" DiskId="1" Guid="..." NeverOverwrite="yes">
<File Id="MYAPP.EXE.CONFIG"
Name="MyApp.exe.config"
Source="..."
KeyPath="yes" />
</Component>
...
</Directory>
...
<Directory Id="ProgramMenuFolder">
<Directory Id="ProgramMenuDir" Name="!(loc.ProductPrefix)">
<Component Id="ProgramMenuDir" Guid="...">
<RegistryValue Root="HKCU" Key="SOFTWARE\MyApp"
Type="string" Value="[INSTALLLOCATION]" KeyPath="yes" />
<RemoveFolder Id="ProgramMenuDir" On="uninstall"/>
</Component>
</Directory>
</Directory>
Note A: The config-file is a machine-wide configuration and should apply for all users.
Note B: I'm using WiX 3.7 and the target plattform is Windows 7 and 8.
Theoretically "NoOverwrite=yes and move the RemoveExistingProducts to InstallFinalize" should work, but it s clear we are losing something from the big picture. The best method to see why Windows Installer removes the shortcuts is to create a verbose log when launching the upgrade setup. You can do that in a cmd.exe with this command: msiexec /i [msi path] /L*V debug.log
The post the a download link for the log and the GUIDs of the components hosting the shortcuts so we can see if the log helps us understand what happens.
Windows installer works very exact in those things, and if anything gets removed in the After="InstallFinalize" case, this means, that a component has been removed, MSI has thought is not needed, because not contained in your new version of the msi file. Be very sure the GUID of the component containing MYAPP.exe and the shortcut has not changed in your new version. (Compare with a tool like Orce or Insted). It seems it has!
MSI removes only full components, not only shortcuts. Really! Maybe you have an update problem of shortcuts in Windows. Sometimes such things happen. Try to reboot to be sure, that this happens, what you think. Maybe there is an error in your test procedure (or it's the above mentioned GUID problem). There are not many other possibilities, if you have not custom actions which remove shortcuts or you try to add shortcuts as files or such dangerous stuff.
Putting a shortcut in the same component as the .exe is common, but not optimal in my eyes! I recommend to separate resources as much as possible, so put it in an own component. This has advantages, if you later want to rename the shortcut. Then you can just change the GUID of this component and the important .exe file is not touched.
There is a small disadvantage of that, loosing the direct connection to the file version of MYAPP.exe in overinstall scenarios, so if MYAPP.exe is a shared file between several different setups, this is not recommended. Perfect solutions for this are possible, but are not in the focus here.
Workaround: If you are still able to change the old (first) msi setup, just mark the component MYAPP.EXE.CONFIG as permanent. Then it will not be uninstalled during Major Upgrade (but not uninstalled at all, what has advantages and disadvantages, in other words, it is mostly acceptable for .config files).
If version 1 of your setup is already shipped, then you could do the same with some tricks too.

Wix: Preventing a file from restoring by Windows Installer Service

We have a little situation here. We are writing an ini file at install-time using following code segment:
<Component Id="_CFG" Guid="{CADE766F-3AF0-40A6-9D35-12AC4FD5B278}" Feature="DefaultFeature" KeyPath="yes" Location="either" NeverOverwrite="yes">
<CreateFolder Directory="CFG" />
<Environment Id="SharedAppend" Name="Path" Value="[CommonFilesFolder]Company Shared\MyDir" Separator=";" Action="set" Part="last" Permanent="yes" System="yes" />
<IniFile Id="MyCFG.ini1" Action="addLine" Directory="CFG" Key="LOCAL_ROOT" Name="ata.ini" Section="ALIAS" Value="[CommonAppDataFolder]Company\MyDir" />
<IniFile Id="MyCFG.ini73" Action="addLine" Directory="CFG" Key="APPLICATIONS" Name="ata.ini" Section="GENERAL" Value="Product1;Product2;Product3;Product4;" />
<RegistryValue Id="Registry47asdf" Root="HKLM" Key="SOFTWARE\Company\MyProd" Name="LocalRoot" Value="[CommonAppDataFolder]Company\MyDir\" Type="string" />
</Component>
This installation is conducted by an Admin user. Now a 2nd user (Standard) modify this file via some application. After that when a 3rd user would logged in and launch the application, Windows Installer Progress Dialog appear and that would restore the file to original one.
I thought, "NeverOverwrite" would prevent this, but it didn’t worked.
I’m assuming that "NeverOverwrite" attribute may not be applicable on element.
Anyone have any idea how to prevent this file from restoring by Windows installer service?
Thanks a bunch..
Modification of an ini file should not trigger Windows Installer Resiliency. What happens is that a component will be reinstalled when its keypath (i.e. a certain file or registry entry) disappears.
So you need to figure out these things:
Which component installs the INI file? (I suppose it is not the component you show in your question, because that one only modifies INI files.)
What is the keypath of that component? (If it is not marked explicitly, wix will take the first file or registry entry in that component.)
Why is the keypath file or registry entry disappearing, thus triggering the reinstallation of that component?
Also, you might want to consider putting the ini file in its own component. This way, it will be its own keypath and it will only be reinstalled by the windows installer resiliency mechanism when it actually disappeared (and not when some other file or registry entry disappears.)