We use WiX for building installation packages. I am new to WiX technology and currently trying to do a major upgrade of the installed application, but on the different directory location than the previous version. For example, if v2 of a product was installed on Program Files (x86)\Old_path\Product , I would like to installed the upgraded version v3 on a different folder C:\Program Files (x86)\New_path\Product.
I have modified the msi property INSTALLDIR to have the new location path. We tried to alter the InstallExecuteSequence, added RemoveRegistryValues after InstallValidate to remove stored old path on registry and did WriteRegistryValues to add new registry values.
<InstallExecuteSequence>
....
<Custom Action="HxPrepare" Before="InstallValidate">NOT Installed</Custom>
<RemoveRegistryValues After="InstallValidate" />
<WriteRegistryValues />
<Custom Action="HxFinalize" Before="StartServices">NOT Installed</Custom>
....
<InstallExecuteSequence />
But I see no change in the installation process, and the new files get copied to the old directory path only. Can I know where is this old path obtained from even after modifying the INSTALLDIR path? How could we do this installation path change during major upgrades.
Reply to the comment by PhilDW :
That is a correct process for Major upgrade. All the older version files are removed. But however in our application, there is no browse dialogue during upgradation to ask for the new/required installation directory. It simply takes previous version path. This is because first we need to take a back up of important settings/user configured files of lower version and later use them in the upgraded version. After this backup is saved, I try to move this backup files to new path and later start copying new files. I do this path change to INSTALLDIR in HxPrepare step and want to continue the process in the new directory. But I cannot know from where the old path is only considered.
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
<Custom Action="PreventDowngrade" After="FindRelatedProducts">DOWNGRADE</Custom>
<Custom Action="HxInit" After="CostFinalize">NOT Installed</Custom>
<Custom Action="HxPrepare" Before="InstallValidate">NOT Installed</Custom>
<Custom Action="HxFinalize" Before="StartServices">NOT Installed</Custom>
<Custom Action="HxPreUninstall" Before="InstallValidate">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
<Custom Action="HxUninstall" After="InstallInitialize">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
The reason I want to perform this installation path change is because I want to change the product manufacturer name and I want the major upgrade of the product to happen on the new path like "C:\Program Files (x86)\New_manufacturer\Product installation" . How can I achieve this?
Related
I made something wrong in my installer, but I don't know what it is:
during uninstallation I see how all contents of the product folder is disappearing...
...and then, after uninstallation is complete, the contents is appearing again - my product is not uninstalled actually.
Such behaviour is not always, but happens accidentally (or I didn't catch some factors).
Can anybody help with this issue?
I have checked in the EventViewer that uninstallation completed with error 1603.
The documentation tells that this error means:
A system restart may be required because the file being updated is also currently in use.
But no product's files were opened during uninstallation. Also I stopped all applications from my product.
The reason became simple. In the InstallExecute sequence I had:
<InstallExecuteSequence>
<Custom Action="ModifyServiceConfig" Before="InstallFinalize"/>
</InstallExecuteSequence>
As a result, on uninstallation this custom action was calling too, and I got an error 1603.
I didn't considered the fact that instructions inside InstallExecute sequence are called during uninstallation too.
The fragment above must look like this:
<InstallExecuteSequence>
<Custom Action="ModifyServiceConfig" Before="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
That means that this custom action must be called only during installation.
I've created a WiX installer project and a CustomAction project. I've successfully added the MyCustomAction to the installation script and it works as it should.
However, the installer leaves empty folders in the [INSTALLFOLDER] every time the installer is executed. They're named MyCustomAction.CA.dll-, MyCustomAction.CA.dll-0, MyCustomAction.CA.dll-1 etc. Even the uninstaller won't remove them, so the amount of empty folders just get bigger.
Is there a way to prevent the folder creation? I've tried different Execute values (commit, deferred) but they don't seem to make any difference.
MyCustomAction is defined as follows:
<CustomAction Id="MyCustomAction"
Return="check"
Execute="commit"
FileKey="MyCustomAction.CA.dll"
DllEntry="MyCustomAction" />
<InstallExecuteSequence>
<Custom Action="MyCustomAction" Before="InstallFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
I found a solution to the problem: I had included the MyCustomAction.CA.dll in my product's installation files and not in its own Fragment. That caused the dll to be copied to the installation folder.
Now when the CustomActions are defined in their own Fragment the temporary folder is not created in the INSTALLFOLDER.
did you add a binary entry for them?
<Binary Id='FooBinary' SourceFile='foo.dll'/>
http://wixtoolset.org/documentation/manual/v3/wixdev/extensions/authoring_custom_actions.html
I'm creating an installer for a program using WiX. The program creates a log file and a .dat file in the program directory during the configuration process (after complete installation). How do I tell WiX to remove these files during the uninstallation process if they are not present during the installation process?
Any suggestions would be greatly appreciated.
One way is to define the problem out of existence by installing those files. That is, create and install an empty log file and a dat file—initialized to whatever empty or default is for it.
Another way is to put RemoveFile elements under the Component element that is most closely associated with the use those files (e.g., the program exe).
Are you sure you want writable files in the same directory as the program? Usually, programs are installed so that only administrators can change them. If the program uses data that any user can change to affect all users, the data would be stored under the ALLUSERS profile. And, data that a user can change that affects only that user would be stored under that user's profile.
When data is stored that way, it is a question as to when or even whether such data should be deleted. A user might want that data preserved for the next installation of the program even if the user doesn't know how the data is persisted.
This worked for me - use custom command and delete using "del" or "rmdir"
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Forced-remove-of-folder-and-files-within-td698425.html
<Product>
<CustomAction Id="Cleanup_logfile" Directory="INSTALLFOLDER"
ExeCommand="cmd /C "del install.log""
Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="Cleanup_logfile" After="RemoveFiles" >
REMOVE="ALL"
</Custom>
</InstallExecuteSequence>
</Product>
I have the following in my wix project but the msi file (which is valid and runs from the command line) will not run either with or without the silent parameter
<InstallExecuteSequence >
<Custom Action="Runmymsi" After="InstallFinalize">Not Installed</Custom>
</InstallExecuteSequence>
I have run into this before. Your issue is that you can't call an MSI from another MSI. These need to be run at separate times. I would suggest writing a bootstrapper that will run your MSIs in the proper sequence.
I have something like this:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
Since one of the uninstallation fails i need to execute a Custom Action to solve the problem BEFORE RemoveExistingProducts. Something in the lines of:
<CustomAction Id="FixStuff" .. />
<InstallExecuteSequence>
<Custom Action="FixStuff" Before="RemoveExistingProducts" />
<RemoveExistingProducts After="InstallValidate"/>
</InstallExecuteSequence>
This of course doesn't work since Custom Action cannot be before InstallInitialize. I'd really like to remove existing products between InstallValidate and InstallInitialize, but i'd like to execute FixStuff before removing existing products.
Is it even possible to do that?
Unfortunately you cannot run an elevated custom action before RemoveExistingProducts with your current configuration.
Some possible approaches would be:
Move RemoveExistingProducts right before InstallFinalize. This solves the custom action problem, but other problems may occur since this approach has many restrictions (the components need to maintain their names and GUIDs between versions, your custom actions should be aware that the upgrade is performed at installation end etc.).
Create an EXE bootstrapper which fixes the old installer before launching the new MSI. This bootrapper can require Administrator privileges through a manifest:
http://msdn.microsoft.com/en-us/library/bb756929.aspx
Repair the broken MSI by using this method:
fix the problem in the old MSI
create a BAT or EXE bootstrapper which recaches it through this command:
msiexec /fv <path_to_msi>
distribute this MSI as an update before your new package
When your new package runs RemoveExistingProducts, the old cached MSI should be fixed and it should uninstall correctly.