Wix Custom Actions - Reading Parameters from an XML File

How to write a Wix installer that imports parameter values ​​from an XML file for use during installation?

+6
source share
2 answers

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 a new project and select the installation project for the xml-installation of Windows Installer
  • Add a new project and select a Windows Xml C # installer custom action project
  • In your installation project:

    • Add something to install, for example. files \ website, etc. (see other guides on how to do this)
    • Set some properties in Product.wxs, for example.

      <Property Id="MyProperty1" /> <Property Id="MyProperty2" /> 
    • Map the newly created custom actions (below) in Product.wxs:

       <Product> ..... <Binary Id='VantageInstallerCustomActions.CA.dll' src='..\VantageInstallerCustomActions\bin\$(var.Configuration)\VantageInstallerCustomActions.CA.dll' /> <InstallExecuteSequence> <Custom Action="SetInstallerProperties" Before="CostFinalize" /> </InstallExecuteSequence> </Product> <Fragment> <CustomAction Id='SetInstallerProperties' BinaryKey='VantageInstallerCustomActions.CA.dll' DllEntry='SetInstallerProperties' Return='check' Execute='immediate' /> </Fragment> 
  • Add the following code to your custom action project or something similar:

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()); //Set the Wix Properties in the Session object from the XML file foreach (var parameter in parameters) { session[parameter.Key] = parameter.Value; } } else { session.Log("No Parameters loaded"); } } catch (Exception ex) { session.Log("ERROR in custom action SetInstallerProperties {0}", ex.ToString()); return ActionResult.Failure; } session.Log("End SetInstallerProperties"); return ActionResult.Success; } } 

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

+6
source

One solution is to use the "MSI Community Extensions"

The user action you are following is probably Xml_SelectNodeValue (there is an example of how to use it).

+2
source

Source: https://habr.com/ru/post/969693/


All Articles