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]);
}
}
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…