作者:jerry613 | 2023-09-03 10:55
是否有工具在给定.reg文件的情况下生成WiX XML?
在2.0中,您应该能够运行tallow来生成注册表XML:
tallow -r my.reg
对于它的价值,我所拥有的牛脂版本正在生成空XML.
在3.0中,牛脂已被热量取代,但我无法弄清楚如何从.reg文件生成输出.
有没有办法在3.0中这样做?
1> Adam Tegen..: 我找不到工具,所以我做了一个.
源代码可能不优雅,但它似乎工作:
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 ");
}
///
/// Parse the hive out of a registry key
///
///
///
///
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();
}
}
///
/// Write a WiX RegistryValue element for the specified key, name, and value
///
///
///
///
///
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();
}
///
/// Convert a .reg file into an XML document
///
///
///
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);
}
}
}
}
}
}
///
/// Convert a .reg file into a .wsx file
///
///
///
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]);
}
}
}
2> 小智..: 以下是生成Wix 3标记的实用程序的源代码(包括二进制,双字和多字符串注册表值):
using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
namespace AbsReg2Wix
{
public class Program
{
#region Constants
private const string NS_URI = "http://schemas.microsoft.com/wix/2006/wi";
private const string RegEditorVersionPattern = @"Windows\sRegistry\sEditor\sVersion\s(?.*)";
private const string RegKeyPattern = @"\[(?[^\\]*)\\(?.*)\]";
private const string RegNameValuePattern = "\\\"(?.*)\\\"=(?\\\"?[^\\\\\\\"]*)(?\\\\?)";
private const RegexOptions DefaultRegexOptions = RegexOptions.Multiline |
RegexOptions.IgnorePatternWhitespace |
RegexOptions.CultureInvariant;
#endregion
#region Methods
///
/// Main applciation entry point
///
/// The args.
private static void Main(string[] args)
{
if (args.Length != 4)
{
PrintUsageInstructions();
return;
}
if (File.Exists(args[1]))
{
ConvertRegistryFileToWix(args[1], args[3]);
Console.WriteLine("Successfully completed conversion.");
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
else
{
Console.WriteLine(@"Input file {0} not found.", args[1]);
}
}
///
/// Prints the usage instructions.
///
private static void PrintUsageInstructions()
{
Console.WriteLine("Syntax: AbsReg2Wix.exe /in /out ");
}
///
/// Convert a .reg file into a .wsx file
///
/// The input path.
/// The output path.
private static void ConvertRegistryFileToWix(string inputPath, string outputPath)
{
try
{
using (var reader = new StreamReader(inputPath))
{
string regEditorVersion = string.Empty;
bool isRegEditorVersionFound = false;
// Initialize Regex
var regEditorVersionRegex = new Regex(RegEditorVersionPattern, DefaultRegexOptions);
var regKeyRegex = new Regex(RegKeyPattern, DefaultRegexOptions);
var regNameValueRegex = new Regex(RegNameValuePattern, DefaultRegexOptions);
// Create xml document for output
var xDoc = new XmlDocument();
xDoc.AppendChild(xDoc.CreateProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""));
xDoc.AppendChild(xDoc.CreateComment(
string.Format(
"{0}Following code was generated by AbsReg2Wix tool.{0}Tool Version: {1}{0}Date: {2}{0}Command Line: {3}\n",
"\n\t", Assembly.GetExecutingAssembly().GetName().Version,
DateTime.Now.ToString("F"),
Environment.CommandLine)));
XmlElement includeElement = xDoc.CreateElement("Include", NS_URI);
XmlElement componentElement = null,
regKeyElement = null,
registryValueElement = null;
bool multiLine = false;
var rawValueBuilder = new StringBuilder();
while (!reader.EndOfStream)
{
string regFileLine = reader.ReadLine().Trim();
if (!isRegEditorVersionFound)
{
var regEditorVersionMatch = regEditorVersionRegex.Match(regFileLine);
if (regEditorVersionMatch.Success)
{
regEditorVersion = regEditorVersionMatch.Groups["RegEditorVersion"].Value;
includeElement.AppendChild(
xDoc.CreateComment("Registry Editor Version: " + regEditorVersion));
isRegEditorVersionFound = true;
}
}
var regKeyMatch = regKeyRegex.Match(regFileLine);
// Registry Key line found
if (regKeyMatch.Success)
{
if (componentElement != null)
{
componentElement.AppendChild(regKeyElement);
includeElement.AppendChild(componentElement);
}
componentElement = xDoc.CreateElement("Component", NS_URI);
var idAttr = xDoc.CreateAttribute("Id");
idAttr.Value = "Comp_" + GetMD5HashForString(regFileLine);
componentElement.Attributes.Append(idAttr);
var guidAttr = xDoc.CreateAttribute("Guid");
guidAttr.Value = Guid.NewGuid().ToString();
componentElement.Attributes.Append(guidAttr);
regKeyElement = xDoc.CreateElement("RegistryKey", NS_URI);
var hiveAttr = xDoc.CreateAttribute("Root");
hiveAttr.Value = GetShortHiveName(regKeyMatch.Groups["RegistryHive"].Value);
regKeyElement.Attributes.Append(hiveAttr);
var keyAttr = xDoc.CreateAttribute("Key");
keyAttr.Value = regKeyMatch.Groups["RegistryKey"].Value;
regKeyElement.Attributes.Append(keyAttr);
var actionAttr = xDoc.CreateAttribute("Action");
actionAttr.Value = "createAndRemoveOnUninstall";
regKeyElement.Attributes.Append(actionAttr);
}
var regNameValueMatch = regNameValueRegex.Match(regFileLine);
// Registry Name/Value pair line found
if (regNameValueMatch.Success)
{
registryValueElement = xDoc.CreateElement("RegistryValue", NS_URI);
var nameAttr = xDoc.CreateAttribute("Name");
nameAttr.Value = regNameValueMatch.Groups["Name"].Value;
registryValueElement.Attributes.Append(nameAttr);
var actionAttr = xDoc.CreateAttribute("Action");
actionAttr.Value = "write";
registryValueElement.Attributes.Append(actionAttr);
if (string.IsNullOrEmpty(regNameValueMatch.Groups["MultiLine"].Value))
{
string valueType, actualValue;
ParseRegistryValue(regNameValueMatch.Groups["Value"].Value, out valueType,
out actualValue);
var typeAttr = xDoc.CreateAttribute("Type");
typeAttr.Value = valueType;
registryValueElement.Attributes.Append(typeAttr);
var valueAttr = xDoc.CreateAttribute("Value");
valueAttr.Value = actualValue;
registryValueElement.Attributes.Append(valueAttr);
regKeyElement.AppendChild(registryValueElement);
}
else
{
multiLine = true;
rawValueBuilder.Append(regNameValueMatch.Groups["Value"].Value
.Replace("\\", string.Empty));
}
}
else if (multiLine)
{
if (regFileLine.IndexOf("\\") != -1)
{
rawValueBuilder.Append(regFileLine.Replace("\\", string.Empty));
}
else
{
rawValueBuilder.Append(regFileLine);
string valueType, actualValue;
ParseRegistryValue(rawValueBuilder.ToString(), out valueType, out actualValue);
var typeAttr = xDoc.CreateAttribute("Type");
typeAttr.Value = valueType;
registryValueElement.Attributes.Append(typeAttr);
var valueAttr = xDoc.CreateAttribute("Value");
valueAttr.Value = actualValue;
registryValueElement.Attributes.Append(valueAttr);
regKeyElement.AppendChild(registryValueElement);
rawValueBuilder.Remove(0, rawValueBuilder.Length);
multiLine = false;
}
}
}
if (componentElement != null)
{
componentElement.AppendChild(regKeyElement);
includeElement.AppendChild(componentElement);
}
xDoc.AppendChild(includeElement);
xDoc.Save(outputPath);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
///
/// Parses the registry value.
///
/// The raw value.
/// Type of the value.
/// The actual value.
private static void ParseRegistryValue(string rawValue, out string valueType, out string actualValue)
{
if (rawValue.IndexOf("\"") != -1)
{
valueType = "string";
actualValue = rawValue.Substring(1, rawValue.Length - 2);
}
else if (rawValue.IndexOf("dword:") != -1)
{
valueType = "integer";
actualValue = rawValue.Replace("dword:", string.Empty);
}
else if (rawValue.IndexOf("hex:") != -1)
{
valueType = "binary";
actualValue = rawValue.Replace("hex:", string.Empty)
.Replace(",", string.Empty)
.ToUpper();
}
else if (rawValue.IndexOf("hex(7):") != -1)
{
valueType = "multiString";
string[] hexStrings = rawValue.Replace("hex(7):", string.Empty).Split(',');
var bytes = new byte[hexStrings.Length];
for (int i = 0; i < hexStrings.Length; i++)
{
bytes[i] = byte.Parse(hexStrings[i], NumberStyles.HexNumber);
}
actualValue = Encoding.Unicode.GetString(bytes).Replace("\0", "[~]");
}
else
{
valueType = "string";
actualValue = rawValue;
}
}
///
/// Gets the short name of the registry hive.
///
/// Full name of the hive.
///
private static string GetShortHiveName(string fullHiveName)
{
switch (fullHiveName)
{
case "HKEY_LOCAL_MACHINE":
return "HKLM";
case "HKEY_CLASSES_ROOT":
return "HKCR";
case "HKEY_USERS":
return "HKU";
case "HKEY_CURRENT_USER":
return "HKCU";
default:
throw new ArgumentException(string.Format("Registry Hive unsupported by Wix: {0}.",
fullHiveName));
}
}
///
/// Gets the MD5 hash for string.
///
/// The input string.
///
private static string GetMD5HashForString(string inputString)
{
MD5 hashAlg = MD5.Create();
byte[] originalInBytes = Encoding.ASCII.GetBytes(inputString);
byte[] hashedOriginal = hashAlg.ComputeHash(originalInBytes);
String outputString = Convert.ToBase64String(hashedOriginal)
.Replace("/", "aa")
.Replace("+", "bb")
.Replace("=", "cc");
return outputString;
}
#endregion
}
}
3> Ujjwal Singh..: 现在它被内置到Wix:Heat.exe
- 收获工具.
/sf/ask/17360801/