deployment - 如何从 .reg 文件生成 WiX XML?

标签 deployment installation wix windows-installer

是否有工具可以在给定 .reg 文件的情况下生成 WiX XML?

<小时/>

在 2.0 中,您应该能够运行 Tallow 来生成注册表 XML:

tallow -r my.reg 

无论如何,我拥有的牛脂版本会生成空 XML。

在 3.0 中,牛脂已被热量取代,但我不知道如何让它从 .reg 文件生成输出。

在 3.0 中有办法做到这一点吗?

最佳答案

我找不到工具,所以我做了一个。

源代码可能不太优雅,但似乎可以工作:

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]);
        }
    }
}

关于deployment - 如何从 .reg 文件生成 WiX XML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/269423/

相关文章:

amazon-web-services - 用于 go 的 Elastic Beanstalk Procfile

deployment - 要安装多少个 wiki 实例?

visual-studio-2010 - 如何从 Visual Studio 2010 加速 Azure 部署

makefile - 如何使用 cmake 删除安装目录中的旧二进制文件?

linux - 如何在 64 位 Linux red hat 6.2 服务器上安装 32 位软件包

python - 在使用 setup.py 构建/安装模块期间,如何将目录指定或添加到 Python.h 搜索路径?

c++ - 静默接受 .pfx 证书

windows-server-2008 - 将 Web 服务从 Team Foundation Server 部署到 IIS

Wix Custom BA 妥善处理升级

wix - 安装 MSI 之前删除文件和目录