public void PackRegMultiString()
        {
            string[] src =
            {
                "C:\\",
                "Hello",
                "World",
            };
            string       dest = StringEscaper.PackRegMultiString(src);
            const string comp = "C:\\#$zHello#$zWorld";

            Assert.IsTrue(dest.Equals(comp, StringComparison.Ordinal));
        }
        public static List <LogInfo> RegRead(EngineState s, CodeCommand cmd)
        { // RegRead,<HKey>,<KeyPath>,<ValueName>,<DestVar>
            List <LogInfo> logs = new List <LogInfo>();

            CodeInfo_RegRead info = cmd.Info.Cast <CodeInfo_RegRead>();

            string keyPath   = StringEscaper.Preprocess(s, info.KeyPath);
            string valueName = StringEscaper.Preprocess(s, info.ValueName);

            string hKeyStr = RegistryHelper.RegKeyToString(info.HKey);

            if (hKeyStr == null)
            {
                throw new InternalException("Internal Logic Error");
            }
            string fullKeyPath = $"{hKeyStr}\\{keyPath}";

            string valueDataStr;

            using (RegistryKey subKey = info.HKey.OpenSubKey(keyPath, false))
            {
                if (subKey == null)
                {
                    return(LogInfo.LogErrorMessage(logs, $"Registry key [{fullKeyPath}] does not exist"));
                }

                object valueData = subKey.GetValue(valueName, null, RegistryValueOptions.DoNotExpandEnvironmentNames);
                if (valueData == null)
                {
                    return(LogInfo.LogErrorMessage(logs, $"Cannot read registry key [{fullKeyPath}]"));
                }

                RegistryValueKind kind = subKey.GetValueKind(valueName);
                switch (kind)
                {
                case RegistryValueKind.None:
                    return(LogInfo.LogErrorMessage(logs, $"Cannot read empty value [{fullKeyPath}\\{valueName}]"));

                case RegistryValueKind.String:
                case RegistryValueKind.ExpandString:
                    valueDataStr = (string)valueData;
                    break;

                case RegistryValueKind.Binary:
                    valueDataStr = StringEscaper.PackRegBinary((byte[])valueData);
                    break;

                case RegistryValueKind.DWord:
                    valueDataStr = ((uint)(int)valueData).ToString();
                    break;

                case RegistryValueKind.MultiString:
                    valueDataStr = StringEscaper.PackRegMultiString((string[])valueData);
                    break;

                case RegistryValueKind.QWord:
                    valueDataStr = ((ulong)(long)valueData).ToString();
                    break;

                default:
                    return(LogInfo.LogErrorMessage(logs, $"Unsupported registry value type [0x{(int)kind:0:X}]"));
                }
            }

            logs.Add(new LogInfo(LogState.Success, $"Registry value [{fullKeyPath}\\{valueName}]'s data is [{valueDataStr}]"));
            List <LogInfo> varLogs = Variables.SetVariable(s, info.DestVar, valueDataStr);

            logs.AddRange(varLogs);

            return(logs);
        }
        private void RegWrite_Template(EngineState s, string rawCode,
                                       RegistryKey hKey, RegistryValueKind compKind, string keyPath, string valueName, object comp,
                                       ErrorCheck check = ErrorCheck.Success)
        {
            EngineTests.Eval(s, rawCode, CodeType.RegWrite, check);

            if (check == ErrorCheck.Success || check == ErrorCheck.Warning)
            {
                string valueDataStr;
                using (RegistryKey subKey = hKey.OpenSubKey(keyPath, false))
                {
                    Assert.IsNotNull(subKey);

                    RegistryValueKind kind = subKey.GetValueKind(valueName);
                    Assert.IsTrue(kind == compKind);

                    object valueData = subKey.GetValue(valueName, null, RegistryValueOptions.DoNotExpandEnvironmentNames);
                    Assert.IsNotNull(valueData);

                    switch (kind)
                    {
                    case RegistryValueKind.None:
                        break;

                    case RegistryValueKind.String:
                    case RegistryValueKind.ExpandString:
                    {
                        string destStr = (string)valueData;
                        string compStr = (string)comp;
                        Assert.IsTrue(destStr.Equals(compStr, StringComparison.Ordinal));
                    }
                    break;

                    case RegistryValueKind.MultiString:
                    {
                        string[] destStrs = (string[])valueData;
                        string[] compStrs = (string[])comp;

                        Assert.IsTrue(destStrs.Length == compStrs.Length);
                        for (int i = 0; i < destStrs.Length; i++)
                        {
                            Assert.IsTrue(destStrs[i].Equals(compStrs[i], StringComparison.Ordinal));
                        }
                    }
                        valueDataStr = StringEscaper.PackRegMultiString((string[])valueData);
                        break;

                    case RegistryValueKind.Binary:
                    {
                        byte[] destBin = (byte[])valueData;
                        byte[] compBin = (byte[])comp;
                        Assert.IsTrue(destBin.SequenceEqual(compBin));
                    }
                    break;

                    case RegistryValueKind.DWord:
                    {
                        uint destInt = (uint)(int)valueData;
                        uint compInt = (uint)comp;
                        Assert.IsTrue(destInt == compInt);
                    }
                    break;

                    case RegistryValueKind.QWord:
                    {
                        ulong destInt = (ulong)(long)valueData;
                        ulong compInt = (ulong)comp;
                        Assert.IsTrue(destInt == compInt);
                    }
                    break;

                    default:
                        Assert.Fail();
                        break;
                    }
                }
            }
        }