How can you _create_ a text file in Wix? - wix

Is there any way to create a new text file and write to it using Wix? I have come across elements that will allow me to work with Xml files and Ini files, but nothing for a plain text file.
The root of the problem stems from the fact that we're using a third party library that reads from its own custom configuration file, which really ties my hands as to what the text file can look like. The configuration file is similar to an Ini file, minus the "sections." And I've noticed that Wix handles Ini files by always placing them in the system folder, which won't work for our needs.
The data that needs to be written to the configuration file is gathered at run-time, so there's no opportunity to simply lay down a pre-configured file.
I would be willing to accept a Wix extension to accomplish the same result if one exists, but haven't come across one yet.

There is no built-in feature in Windows Installer for this. You'll have to write code to do it and invoke that code with a custom action.

The IniFile element can write .ini files anywhere; use the #Directory attribute to specify which directory it should go in. If the library ignores [section] lines, you can use anything as the #Section attribute value.

You might want to have a look at this project. It contains the collection of WiX extensions and custom actions, and I suppose it also has CA to read and write text files. Try it out - it is claimed to be tested and proved by using in enterprise installations.

Related

How to check if ini file exists with Wix Toolset

I have an .ini file with configuration. I need to check if it exists in new installation to avoid creating it again. Besides if the new .ini have new fields add to the existing file.
Don't install an ini file as a file, but convert the entries into IniFile Table entries. This allows all ini file changes to be treated as "atomic change units" that allows proper merging and rollback via built-in MSI mechanism. You avoid all custom action complexity.
As Chris points out in his major upgrade comment: do things the right way in Wix / MSI and you avoid a lot of problems that start to pop up when requirements change or updates get complicated. IniFile updates implemented the right way are robust and simple to deal with.
In Wix you use the IniFile Element to achieve this. All merge capabilities, rollback support and advanced ini file handling comes along for free. All you need to do is to define what needs to be added or modified in the ini file during your installation. It will also be created if it is not there in the first place.
Using the IniFile element may look harder than it is. Here is a sample. You can also have a look at the well known Wix tutorial here.
All MSI-experts keep repeating this advice: never use a custom action to change a system if there are equivalent built-in MSI constructs.
Set NeverOverwrite="yes" on the .ini file's component and then handle the update via a custom action.
Edit: Generally it is much better to use the IniFile table as explained in my answer since you get rollback and merge capabilities. However, some people prefer the INI file installed as a file to allow easy modification of the file from outside the MSI file. Though not preferred, this does allow people to "hotfix" the INI file directly on the installation media location. Teams can use this to have the installer pick up the latest INI from development. There are technical problems with this that can be handled via a custom action (most significantly file replacement issues on install). It is also possible that an INI file can feature non-standard elements and formatting that doesn't fit in the IniFile table (rare, but possible - people with sense then use a different file extension than ini). As already explained, I would strongly advice against updating INI files via your own custom action, unless you are doing something very special - that's actually needed. It is complicated to implement and to get right.
I would suggest having 2 INI files. One that the installer owns and one that the application / user owns. The installer can always overwrite it's INI file and never worry about stomping on user data.

Wix generate single component id for entire tree

I am someone with little to no experience with wix and I am trying to support Windows also for the component I am responsible for. I am trying to create merge module for a set of files that my product generates. These files exist in numerous sub directories. I was wondering how I can create a single component ID for all the files in the entire tree. I am not worried about minor upgrades as that is something I am not going to be doing. I am trying to avoid generating numerous GUIDs for each of the file.
Also is there any way I can change the name of the root directory I want the files to be installed. Currently, in our build system the files I want to install end up in a directory name "install". In the wxs file generated by heat it comes up as install. I was wondering if I could change it to the actual product name instead of "install".
Use one file per component - this avoids all sorts of problems (except .NET assemblies spanning multiple files). See the following thread: One file per component or several files per component?
Wix is a great framework for creating installers, but it has a steep learning curve. I strongly recommend you read a few sections of this great, online tutorial: https://www.firegiant.com/wix/tutorial/
If you are a "sample based tinkerer", you can find an even quicker, sample based tour in this article: http://www.codeproject.com/Tips/105638/A-quick-introduction-Create-an-MSI-installer-with
Wix is hands-on. Just focus on the samples, and focus on getting the components created and a major upgrade set up:
How to implement WiX installer upgrade? (modern, convenience way)
How to get WiX major upgrade working? (legacy way - more flexible, less convenient)
http://wixtoolset.org/documentation/manual/v3/howtos/updates/major_upgrade.html
Once you got that running the rest of the details fall into place by reading the documentation for whatever feature you need. Using Visual Studio / Votive with intellisense ensures that you can learn as you go with features such as shortcuts, ini files, xml files, dialogs, etc...
Another top tip is to use dark.exe (part of the Wix toolkit) to decompile existing MSI files. This yields Wix XML with code you can copy and paste into your own Wix files. I use other MSI tools to compile such MSI files, and then copy the sections I need into my Wix file - just to speed up the process of creating the Wix XML. Studying the decompiled XML is very educational - a real time saver.
UPDATE, May 2021: Some more links:
WiX Quick Start - Very long version
WiX Quick Start - Short version
If all the files are going to the same destination folder, then you can create one single COMPONENT with all the FILE within it. There is nothing stopping you to do that. You can then just create one GUID for that component. Also read these answers which talks about the advantages vs disadvantages of one component vs multiple components before you implement it: Answer1 Answer2. To Summarize:
You will have trouble with minor upgrades/repairs. If a component is
being updated, only the file designated as the KEYPATH is checked to see if
it is out of date: if it is up to date, all the others are ignored.
You'll also have difficulty if you want to add or remove files from each
component. Once released, a component is immutable (in terms of what files
are in it). The only way to update it without breaking component rules would
be to effectively remove and install the a new version of the MSI.
Understanding the component rules is key in Windows Installer and one file
per component makes the component rules easier to work with, which is why it
is the recommendation of many people here.
LINK
The root directory name can be changed by modifying the "Name" property for the DIRECTORY element.

Use directory from main setup in merge module

I need to install the content of a merge module to a special (sub) folder set in the main setup.
Currently all our setups contain a directory with a special name (ex. "PROGDIR") and we use InstallShield's Direct Editor so give the directory in the merge module the same name.
During merging the directory in the merge module gets overwritten/discarded (call it magic, call it a hack, it's ugly ...).
This solution is quite fragile, as whenever you touch the merge module in InstallShield and fiddle with components or use the "Files and Folders" tab, IS appends the merge module guid to the directory identifier and it all stops working (PROGDIR -> PROGDIR.1234ABC...)
I now want to move our merge modules step by step to WiX. The main setups can not yet follow and must not need to change.
Can I prevent WiX from automatically adding a guid to the directory identifier to use the same hack as before?
Or is there a better, cleaner solution without changing the main setups?
I have looked into the Substitution element, but can not wrap my head around how this would work. If this could help somehow I would appreciate an example ...

Implement a self extracting archive?

I know i can use 7z or winrar but i want to learn this for myself.
How would i implement a self extracting archive? I can use C# or C++ but let me run down the problem.
When i open the exe i need some kind of GUI asking where to extract the files. Once the user says ok I should obviously extract them. I implemented a simple example in C# winforms already BUT my problem is HOW do i get the filenames and binary of the files into an exe?
One upon a time i ask Is it safe to add extra data to end of exe? and the answer suggested if i just add data to the end of the exe it may be picked up by a virus scanner. Now its pretty easy to write the length of the archive as the last 4bytes and just append the data to my generic exe and i do believe my process can read my own exe so this could work. But it feels hacky and i rather not have people accuse me of writing virus just because i am using this technique. Whats the proper way to implement this?
Note: I checked the self-extracting tag and many of the question is how to manipulate self extracting and not how to implement. Except this one which is asking something else Self-extracting self-checking executable
-edit- I made two self extracting with 7z and compared them. It looks like... well it IS the 7z.sfx file but with a regular 7z archive appended. So... there is nothing wrong with doing this? Is there a better way? I'm targeting windows and can use the C# compiler to help but i don't know how much extra work or how difficult it may be programmatically and maybe adding data to end of exe isnt bad?
It is possible. I used the following technique once, when we needed to distribute updates for the application, but the computers were configured so that the end user had no permissions to change application files. The update was supposed to log on to administrator account and update required files (so we came across identical problem: how to distribute many files as a single executable).
The solution were file resources in C#. All you need to do is:
Create a resource file in your C# project (file ending with .resx).
Add new resource of type "file". You can easily add existing files as byte[] resources.
In program you can simply extract resource as file:
System.IO.FileStream file = new System.IO.FileStream("C:\\PathToFile",
System.IO.FileMode.OpenOrCreate);
System.IO.BinaryWriter writer = new System.IO.BinaryWriter(file);
writer.Write(UpdateApplication.Data.DataValue, 0, UpdateApplication.Data.DataValue.Length);
(Here UpdateApplication.Data denotes binary resource).
Our solution lacked compression, but I believe this is easily achieved with libraries such as C#ZipLib.
I hope this solution is virus-scanner-safe, as this method creates complete, valid executable file.

How do I do a search and replace on a configuration file using Wix?

Some code I inherited has its "configuration" (if you can call it that) embedded into its PHP and ASP (don't ask) code. Because its not an XML or INI file, I'm having the darnedest time figuring out how to modify these files at install time. If I could, I'd like to do a simple search and replace. I've read elsewhere (WiX Search and Replace on a configuration file) that I should just write a Custom Action. I'd rather avoid it if I could since the code I wish to configure is deprecated and I don't want to create yet another project to support this code.
So is there a way to do this without writing a custom action. If not, is anyone aware of any custom actions that are already built that could help me with this task?
Windows Installer has built-in support for INI files and WiX / InstallShield has extensions for supporting XML files. InstallShield has an additional extension that supports "Text File Changes" with what they call Replacement Sets. ( Find What, Replace With, Match Whole Word Only, Match Case, Replace Once Only ) I don't think it supports RegEx.
So unless you are going to switch to InstallShield you are going to have to write a custom action or refactor the text file to be XML.