/// <summary>
        /// Converts the registry values to WiX regisry key element.
        /// </summary>
        /// <param name="sr">The registry file stream.</param>
        /// <param name="component">A WiX component reference.</param>
        /// <param name="root">The root key.</param>
        /// <param name="line">The current line.</param>
        private void ConvertValues(StreamReader sr, ref Wix.Component component, Wix.RegistryRootType root, string line)
        {
            string name  = null;
            string value = null;

            Wix.RegistryValue.TypeType type;
            Wix.RegistryKey            registryKey = new Wix.RegistryKey();

            registryKey.Root = root;
            registryKey.Key  = line;

            while (this.GetValue(sr, ref name, ref value, out type))
            {
                Wix.RegistryValue registryValue = new Wix.RegistryValue();
                ArrayList         charArray;

                // Don't specifiy name for default attribute
                if (!string.IsNullOrEmpty(name))
                {
                    registryValue.Name = name;
                }

                registryValue.Type = type;

                switch (type)
                {
                case Wix.RegistryValue.TypeType.binary:
                    registryValue.Value = value.Replace(",", string.Empty).ToUpper();
                    break;

                case Wix.RegistryValue.TypeType.integer:
                    registryValue.Value = Int32.Parse(value, NumberStyles.HexNumber).ToString();
                    break;

                case Wix.RegistryValue.TypeType.expandable:
                    charArray = this.ConvertCharList(value);
                    value     = string.Empty;

                    // create the string, remove the terminating null
                    for (int i = 0; i < charArray.Count; i++)
                    {
                        if ('\0' != (char)charArray[i])
                        {
                            value += charArray[i];
                        }
                    }

                    registryValue.Value = value;
                    break;

                case Wix.RegistryValue.TypeType.multiString:
                    charArray = this.ConvertCharList(value);
                    value     = string.Empty;

                    // Convert the character array to a string so we can simply split it at the nulls, ignore the final null null.
                    for (int i = 0; i < (charArray.Count - 2); i++)
                    {
                        value += charArray[i];
                    }

                    // Although the value can use [~] the preffered way is to use MultiStringValue
                    string[] parts = value.Split("\0".ToCharArray());
                    foreach (string part in parts)
                    {
                        Wix.MultiStringValue multiStringValue = new Wix.MultiStringValue();
                        multiStringValue.Content = part;
                        registryValue.AddChild(multiStringValue);
                    }

                    break;

                case Wix.RegistryValue.TypeType.@string:
                    // Remove \\ and \"
                    value = value.ToString().Replace("\\\"", "\"");
                    value = value.ToString().Replace(@"\\", @"\");
                    // Escape [ and ]
                    value = value.ToString().Replace(@"[", @"[\[]");
                    value = value.ToString().Replace(@"]", @"[\]]");
                    // This undoes the duplicate escaping caused by the second replace
                    value = value.ToString().Replace(@"[\[[\]]", @"[\[]");
                    // Escape $
                    value = value.ToString().Replace(@"$", @"$$");

                    registryValue.Value = value;
                    break;

                default:
                    throw new ApplicationException(String.Format("Did not recognize the type of reg value on line {0}", this.currentLineNumber));
                }

                registryKey.AddChild(registryValue);
            }

            // Make sure empty keys are created
            if (null == value)
            {
                registryKey.ForceCreateOnInstall = Wix.YesNoType.yes;
            }

            component.AddChild(registryKey);
        }
Beispiel #2
0
        /// <summary>
        /// Harvest a registry key.
        /// </summary>
        /// <param name="registryKey">The registry key to harvest.</param>
        /// <param name="registryValues">The collected registry values.</param>
        private void HarvestRegistryKey(RegistryKey registryKey, ArrayList registryValues)
        {
            // harvest the sub-keys
            foreach (string subKeyName in registryKey.GetSubKeyNames())
            {
                using (RegistryKey subKey = registryKey.OpenSubKey(subKeyName))
                {
                    this.HarvestRegistryKey(subKey, registryValues);
                }
            }

            string[] parts = GetPathParts(registryKey.Name);

            Wix.RegistryRootType root;
            switch (parts[0])
            {
                case "HKEY_CLASSES_ROOT":
                    root = Wix.RegistryRootType.HKCR;
                    break;
                case "HKEY_CURRENT_USER":
                    root = Wix.RegistryRootType.HKCU;
                    break;
                case "HKEY_LOCAL_MACHINE":
                    // HKLM\Software\Classes is equivalent to HKCR
                    if (1 < parts.Length && parts[1].StartsWith(HKCRPathInHKLM, StringComparison.OrdinalIgnoreCase))
                    {
                        root = Wix.RegistryRootType.HKCR;
                        parts[1] = parts[1].Remove(0, HKCRPathInHKLM.Length);

                        if (0 < parts[1].Length)
                        {
                            parts[1] = parts[1].TrimStart('\\');
                        }

                        if (String.IsNullOrEmpty(parts[1]))
                        {
                            parts = new [] { parts[0] };
                        }
                    }
                    else
                    {
                        root = Wix.RegistryRootType.HKLM;
                    }
                    break;
                case "HKEY_USERS":
                    root = Wix.RegistryRootType.HKU;
                    break;
                default:
                    // TODO: put a better exception here
                    throw new Exception();
            }

            // harvest the values
            foreach (string valueName in registryKey.GetValueNames())
            {
                Wix.RegistryValue registryValue = new Wix.RegistryValue();

                registryValue.Action = Wix.RegistryValue.ActionType.write;

                registryValue.Root = root;

                if (1 < parts.Length)
                {
                    registryValue.Key = parts[1];
                }

                if (null != valueName && 0 < valueName.Length)
                {
                    registryValue.Name = valueName;
                }

                object value = registryKey.GetValue(valueName);

                if (value is byte[]) // binary
                {
                    StringBuilder hexadecimalValue = new StringBuilder();

                    // convert the byte array to hexadecimal
                    foreach (byte byteValue in (byte[])value)
                    {
                        hexadecimalValue.Append(byteValue.ToString("X2", CultureInfo.InvariantCulture.NumberFormat));
                    }

                    registryValue.Type = Wix.RegistryValue.TypeType.binary;
                    registryValue.Value = hexadecimalValue.ToString();
                }
                else if (value is int) // integer
                {
                    registryValue.Type = Wix.RegistryValue.TypeType.integer;
                    registryValue.Value = ((int)value).ToString(CultureInfo.InvariantCulture);
                }
                else if (value is string[]) // multi-string
                {
                    registryValue.Type = Wix.RegistryValue.TypeType.multiString;

                    if (0 == ((string[])value).Length)
                    {
                        Wix.MultiStringValue multiStringValue = new Wix.MultiStringValue();

                        multiStringValue.Content = String.Empty;

                        registryValue.AddChild(multiStringValue);
                    }
                    else
                    {
                        foreach (string multiStringValueContent in (string[])value)
                        {
                            Wix.MultiStringValue multiStringValue = new Wix.MultiStringValue();

                            multiStringValue.Content = multiStringValueContent;

                            registryValue.AddChild(multiStringValue);
                        }
                    }
                }
                else if (value is string) // string, expandable (there is no way to differentiate a string and expandable value in .NET 1.1)
                {
                    registryValue.Type = Wix.RegistryValue.TypeType.@string;
                    registryValue.Value = (string)value;
                }
                else
                {
                    // TODO: put a better exception here
                    throw new Exception();
                }

                registryValues.Add(registryValue);
            }

            // If there were no subkeys and no values, we still need an element for this empty registry key.
            // But specifically avoid SOFTWARE\Classes because it shouldn't be harvested as an empty key.
            if (parts.Length > 1 && registryKey.SubKeyCount == 0 && registryKey.ValueCount == 0 &&
                !String.Equals(parts[1], HKCRPathInHKLM, StringComparison.OrdinalIgnoreCase))
            {
                Wix.RegistryValue emptyRegistryKey = new Wix.RegistryValue();
                emptyRegistryKey.Root = root;
                emptyRegistryKey.Key = parts[1];
                emptyRegistryKey.Type = Wix.RegistryValue.TypeType.@string;
                emptyRegistryKey.Value = String.Empty;
                emptyRegistryKey.Action = Wix.RegistryValue.ActionType.write;
                registryValues.Add(emptyRegistryKey);
            }
        }