private XElement?GetSubNodeElement(string nodeNameOrPath, bool createIfNotFound)
            {
                Conditions.RequireString(nodeNameOrPath, nameof(nodeNameOrPath));

                XElement?result         = null;
                XElement currentElement = this.element;

                // Use backslash as the path separator because that's what RegistryKey.OpenSubKey uses,
                // and callers need to be able to switch between the ISettingsStore types without breaking.
                // FWIW, RegistryKey ignores the forward slash character, so we can't split on it.
                string[] nodeNames = nodeNameOrPath.Split('\\');
                foreach (string nodeName in nodeNames)
                {
                    result = GetSubNodeElements(currentElement).SingleOrDefault(e => GetNodeName(e) == nodeName);
                    if (result == null)
                    {
                        if (!createIfNotFound)
                        {
                            break;
                        }

                        result = CreateNodeElement(nodeName);
                        currentElement.Add(result);
                    }

                    currentElement = result;
                }

                return(result);
            }
            internal static XElement CreateNodeElement(string nodeName)
            {
                Conditions.RequireString(nodeName, nameof(nodeName));
                XElement result = new("Settings", new XAttribute("Name", nodeName));

                return(result);
            }
Exemple #3
0
        /// <summary>
        /// Replaces a substring within the given text using the given comparison type.
        /// </summary>
        /// <param name="text">The text to search.</param>
        /// <param name="oldValue">The substring to search for.</param>
        /// <param name="newValue">The string that should replace the substring.</param>
        /// <param name="comparisonType">The type of string comparison to perform.</param>
        /// <returns>The string with the substring instances replaced.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="text"/> or <paramref name="oldValue"/>
        /// are null or empty.</exception>
        public static string Replace(string text, string oldValue, string?newValue, StringComparison comparisonType)
        {
            // Note: It's ok if newValue is null or empty.
            Conditions.RequireString(text, nameof(text));
            Conditions.RequireString(oldValue, nameof(oldValue));

            string result       = text;
            int    currentIndex = text.IndexOf(oldValue, comparisonType);

            if (currentIndex >= 0)
            {
                int           textLength     = text.Length;
                int           oldValueLength = oldValue.Length;
                int           previousIndex  = 0;
                StringBuilder sb             = new(text.Length);
                while (currentIndex >= 0)
                {
                    if (currentIndex > previousIndex)
                    {
                        sb.Append(text.Substring(previousIndex, currentIndex - previousIndex));
                    }

                    sb.Append(newValue);

                    currentIndex += oldValueLength;
                    previousIndex = currentIndex;
                    if ((currentIndex + 1) < textLength)
                    {
                        currentIndex = text.IndexOf(oldValue, currentIndex + 1, comparisonType);
                    }
                    else
                    {
                        break;
                    }
                }

                if (previousIndex < text.Length)
                {
                    sb.Append(text.Substring(previousIndex));
                }

                result = sb.ToString();
            }

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Strips the opening and closing quotes off of a string if they exist.
        /// </summary>
        /// <param name="text">The text to search.</param>
        /// <param name="openQuote">The opening quote string.</param>
        /// <param name="closeQuote">The closing quote string.</param>
        /// <returns>The text with the quotes removed.</returns>
        public static string StripQuotes(string text, string openQuote, string closeQuote)
        {
            Conditions.RequireReference(text, nameof(text));             // An empty string is ok.
            Conditions.RequireString(openQuote, nameof(openQuote));
            Conditions.RequireString(closeQuote, nameof(closeQuote));

            int startIndex = 0;
            int length     = text.Length;

            if (text.StartsWith(openQuote))
            {
                int quoteLength = openQuote.Length;
                startIndex += quoteLength;
                length     -= quoteLength;
            }

            if (text.EndsWith(closeQuote))
            {
                length -= closeQuote.Length;
            }

            return(text.Substring(startIndex, length));
        }
Exemple #5
0
        /// <summary>
        /// Ensures that the given text has the specified quotes at the start and end.
        /// </summary>
        /// <param name="text">The text to quote if necessary.</param>
        /// <param name="openQuote">The opening quote mark to use.</param>
        /// <param name="closeQuote">The closing quote mark to use.</param>
        /// <returns>The text enclosed in quotes.</returns>
        public static string EnsureQuotes(string text, string openQuote, string closeQuote)
        {
            Conditions.RequireReference(text, nameof(text));             // An empty string is ok.
            Conditions.RequireString(openQuote, nameof(openQuote));
            Conditions.RequireString(closeQuote, nameof(closeQuote));

            bool needsOpenQuote  = !text.StartsWith(openQuote);
            bool needsCloseQuote = !text.EndsWith(closeQuote);

            if (needsOpenQuote && needsCloseQuote)
            {
                text = string.Concat(openQuote, text, closeQuote);
            }
            else if (needsOpenQuote)
            {
                text = openQuote + text;
            }
            else if (needsCloseQuote)
            {
                text += closeQuote;
            }

            return(text);
        }
Exemple #6
0
        internal static string?GetShellFileTypeAndIcon(string fileName, bool useExistingFile, IconOptions iconOptions, Action <IntPtr>?useIconHandle)
        {
            Conditions.RequireString(fileName, nameof(fileName));
            Conditions.RequireArgument(
                (iconOptions == IconOptions.None && useIconHandle == null) || (iconOptions != IconOptions.None && useIconHandle != null),
                "The iconOptions and useIconHandle arguments must be compatible.");

            SHFILEINFO info       = default;
            int        cbFileInfo = Marshal.SizeOf(info);
            SHGFI      flags      = SHGFI.TypeName;

            int fileAttributes = 0;

            if (!useExistingFile)
            {
                flags |= SHGFI.UseFileAttributes;
                const int FILE_ATTRIBUTE_NORMAL    = 128;
                const int FILE_ATTRIBUTE_DIRECTORY = 16;

                // http://stackoverflow.com/questions/1599235/how-do-i-fetch-the-folder-icon-on-windows-7-using-shell32-shgetfileinfo
                fileAttributes = iconOptions.HasFlag(IconOptions.Folder) ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL;
            }

            bool useIcon = iconOptions != IconOptions.None;

            if (useIcon)
            {
                flags |= SHGFI.Icon;

                // The Small and Large options are mutually exclusive.  If they specify neither or both, then we'll default to small.
                if (iconOptions.HasFlag(IconOptions.Small) || !iconOptions.HasFlag(IconOptions.Large))
                {
                    flags |= SHGFI.SmallIcon;
                }
                else
                {
                    flags |= SHGFI.LargeIcon;
                }

                if (iconOptions.HasFlag(IconOptions.ShellSize))
                {
                    flags |= SHGFI.ShellIconSize;
                }

                if (iconOptions.HasFlag(IconOptions.Open))
                {
                    flags |= SHGFI.OpenIcon;
                }

                if (iconOptions.HasFlag(IconOptions.Shortcut))
                {
                    flags |= SHGFI.LinkOverlay;
                }

                if (iconOptions.HasFlag(IconOptions.Selected))
                {
                    flags |= SHGFI.Selected;
                }
            }

            string?result = null;

            if (SHGetFileInfo(fileName, fileAttributes, out info, (uint)cbFileInfo, flags) != IntPtr.Zero)
            {
                result = info.szTypeName;
                if (useIcon && useIconHandle != null)
                {
                    // The caller has to make a copy (e.g., Icon.FromHandle(hIcon).Clone()).
                    useIconHandle(info.hIcon);
                    DestroyIcon(info.hIcon);
                }
            }

            return(result);
        }