Create file in installation folder using WiX custom action - wix

I try to create a wix installer that has the need to create a file in the programme folder after Installation. For doing so, I have created a custom action, but I now have the following problem:
In order to write the file, I need to know the installation directory from session["INSTALLDIR"], which is only available if the action is executed "immediate".
However, if i run "immediate" after "install files", the target directory does not yet exist. If I run "deferred", it exists, but i cannot access session["INSTALLDIR"].
If I run "immediate" after "InstallFinalize", I can get the variable and the directory exists, but I am not elevated and hence not allowed to write the file.
What is the correct combination for writing a file to the installation directory?

You need to use CustomActionData to access property values from a deferred CA. You need something like this
or
another answer

Beyond using a built in extension for custom actions instead of writing your own, the next level would be how can I move complexity / custom actions out of the installer?
One thought is to write it to the registry instead. Another thought is for the application reading the value to be able to determine installation directory on it's own. One possibility is reflection to get the location another possibility is to query the MSI API for where the product is installed.

Related

Windows temporary files directory is not accessable

I'm creating installer using wix, and in my deferred custom action File.Exists return false on existing temporary file. How can I make C:\Users\<me>\AppData\Local\Temp visible for my custom action?
You should show the actual code. It might work fine in code run from the interactive user's desktop, but it's being called from an msiexec process running impersonated (or with the system account) from the system folder, and you don't even say if it's a Dll call or an executable.
However, the issue is that you can't just look in that folder from a custom action. If you are running deferred with the system account and looking at Environment.SpecialFolder to get the user's temp folder you'll get the system account's temp folder. If you run with impersonation you still won't get the right location because impersonation does not load up the entire user profile that would give you access to user profile locations like the user's temp folder.
Without knowing exactly what you're trying to do this may not help, but WiX and Windows Installer have searches which will do exactly what you want. Just do a file search for that file in TempFolder, which is the property name location you need. You need this kind of thing searching TempFolder, ignoring the version checks:
http://wixtoolset.org/documentation/manual/v3/howtos/files_and_registry/check_the_version_number.html

How to limit UI installation paths in WIX?

I am writing an installation script using WIX and have a question that arises in regards to the user selected location for installation. The program that needs to be installed needs to be installed at the root drive C:/, D:/, ext for the program to work. Using the Wix UI package WIXUI_INSTALLDIR the user can change the path that the program is installed too what I want to do is to make it impossible for the user to change anything except the root drive ie change D:\usr\sparrow\bin ---> C:\usr\sparrow bin if they so desired. Does anyone have any suggestions about how this might be accomplished?
You can do this with a custom action and a custom dialog, but I wouldn't do this. It is a lot of work, and doesn't seem to have any major benefits.
If I were you I would remove the chance to install to a custom location altogether. However, if the setup is run by command line, you won't be able to control what path they specify for TARGETDIR / INSTALLDIR anyway, unless you add a custom action check to abort the setup if the path is not to be allowed:
msiexec /i setup.msi TARGETDIR=c:\anypathcanbewrittenhere

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.