Is there a tool to generate WiX XML given a .reg file?
In 2.0, you were supposed to be able to run tallow to generate registry XML:
tallow -r my.reg
For what it's worth, the version of tallow I have is producing empty XML.
In 3.0, tallow has been replaced with heat, but I can't figure out how to get it to produce output from a .reg file.
Is there a way to do this in 3.0?
From Wix 4.0
C:\Program Files (x86)\WiX Toolset v4.0\bin>heat /? | find /i "reg"
reg harvest a .reg file
-sreg suppress registry harvesting
To use, where regfile.reg is the registry input file and fragment.xml is the output file to generate.
heat reg regfile.reg -o fragment.xml
I couldn't find a tool, so I made one.
The source code may not be elegant, but it seems to work:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
using System.Text.RegularExpressions;
namespace Reg2Wix
{
class Program
{
static void PrintUsage()
{
Console.WriteLine("reg2wix <input file> <output file>");
}
/// <summary>
/// Parse the hive out of a registry key
/// </summary>
/// <param name="keyWithHive"></param>
/// <param name="hive"></param>
/// <param name="key"></param>
static void ParseKey(string keyWithHive, out string hive, out string key)
{
if (keyWithHive == null)
{
throw new ArgumentNullException("keyWithHive");
}
if (keyWithHive.StartsWith("HKEY_LOCAL_MACHINE\\"))
{
hive = "HKLM";
key = keyWithHive.Substring(19);
}
else if (keyWithHive.StartsWith("HKEY_CLASSES_ROOT\\"))
{
hive = "HKCR";
key = keyWithHive.Substring(18);
}
else if (keyWithHive.StartsWith("HKEY_USERS\\"))
{
hive = "HKU";
key = keyWithHive.Substring(11);
}
else if (keyWithHive.StartsWith("HKEY_CURRENT_USER\\"))
{
hive = "HKCU";
key = keyWithHive.Substring(18);
}
else
{
throw new ArgumentException();
}
}
/// <summary>
/// Write a WiX RegistryValue element for the specified key, name, and value
/// </summary>
/// <param name="writer"></param>
/// <param name="key"></param>
/// <param name="name"></param>
/// <param name="value"></param>
static void WriteRegistryValue(XmlWriter writer, string key, string name, string value)
{
if (writer == null)
{
throw new ArgumentNullException("writer");
}
if (key == null)
{
throw new ArgumentNullException("key");
}
if (value == null)
{
throw new ArgumentNullException("value");
}
string hive;
string keyPart;
ParseKey(key, out hive, out keyPart);
writer.WriteStartElement("RegistryValue");
writer.WriteAttributeString("Root", hive);
writer.WriteAttributeString("Key", keyPart);
if (!String.IsNullOrEmpty(name))
{
writer.WriteAttributeString("Name", name);
}
writer.WriteAttributeString("Value", value);
writer.WriteAttributeString("Type", "string");
writer.WriteAttributeString("Action", "write");
writer.WriteEndElement();
}
/// <summary>
/// Convert a .reg file into an XML document
/// </summary>
/// <param name="inputReader"></param>
/// <param name="xml"></param>
static void RegistryFileToWix(TextReader inputReader, XmlWriter xml)
{
Regex regexKey = new Regex("^\\[([^\\]]+)\\]$");
Regex regexValue = new Regex("^\"([^\"]+)\"=\"([^\"]*)\"$");
Regex regexDefaultValue = new Regex("@=\"([^\"]+)\"$");
string currentKey = null;
string line;
while ((line = inputReader.ReadLine()) != null)
{
line = line.Trim();
Match match = regexKey.Match(line);
if (match.Success)
{
//key track of the current key
currentKey = match.Groups[1].Value;
}
else
{
//if we have a current key
if (currentKey != null)
{
//see if this is an acceptable name=value pair
match = regexValue.Match(line);
if (match.Success)
{
WriteRegistryValue(xml, currentKey, match.Groups[1].Value, match.Groups[2].Value);
}
else
{
//see if this is an acceptable default value (starts with @)
match = regexDefaultValue.Match(line);
if (match.Success)
{
WriteRegistryValue(xml, currentKey, (string)null, match.Groups[1].Value);
}
}
}
}
}
}
/// <summary>
/// Convert a .reg file into a .wsx file
/// </summary>
/// <param name="inputPath"></param>
/// <param name="outputPath"></param>
static void RegistryFileToWix(string inputPath, string outputPath)
{
using (StreamReader reader = new StreamReader(inputPath))
{
using (XmlTextWriter writer = new XmlTextWriter(outputPath, Encoding.UTF8))
{
writer.Formatting = Formatting.Indented;
writer.Indentation = 3;
writer.IndentChar = ' ';
writer.WriteStartDocument();
writer.WriteStartElement("Component");
RegistryFileToWix(reader, writer);
writer.WriteEndElement();
writer.WriteEndDocument();
}
}
}
static void Main(string[] args)
{
if (args.Length != 2)
{
PrintUsage();
return;
}
RegistryFileToWix(args[0], args[1]);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With