Skip to content

Commit

Permalink
- Issue #137: Add custom attribute to Bundle project (Bootstrapper)
Browse files Browse the repository at this point in the history
    - Added support for XML namespace prefix in 'AttributesDefinition`
    `AttributesDefinition = "{dep}ProviderKey = 01234567-8901-2345-6789-012345678901"`
  • Loading branch information
oleg-shilo committed Aug 28, 2017
1 parent 7b04d95 commit 88ae6e9
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 27 deletions.
35 changes: 35 additions & 0 deletions Source/src/WixSharp.Samples/Support/testpad/setup.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,49 @@
//css_ref ..\..\WixSharp.dll;
//css_ref System.Core.dll;
using System;
using System.Collections.Generic;
using System.Linq;
using WixSharp;
using WixSharp.CommonTasks;
using WixSharp.Forms;

// Truly a throw away project for dev testing

class Script
{
static void prepare_dirs(string root)
{
for (int i = 0; i < 40; i++)
{
var dir = root.PathJoin(i.ToString());
System.IO.Directory.CreateDirectory(dir);
System.IO.File.WriteAllText(dir.PathJoin($"file_{i}.txt"), i.ToString());
}
}

static public void Main(string[] args)
{
// prepare_dirs("dirs"); return;

// var project = new ManagedProject("MyProduct",
// new Dir(@"C:\MyCompany2", new File("setup.cs")),
// new Dir(@"C:\MyCompany\MyProduct",
// new Files(@"dirs\*.*")));

var dirs = System.IO.Directory.GetFiles("dirs", "*", System.IO.SearchOption.AllDirectories)
.Select(x => x.PathGetFullPath())
.Select(x => new Dir(x.PathGetDirName(),
new File(x)))
.ToArray();
var project = new ManagedProject("MyProduct", dirs);

project.UI = WUI.WixUI_ProgressOnly;

Compiler.PreserveTempFiles = true;
Compiler.BuildMsi(project);
}

static public void Main1(string[] args)
{
var application = new Feature("Application") { Name = "Application", Description = "Application" };
var drivers = new Feature("Drivers") { Name = "Drivers", Description = "Drivers", AttributesDefinition = $"Display = {FeatureDisplay.expand}" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static public void Build()

static public void BuildWithAttributes()
{
//this sample is inly useful for the demonstration of how to work with AttributesDefinition and XML jnjection
//this sample is inly useful for the demonstration of how to work with AttributesDefinition and XML injection

var project =
new Project("MyProduct",
Expand Down
Binary file modified Source/src/WixSharp.Samples/WixSharp.UI.dll
Binary file not shown.
Binary file modified Source/src/WixSharp.Samples/WixSharp.dll
Binary file not shown.
16 changes: 9 additions & 7 deletions Source/src/WixSharp.Samples/WixSharp.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4166,6 +4166,8 @@
<member name="M:WixSharp.Extensions.SetAttribute(System.Xml.Linq.XElement,System.String,System.Object)">
<summary>
Sets the value of the attribute. This is a fluent version of XElement.SetAttributeValue.
<para><c>name</c> can include xml namespace prefix (e.g. element.SetAttribute("{dep}ProviderKey", "01234567-8901-2345-6789-012345678901")).
Though in this case the required namespace must be already added to the element/document.</para>
</summary>
<param name="obj">The object.</param>
<param name="name">The name.</param>
Expand Down Expand Up @@ -4552,12 +4554,12 @@
<returns></returns>
</member>
<member name="M:WixSharp.Extensions.PathJoin(System.String,System.String[])">
<summary>

</summary>
<param name="path"></param>
<param name="items"></param>
<returns></returns>
<summary>
Equivalent of <see cref="M:System.IO.Path.Combine(System.String,System.String)"/>.
</summary>
<param name="path"></param>
<param name="items"></param>
<returns></returns>
</member>
<member name="M:WixSharp.Extensions.PathGetDirName(System.String)">
<summary>
Expand Down Expand Up @@ -10054,7 +10056,7 @@
</member>
<member name="F:WixSharp.Project.RebootSupressing">
<summary>
Provideds fine control over rebooting at the end of installation.
Provides fine control over rebooting at the end of installation.
<para>If set it creates MSI <c>REBOOT</c> property with the user specified value <see cref="F:WixSharp.Project.RebootSupressing"/>.</para>
</summary>
<example>
Expand Down
15 changes: 12 additions & 3 deletions Source/src/WixSharp/AutoElements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,9 @@ static void ExpandCustomAttributes(XDocument doc, Project project)
static bool DefaultExpandCustomAttribute(XElement source, string item, Project project)
{
var attrParts = item.Split('=');
// {dep}ProductKey=12345 vs Component:{dep}ProductKey=12345
if (item.StartsWith("{"))
item = ":" + item;
var keyParts = attrParts.First().Split(':');

string element = keyParts.First();
Expand All @@ -402,7 +405,7 @@ static bool DefaultExpandCustomAttribute(XElement source, string item, Project p
XElement destElement = source.Parent("Component");
if (destElement != null)
{
destElement.SetAttributeValue(key, value);
destElement.SetAttribute(key, value);
return true;
}
}
Expand All @@ -411,7 +414,7 @@ static bool DefaultExpandCustomAttribute(XElement source, string item, Project p
{
source.Parent("Product")
.SelectOrCreate("Icon")
.SetAttributeValue(key, value);
.SetAttribute(key, value);
return true;
}

Expand All @@ -421,11 +424,17 @@ static bool DefaultExpandCustomAttribute(XElement source, string item, Project p
var elements = source.Document.Descendants("Custom").Where(e => e.Attribute("Action").Value == id);
if (elements.Any())
{
elements.ForEach(e => e.SetAttributeValue(key, value));
elements.ForEach(e => e.SetAttribute(key, value));
return true;
}
}

if (key.StartsWith("{"))
{
source.SetAttribute(key, value);
return true;
}

if (key.StartsWith("xml_include"))
{
var parts = value.Split('|');
Expand Down
6 changes: 0 additions & 6 deletions Source/src/WixSharp/Dir.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,6 @@ internal get

bool isInstallDir;

///// <summary>
///// Defines the launch <see cref="Condition"/>, which is to be checked during the installation to
///// determine if the directory should be installed.
///// </summary>
//public Condition Condition;

/// <summary>
/// Returns the WiX <c>Directory</c> as a string.
/// </summary>
Expand Down
38 changes: 29 additions & 9 deletions Source/src/WixSharp/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,30 +263,48 @@ internal static XElement SetAttributeFromFieldsOf(this XElement obj, object src)

/// <summary>
/// Sets the value of the attribute. This is a fluent version of XElement.SetAttributeValue.
/// <para>Note <c>name</c> can include xml namespace prefix:
/// <code>
/// element.SetAttribute("{dep}ProviderKey", "01234567-8901-2345-6789-012345678901");
/// </code>
/// Though in this case the required namespace must be already added to the element/document.</para>
/// </summary>
/// <param name="obj">The object.</param>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <returns></returns>
public static XElement SetAttribute(this XElement obj, string name, object value)
{
XName x_name = name;

if (name.StartsWith("{"))
{
var tokens = name.Substring(1).Split(new[] { '}' }, 2);
var xml_namespace = tokens.First();
var prefix = obj.GetNamespaceOfPrefix(xml_namespace);
if (prefix == null)
throw new Exception($"Cannot find XML namespace prefix '{xml_namespace}'");

x_name = obj.GetNamespaceOfPrefix(xml_namespace) + tokens.Last();
}

if (value is string && (value as string).IsEmpty())
{
obj.SetAttributeValue(name, null);
obj.SetAttributeValue(x_name, null);
}
else if (value is bool?)
{
var attrValue = (bool?)value;
obj.SetAttributeValue(name, attrValue.ToNullOrYesNo());
obj.SetAttributeValue(x_name, attrValue.ToNullOrYesNo());
}
else if (value is bool)
{
var attrValue = (bool)value;
obj.SetAttributeValue(name, attrValue.ToYesNo());
obj.SetAttributeValue(x_name, attrValue.ToYesNo());
}
else
{
obj.SetAttributeValue(name, value);
obj.SetAttributeValue(x_name, value);
}
return obj;
}
Expand Down Expand Up @@ -332,14 +350,16 @@ public static XElement AddAttributes(this XElement obj, Dictionary<string, strin
{
if (attributes.Any())
{
var optimizedAttributes = attributes.Where(x => !x.Key.Contains(":")).ToDictionary(t => t.Key, t => t.Value);
var optimizedAttributes = attributes.Where(x => !x.Key.Contains(":") && !x.Key.Contains(":{") && !x.Key.StartsWith("{"));

var optimizedAttributesMap = optimizedAttributes.ToDictionary(t => t.Key, t => t.Value);

var compositValues = string.Join(";", attributes.Where(x => x.Key.Contains(":")).Select(x => x.Key + "=" + x.Value).ToArray());
var compositValues = string.Join(";", attributes.Except(optimizedAttributes).Select(x => x.Key + "=" + x.Value).ToArray());
if (compositValues.IsNotEmpty())
optimizedAttributes.Add("WixSharpCustomAttributes", compositValues);
optimizedAttributesMap.Add("WixSharpCustomAttributes", compositValues);

foreach (var key in optimizedAttributes.Keys)
obj.SetAttributeValue(key, optimizedAttributes[key]);
foreach (var key in optimizedAttributesMap.Keys)
obj.SetAttributeValue(key, optimizedAttributesMap[key]);
}
return obj;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/src/WixSharp/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ public Guid? GUID
public ForceReboot ForceReboot;

/// <summary>
/// Provideds fine control over rebooting at the end of installation.
/// Provides fine control over rebooting at the end of installation.
/// <para>If set it creates MSI <c>REBOOT</c> property with the user specified value <see cref="RebootSupressing"/>.</para>
/// </summary>
/// <example>
Expand Down
10 changes: 10 additions & 0 deletions Source/src/WixSharp/WixEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ public class WixObject
/// The code above will force the Wix# compiler to insert "SharedDllRefCount" attribute into <c>Component</c>
/// XML element, which is automatically generated for the <see cref="T:WixSharp.File"/>.
/// <para>Currently the only supported "related" attribute is <c>Component</c>.</para>
/// <para>Note the attribute key can include xml namespace prefix:
/// <code>
/// { "{dep}ProviderKey", "01234567-8901-2345-6789-012345678901" }
/// </code>
/// Though in this case the required namespace must be already added to the element/document.</para>
/// </remarks>
/// </para>
/// </summary>
Expand All @@ -80,6 +85,11 @@ public Dictionary<string, string> Attributes
/// Optional attributes of the <c>WiX Element</c> (e.g. Secure:YesNoPath) expressed as a string KeyValue pairs (e.g. "StartOnInstall=Yes; Sequence=1").
/// <para>OptionalAttributes just redirects all access calls to the <see cref="T:WixEntity.Attributes"/> member.</para>
/// <para>You can also use <see cref="T:WixEntity.AttributesDefinition"/> to keep the code cleaner.</para>
/// <para>Note <c>name</c> can include xml namespace prefix:
/// <code>
/// AttributesDefinition = "{dep}ProviderKey=01234567-8901-2345-6789-012345678901"
/// </code>
/// Though in this case the required namespace must be already added to the element/document.</para>
/// </summary>
/// <example>
/// <code>
Expand Down

0 comments on commit 88ae6e9

Please sign in to comment.