One file per component or several files per component? - wix

Should I wrap all the files I want to install in individual components?
What is the advantage of putting several files in one component?

One reason for "one file per component" is resiliency. When an application is started, Windows Installer can check whether the keypath of any component is missing. If the keypath is missing, the component is reinstalled/repaired.
If a component has multiple files, then only one file can be the keypath. In wix you indicate this by setting KeyPath=yes on a File element. The other files will then not be fully protected by Windows Installer resiliency. They will only be reinstalled if the keypath file goes missing.
Another reason to have "one file per component" is when installing files to locations where they may already be present (e.g. an application upgrade, or when installing to c:\windows\system32). Windows installer determines whether a component needs to be installed by checking the keypath. If the keypath is a file and the file is already there (with the same version or higher) then the component is not installed. That's a problem if the other files in the component actually needed to be installed/upgraded.

I follow the Microsoft approach which is also used by InstallShield: http://msdn.microsoft.com/en-us/library/aa368269(VS.85).aspx
The above link gives the advantages of this approach.
The relevant part is:
Define a new component for every .exe, .dll, and .ocx file. Designate these files as the key path files of their components.

Related

Proper way to register COM server already present on mapped drive

I'm developing a basic MSI installer with installshield 2015, and am trying to understand if there is a proper way, from an installer running on system A, to register an out-of-proc COM server installed on system B (over a network mapped drive) without actually including or delivering the executable file for that COM server. Normally I would use the command to extract COM registration info, but I think this relies on the same component including the file being registered because it uses MSI tables that don't include some information only available in the file table, I think. Is it proper to just manually convert the result of this into registry entries and remove the rows from the Class table and other COM tables?
I followed these steps:
Add a component and add the file to be registered to the component
Set the file as the key file
Extract the COM data for the key file
Clear the key file
Delete the file from the component
Ensure the component's path gets set to the location where the file resides
Temporarily register the component on the machine
Export the ProgID and CLSID registry keys for that component
Delete the registry keys and values from the exported file that are already present in the install project's registry settings for the component
Import the reg files into the install project
Delete the "COM Registration" values and AppID records for the component, leaving only the direct registry updates associated with the component.
Change the LocalServer32 or InprocServer32 value from a hard-coded path and filename to "[$componentname]filename" including quotes

How to use WIX CopyFile element to copy file on change/repair to a system folder without installing it to the target?

I have a problem which is related to the execution of CopyFile on change/repair when using WIX to make a msi setup.
I have a feature which has a component which copies/moves a file from the source folder to a folder already present somwhere inside a users system. It is not the folder of my application. I am only moving this file and not installing it to the the target. This feature works fine if I install it using a complete setup. But when on initial install I chose not to install this feature and then try to install it during a " change " all other custom actions/components inside the feature are executed/installed except for the CopyFile component. This is critical to my setup and if it does not get copied my setup will fail.
Just wondering if anyone found a solution to a similar problem or ever came across a similar issue?
The component which contains the CopyFile operation is configured incorrectly. It should have an actual file or registry entry as a key path.
Although Windows Installer uses components to manage resources, the component key path is main factor which decides if the component is installed or not.
So a component without a resource as a key path will never be installed and the CopyFile operation it contains will never be executed.

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.

In WiX, how would you create a dialog to choose the name of a subfolder of the main application directory?

I am developing an MSI installer by using WiX.
The main program installs to [APPLICATIONFOLDER]. I use the InstallDirDlg to set the directory of this without any issues.
I'd like to display a custom dialogue based on the InstallDirDlg to specify a directory to install a particular component. I'd like to set the default directory to [APPLICATIONFOLDER]\Resources. However when I run the installer, I get an error, code 2343.
I think this may be a problem with displaying a second level folder in the dialogue.
You could take a look at how this is done in the WixUI FeatureTree UI example. In particular, look at the CustomizeDlg.
The error 2343 means "Specified path is empty.", so you have probably set a property incorrectly. Looking at the log files generated by your installer may also help.

Using WiX, how to install single file to (potentially) multiple sub-directories, based on what is available at install time?

I'm using WiX, and would like to know the .wxs necessary to take a file and install it to every available sub-directory of a particular location. This could mean 0 or more final installation locations, determined at install time based on the currently existing directory structure. For example, if I started the install with:
\target
\subdir-1
\subdir-2
Then at the end of the installation my file would be in \subdir-1 and \subdir-2. If on the other hand these directories did not exist on the system when the install was started, my file would not be installed at all and no sub directories would be created.
Afaik this is not possible with WiX (because it is basically against the nature of MSI to install a component into several locations).
You could either
create a different component for each subfolder, or
use a custom action to copy the component to all subfolders.
In the latter case you should also provide a corresponding CA for uninstallation which removes all the files from the subfolders again.
EDIT: Seems my above answer is not totally correct. MSI supports duplicating files using the DuplicateFile tables and WiX 3.0 also provides a mechanism called "smart cabbing". Both are mentioned in a blog post by Aaron Stebner.
Not without a custom action, you need to write a custom action that will do that.
The latest and greatest in custom actions is the DTF (and here) framework that comes with Wix3.
If you are targeting Vista (or Win2k8, not sure about Win2k3), you can use mklink.