WiX - How do I copy existing files to a subdirectory before installed files of the same name overwrite them? - wix

I have some file at Program\file.json, and I want my .msi to copy the file to Program\Backup\file.json before installing a new file at Program\file.json so that the old data is not lost.
I tried writing a Program\backup.bat which copies Program\file.json to Program\Backup\file.json and calling it with a CustomAction, but this does not work because I need to call the batch file after it is installed into the system's Program folder during InstallFiles so that it can move the old file. However, InstallFiles is also when the new Program\file.json overwrites the old one.
I also tried doing it the WiX way by putting the following tag in another Component within the same Feature as the File tag responsible for the new Program\file.json:
<CopyFile SourceDirectory="ProgramFolder" DestinationDirectory="BackupFolder" Id="Copy_of_File" SourceName="file.json"/>
("ProgramFolder" is the Id of the Program Directory, and "BackupFolder" is the Id of the Program\Backup Directory)
However, this appears to copy the old version into Program\Backup\file.json but not overwrite it with the new version. I'm not sure why.

Related

Wix custom action to unzip a file

I've a zipped file which contains around 1000+ files.
I was able to bundle the zip file into msi.
But I would like to know how to unzip that file using any custom action
We had this requirement to unzip a file and place or the sub directories and files inside it at a particular location after installation.
Solution:
1. Create a exe (console app) that will unzip the file and place required files at required location.
2. Ship this exe with installer
3. Make this exe run (with execute sequence) while the application is installs.
This may add overhead, but this works.

WiX: Copy a file from local folder to installation folder

I'm using a WiX setup project to build an MSI package.
I want the MSI, to do a copy of the given file during the installation to the installation folder from the one, where the .msi file is running from.
I read on WiX a bit, and what I found is the <CopyFile... /> element supposed to do that.
Appreciate your help.
Actually I've figured out what the issue is.
The problem is that the SourceDirectory of the CopyFile element supposed to point to the Directory tag id.
Instead, I've used SourceProperty attribute of the CopyFlie tag, and also defined a Property separately, which made the use of the CopyFile element correct.
So it worked.

Creating a WiX patch from single file location

I am trying to create a patch for my application. Implementing the example described here worked as expected. However, the files for each version are stored in separate directories. Version 1.0 files are in c:sample\1.0 and 1.1 files are in c:sample\1.1. If I move the files to a single location, create the 1.0 installer, modify the files, and create the 1.1 installer; wixmst output of torch contains no differences. When I run pyro I get:
warning PYRO1079 : The cabinet 'media1.cab' does not contain any files. If this patch contains no files, this warning can likely be safely ignored. Otherwise, try passing -p to torch.exe when first building the transforms, or add a ComponentRef to your PatchFamily authoring to pull changed files into the cabinet.
This is a problem for me because the files for my project are kept in a single git repository. We use branching and tagging to delineate versions. Because of this I only have one directory of files.
I have the .msi and .wixpdb for both versions.
How can I create my patch in this situation?
Pyro requires access to the .wixmst and the old and new files. If you only have one set of files (newer or older) then the patch will obviously find no file differences. That is why you are getting the error from Pyro.
If you use bindpaths to create the original .msi files (and their .wixpdbs) then you can provide the old paths using the -bt switch to pyro and the new paths to the -bu switch. If you didn't use bindpaths and you need to recreate the old directory structure for the old files and create a new directory structure for the new files.
If you can't get the old and new files to be found (bindpaths work best) then you'll have to do admin image type patching.

Open txt file in wix when clicking btn

I have a wix project to which I added a custom window that checks the dependencies needed to run the app. This window comes up right after the License Agreement. Everything works fine, the dependencies are checked through custom actions and in case they are not fulfilled hyperlinks to official websites appear if the windows installer is above version5.
In case of a lower version I would like to click on a btn "Show dependencies" and to show the txt file with the links. I have the custom action below that open notepad and the property that contains the file.
Code:
<Property Id="FXDEP" Value="$(sys.CURRENTDIR)\Resources\Files\FxDependencies.txt" />
<Property Id='NOTEPAD'>NOTEPAD.EXE</Property>
<CustomAction Id='LaunchDependencies' Property='NOTEPAD' ExeCommand='[FXDEP]' Return='asyncNoWait' />
The problem is that on the dev machine it works since it finds the path, but on other of course it fails.
How should I tell wix to maintain this file and open it?
I tried putting the file into
<Binary Id="FxDependencies.txt" SourceFile="$(sys.CURRENTDIR)\Resources\Files\FxDependencies.txt" />
but the custom action does not recognize it.
You seem to be trying to open the file that resides in the source of your installation. You use the same values for FxDependencies.txt and FXDEP.
Your text file with dependencies resides in Binary table of the installer, to use it you have to extract it into a temporary directory, and then launch Notepad to display it.
To do it, you would have to write several custom actions:
The first CA extract the file into a temporary directory, and saves the path into a property, FXDEPTEMPPATH.
The second CA uses FXDEPTEMPPATH to display it in Notepad.
Another option is to write a small application (.exe) that would contain your FxDependencies.txt, in resources for example. You add this .exe into Binary table of MSI, and launch it instead of Notepad from the installer. In this case MSI will automatically extract the exe into a temporary directory and start it. In your application you create a new text file in temporary directory, by extracting the information from resources, and then launch Notepad to display it.
Edit: There's a number of ways to read a file from the Binary table. See these links for examples:
BinaryWrite from Msiext.
Reading from the Binary Table based on WiX source code.
Streaming a File from the Binary Table.
Write the code yourself:
Open a database view of the active database with MsiGetActiveDatabase and MsiDatabaseOpenView;
Read the binary stream with MsiRecordReadStream.
I would suggest you to create folder in custom action.
So,
Validate pre-requisites
Check windows installer version
If version is less than 5, call a custom action to create folder ($(sys.CURRENTDIR)\Resources\Files\)
Then on button click you can call the custom action to launch txt file

how to copy a file and then conditionally remove it

(I'm newbe in Installer world so I'm still not sure what is right what is wrong. Anyway.)
I make a installer for service which uses desktop database. The database file should somehow be copied during first installation, be intact during upgrades and finally removed during uninstall.
As far I know, I can't add the database file as a directory component - 'cause installer will automatically remove it during uninstall. On the other hand, if I set the Persistent attribute, the database file will be NEVER removed by installer (even, if I will create separate component with RemoveFile element).
The above leads me to thinking, that I can't add the database file as directory's component.
So what are other options?
Is it possible to include a file into installer file (msi) and then copy the file with custom action to target folder?
Then deletion could be solved with RemoveFile element and condition base on UPGRADINGPRODUCTCODE property.
What do you think, guys?
If you are going to be using a custom action, why not create a custom action the will remove the file on uninstall. I have a custom action like that in a couple of my installers due to updates that happen to the target folder after the program has been running for a while. this just ensures a clean uninstall with no files laying around.