This is not an ideal solution, but I spent two days working and wanted to share. Sure, there will be some mistakes, but I did everything I could in the time available:
Add CustomAction class:
public class CustomActions { private static readonly InstallerPropertiesFileManager InstallerPropertiesFileManager = new InstallerPropertiesFileManager(); [CustomAction] public static ActionResult SetInstallerProperties(Session session) { session.Log("Begin SetInstallerProperties"); try { var doc = XDocument.Load(@"C:\temp\Parameters.xml"); session.Log("Parameters Loaded:" + (doc.Root != null)); session.Log("Parameter Count:" + doc.Descendants("Parameter").Count()); var parameters = doc.Descendants("Parameter").ToDictionary(n => n.Attribute("Name").Value, v => v.Attribute("Value").Value); if (parameters.Any()) { session.Log("Parameters loaded into Dictionary Count: " + parameters.Count());
Create your file C: \ temp \ Parameters.xml for storage on disk
<?xml version="1.0" encoding="utf-8"?> <Parameters> <Environment ComputerName="Mycomputer" Description="Installation Parameters for Mycomputer" /> <Category Name="WebServices"> <Parameter Name="MyProperty1" Value="http://myserver/webservice" /> <Parameter Name="MyProperty2" Value="myconfigSetting" /> </Category> </Parameters>
NB you do not need to reference the user action project from the installation project. You should also not set properties too late in the installation cycle, which are required at an early stage, for example, those that are file paths for installing files. I try to avoid this.
Use your properties in Product.wxs to do something! for example I use the restored property to update the web service endpoint in the installed web.config
<Fragment> <DirectoryRef Id ="INSTALLFOLDER"> <Component Id="WebConfig" Guid="36768416-7661-4805-8D8D-E7329F4F3AB7"> <CreateFolder /> <util:XmlFile Id="WebServiceEnpointUrl" Action="setValue" ElementPath="//configuration/system.serviceModel/client/endpoint[\[]@contract='UserService.V1_0.GetUser.ClientProxy.Raw.IGetUserService'[\]]/@address" Value="[MyProperty1]" File="[INSTALLFOLDER]web.config" SelectionLanguage="XPath" /> </Component> </DirectoryRef> </Fragment>
As always with Wix installers, nothing works for the first time. Restore your Wix SetupProject and run msi locally with the following command line to enable logon:
msiexec /i "myInstaller.msi" /l*v "log.log"
After starting, open the log file and you will see the following events:
MSI (s) (C4:3C) [11:00:11:655]: Doing action: SetInstallerProperties Action start 11:00:11: SetInstallerProperties. MSI (s) (C4:A8) [11:00:11:702]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSICD83.tmp, Entrypoint: SetInstallerProperties MSI (s) (C4:A8) [11:00:11:702]: Generating random cookie. MSI (s) (C4:A8) [11:00:11:702]: Created Custom Action Server with PID 496 (0x1F0). MSI (s) (C4:CC) [11:00:11:733]: Running as a service. MSI (s) (C4:CC) [11:00:11:733]: Hello, I'm your 32bit Impersonated custom action server. SFXCA: Extracting custom action to temporary directory: C:\Users\ak9763\AppData\Local\Temp\MSICD83.tmp-\ SFXCA: Binding to CLR version v4.0.30319 Calling custom action VantageInstallerCustomActions!VantageInstallerCustomActions.CustomActions.SetInstallerProperties Begin SetInstallerProperties Parameters loaded into Dictionary: 2 MSI (s) (C4!C0) [11:00:11:858]: PROPERTY CHANGE: Adding MyProperty1 property. Its value is 'http://myserver/webservice'. MSI (s) (C4!C0) [11:00:11:858]: PROPERTY CHANGE: Adding MyProperty2 property. Its value is 'myConfigSetting'. End SetInstallerProperties Action ended 11:00:11: SetInstallerProperties. Return value 1.
Links for this publication:
Creating custom WiX actions in C # and transfer options
From MSI to WiX, Part 5 - User Actions: Introduction
Create an MSI Log File