This is to share a source code for the the previous installment. The whole project can be downloaded here.
You register the action in a wxs file:
<Binary Id="Tools.Wix.Actions.dll"
SourceFile="..\..\..\Tools\src\Tools.Wix.Actions\bin\Debug\Tools.Wix.Actions.CA.dll" />
<CustomAction Id="Tools.Wix.Actions.SetProperties" BinaryKey="Tools.Wix.Actions.dll"
DllEntry="SetInstallEnvironmentProperties" Execute="immediate" />
And then define when to run it:
<InstallExecuteSequence>
<Custom Action="Tools.Wix.Actions.SetProperties" Before="CostFinalize" />
</InstallExecuteSequence>
Just to repeat it again, in my case I set it as Before CostFinalize, as part of the job was to configure a property for an INSTALLLOCATION directory.
The code itself is very straightforward:
using Microsoft.Deployment.WindowsInstaller;
using System;
using System.Text;
using System.Xml.Serialization;
using System.IO;
namespace Tools.Wix.Actions
{
public class CustomActions
{
[CustomAction]
public static ActionResult SetInstallEnvironmentProperties(Session session)
{
try
{
session.Log("Begin CustomActions.SetInstallEnvironmentProperties");
session["INSTALLLOCATION"] = "C:\\FORIS4\\bbb\\";
string environmentPath = session["ENVIRONMENT"];
session.Log("ENVIRONMENT: " + environmentPath);
InstallEnvironment environment = null;
if (!String.IsNullOrEmpty(environmentPath))
{
try
{
environment = InstallEnvironment.ParseFromFile(environmentPath);
session.Log("Environment values:" +
GetEnvironmentAsStringData(environment).ToString());
if (environment.Configuration == null)
{
return ActionResult.Success;
}
foreach (var entry in environment.Configuration)
{
session[entry.Name] = entry.Value;
}
}
catch (Exception ex)
{
HandleException(session, ex);
return ActionResult.Failure;
}
}
}
catch (Exception ex)
{
HandleException(session, ex);
}
return ActionResult.Success;
}
private static void HandleException(Session session, Exception ex)
{
string errorMsg = "Exception during custom action execution:" + ex.ToString();
session.Log(errorMsg);
session.Message(InstallMessage.Error, new Record { FormatString = errorMsg });
}
private static StringBuilder
GetEnvironmentAsStringData(InstallEnvironment environment)
{
var xs = new XmlSerializer(typeof(InstallEnvironment));
var sb = new StringBuilder();
using (var sw = new StringWriter(sb))
{
xs.Serialize(sw, environment);
}
return sb;
}
}
}
With addition of classes to create an environment property bag:
using System.Collections.Generic;
using System;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization;
namespace Tools.Wix.Actions
{
[Serializable]
public class InstallEnvironment
{
private List<Entry> _configuration = new List<Entry>();
public string Name { get; set; }
public string Description { get; set; }
public List<Entry> Configuration
{
get { return _configuration; }
set { _configuration = value; }
}
public static InstallEnvironment ParseFromFile(string filePath)
{
return DeserializeFromFile(filePath, typeof(InstallEnvironment)) as InstallEnvironment;
}
private static object DeserializeFromFile(string path, Type type)
{
object ctc = null;
if (path != null || path != String.Empty)
{
XmlTextReader reader = null;
try
{
var xs = new XmlSerializer(type);
reader = new XmlTextReader(path);
reader.Normalization = false;
ctc = xs.Deserialize(reader);
// Complete post deserialization work.
var idc = ctc as IDeserializationCallback;
if (idc != null)
{
idc.OnDeserialization(null);
}
}
catch (Exception e)
{
throw new Exception
(
"Exception ocurred while reading type " + type.FullName +
"from the file " + path + "\r\n" + e +
"\r\nType:" + e.GetType().Name,
e
);
}
finally
{
if (reader != null) reader.Close();
}
}
return ctc;
}
}
}
And
using System;
using System.Xml.Serialization;
namespace Tools.Wix.Actions
{
[Serializable]
public class Entry
{
[XmlAttribute]
public string Name { get; set; }
[XmlAttribute]
public string Value { get; set; }
[XmlAttribute]
public string Description { get; set; }
}
}
Here is the sample environment file:
<?xml version="1.0" encoding="utf-16"?>
<InstallEnvironment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Name>Test environment</Name>
<Description>Environment for a test platform</Description>
<Configuration>
<Entry Name="INSTALLLOCATION" Value="c:\test5\bbb\"
Description="Location where to install the application" />
<Entry Name="TESTURL" Value="http://test.com/" Description="Test url" />
</Configuration>
</InstallEnvironment>
Hope someone can find it useful .
Yours, Stan
No comments:
Post a Comment