master 55507155dd8e cached
146 files
916.3 KB
228.4k tokens
875 symbols
1 requests
Download .txt
Showing preview only (965K chars total). Download the full file or copy to clipboard to get everything.
Repository: BluePointLilac/ContextMenuManager
Branch: master
Commit: 55507155dd8e
Files: 146
Total size: 916.3 KB

Directory structure:
gitextract_o6208a9c/

├── .gitattributes
├── .gitignore
├── ContextMenuManager/
│   ├── App.config
│   ├── BluePointLilac.Controls/
│   │   ├── DownloadDialog.cs
│   │   ├── IconDialog.cs
│   │   ├── InputDialog.cs
│   │   ├── MyCheckBox.cs
│   │   ├── MyListBox.cs
│   │   ├── MyMainForm.cs
│   │   ├── MySideBar.cs
│   │   ├── MyStatusBar.cs
│   │   ├── MyToolBar.cs
│   │   ├── PictureButton.cs
│   │   ├── ReadOnlyTextBox.cs
│   │   ├── ResizeLimitedForm.cs
│   │   ├── SelectDialog.cs
│   │   └── UAWebClient.cs
│   ├── BluePointLilac.Methods/
│   │   ├── ComboBoxExtension.cs
│   │   ├── ControlExtension.cs
│   │   ├── DirectoryEx.cs
│   │   ├── ElevatedFileDroper.cs
│   │   ├── EncodingType.cs
│   │   ├── ExternalProgram.cs
│   │   ├── FileExtension.cs
│   │   ├── FormExtension.cs
│   │   ├── GuidEx.cs
│   │   ├── HighDpi.cs
│   │   ├── ImageExtension.cs
│   │   ├── IniReader.cs
│   │   ├── IniWriter.cs
│   │   ├── MessageBoxEx.cs
│   │   ├── RegTrustedInstaller.cs
│   │   ├── RegistryEx.cs
│   │   ├── ResourceIcon.cs
│   │   ├── ResourceString.cs
│   │   ├── RichTextBoxExtension.cs
│   │   ├── ShellLink.cs
│   │   ├── SingleInstance.cs
│   │   ├── StringExtension.cs
│   │   ├── TextBoxExtension.cs
│   │   ├── ToolTipBox.cs
│   │   └── WinOsVersion.cs
│   ├── ContextMenuManager.csproj
│   ├── Controls/
│   │   ├── AppSettingBox.cs
│   │   ├── DetailedEditDialog.cs
│   │   ├── DetailedEditList.cs
│   │   ├── DictionariesBox.cs
│   │   ├── DonateBox.cs
│   │   ├── EnhanceMenusDialog.cs
│   │   ├── EnhanceMenusItem.cs
│   │   ├── EnhanceMenusList.cs
│   │   ├── ExplorerRestarter.cs
│   │   ├── FileExtensionDialog.cs
│   │   ├── FoldSubItem.cs
│   │   ├── GuidBlockedItem.cs
│   │   ├── GuidBlockedList.cs
│   │   ├── IEItem.cs
│   │   ├── IEList.cs
│   │   ├── Interfaces/
│   │   │   ├── IBtnDeleteItem.cs
│   │   │   ├── IBtnMoveUpDownItem.cs
│   │   │   ├── IBtnShowMenuItem.cs
│   │   │   ├── IChkVisibleItem.cs
│   │   │   ├── IProtectOpenItem.cs
│   │   │   ├── ITsiAdministratorItem.cs
│   │   │   ├── ITsiCommandItem.cs
│   │   │   ├── ITsiDeleteItem.cs
│   │   │   ├── ITsiFilePathItem.cs
│   │   │   ├── ITsiGuidItem.cs
│   │   │   ├── ITsiIconItem.cs
│   │   │   ├── ITsiRegExportItem.cs
│   │   │   ├── ITsiRegPathItem.cs
│   │   │   ├── ITsiShortcutCommandItem.cs
│   │   │   ├── ITsiTextItem.cs
│   │   │   └── ITsiWebSearchItem.cs
│   │   ├── LanguagesBox.cs
│   │   ├── NewIEDialog.cs
│   │   ├── NewItem.cs
│   │   ├── NewItemForm.cs
│   │   ├── NewLnkFileDialog.cs
│   │   ├── NewOpenWithDialog.cs
│   │   ├── NewShellDialog.cs
│   │   ├── OpenWithItem.cs
│   │   ├── OpenWithList.cs
│   │   ├── RuleItem.cs
│   │   ├── SendToItem.cs
│   │   ├── SendToList.cs
│   │   ├── ShellExItem.cs
│   │   ├── ShellExecuteDialog.cs
│   │   ├── ShellItem.cs
│   │   ├── ShellList.cs
│   │   ├── ShellNewItem.cs
│   │   ├── ShellNewList.cs
│   │   ├── ShellStoreDialog.cs
│   │   ├── ShellSubMenuDialog.cs
│   │   ├── SubItemsForm.cs
│   │   ├── SwitchDicList.cs
│   │   ├── UwpModeItem.cs
│   │   ├── WinXGroupItem.cs
│   │   ├── WinXItem.cs
│   │   └── WinXList.cs
│   ├── MainForm.cs
│   ├── Methods/
│   │   ├── AppConfig.cs
│   │   ├── AppImage.cs
│   │   ├── AppMessageBox.cs
│   │   ├── AppString.cs
│   │   ├── DesktopIni.cs
│   │   ├── GuidInfo.cs
│   │   ├── ObjectPath.cs
│   │   ├── Updater.cs
│   │   ├── UwpHelper.cs
│   │   ├── WinXHasher.cs
│   │   └── XmlDicHelper.cs
│   ├── Program.cs
│   └── Properties/
│       ├── App.manifest
│       ├── AssemblyInfo.cs
│       ├── Resources/
│       │   ├── ShellNew/
│       │   │   ├── 0.c
│       │   │   ├── 0.html
│       │   │   ├── 0.reg
│       │   │   ├── 0.rtf
│       │   │   ├── 0.xlsx
│       │   │   └── 0.xml
│       │   └── Texts/
│       │       ├── AppLanguageDic.ini
│       │       ├── DetailedEditDic.xml
│       │       ├── EnhanceMenusDic.xml
│       │       ├── GuidInfosDic.ini
│       │       └── UwpModeItemsDic.xml
│       ├── Resources.Designer.cs
│       ├── Resources.resx
│       ├── Settings.Designer.cs
│       └── Settings.settings
├── ContextMenuManager.sln
├── Donate.md
├── LICENSE
├── Logo/
│   └── Logo.psd
├── README-en.md
├── README.md
├── Update.ini
└── languages/
    ├── ar-DZ عربية
    ├── de-DE.ini
    ├── en-US.ini
    ├── ja-JP.ini
    ├── ko-KR.ini
    ├── pt-BR.ini
    ├── ru-RU.ini
    ├── zh-CN.ini
    └── zh-TW.ini

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto

###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs     diff=csharp

###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following 
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln       merge=binary
#*.csproj    merge=binary
#*.vbproj    merge=binary
#*.vcxproj   merge=binary
#*.vcproj    merge=binary
#*.dbproj    merge=binary
#*.fsproj    merge=binary
#*.lsproj    merge=binary
#*.wixproj   merge=binary
#*.modelproj merge=binary
#*.sqlproj   merge=binary
#*.wwaproj   merge=binary

###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg   binary
#*.png   binary
#*.gif   binary

###############################################################################
# diff behavior for common document formats
# 
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the 
# entries below.
###############################################################################
#*.doc   diff=astextplain
#*.DOC   diff=astextplain
#*.docx  diff=astextplain
#*.DOCX  diff=astextplain
#*.dot   diff=astextplain
#*.DOT   diff=astextplain
#*.pdf   diff=astextplain
#*.PDF   diff=astextplain
#*.rtf   diff=astextplain
#*.RTF   diff=astextplain


================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/

# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

# DNX
project.lock.json
project.fragment.lock.json
artifacts/

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb

# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding add-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj

# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/

# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets

# Microsoft Azure Build Output
csx/
*.build.csdef

# Microsoft Azure Emulator
ecf/
rcf/

# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt

# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/

# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs

# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/

# GhostDoc plugin setting file
*.GhostDoc.xml

# Node.js Tools for Visual Studio
.ntvs_analysis.dat

# Visual Studio 6 build log
*.plg

# Visual Studio 6 workspace options file
*.opt

# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions

# Paket dependency manager
.paket/paket.exe
paket-files/

# FAKE - F# Make
.fake/

# JetBrains Rider
.idea/
*.sln.iml

# CodeRush
.cr/

# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

================================================
FILE: ContextMenuManager/App.config
================================================
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup>
    
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
  <runtime>
    <legacyCorruptedStateExceptionsPolicy enabled="true"/>
    <EnableWindowsFormsHighDpiAutoResizing enabled="true"/>
  </runtime>
</configuration>


================================================
FILE: ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    sealed class DownloadDialog : CommonDialog
    {
        public string Text { get; set; }
        public string Url { get; set; }
        public string FilePath { get; set; }
        public override void Reset() { }

        protected override bool RunDialog(IntPtr hwndOwner)
        {
            using(Process process = Process.GetCurrentProcess())
            using(DownloadForm frm = new DownloadForm())
            {
                frm.Url = this.Url;
                frm.Text = this.Text;
                frm.FilePath = this.FilePath;
                return frm.ShowDialog() == DialogResult.OK;
            }
        }

        sealed class DownloadForm : Form
        {
            public DownloadForm()
            {
                this.SuspendLayout();
                this.Font = SystemFonts.MessageBoxFont;
                this.FormBorderStyle = FormBorderStyle.FixedSingle;
                this.MinimizeBox = this.MaximizeBox = this.ShowInTaskbar = false;
                this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
                this.Controls.AddRange(new Control[] { pgbDownload, btnCancel });
                this.Load += (sender, e) => DownloadFile(Url, FilePath);
                this.InitializeComponents();
                this.ResumeLayout();
            }

            readonly ProgressBar pgbDownload = new ProgressBar
            {
                Width = 200.DpiZoom(),
                Maximum = 100
            };
            readonly Button btnCancel = new Button
            {
                DialogResult = DialogResult.Cancel,
                Text = ResourceString.Cancel,
                AutoSize = true
            };

            public string Url { get; set; }
            public string FilePath { get; set; }

            private void InitializeComponents()
            {
                int a = 20.DpiZoom();
                pgbDownload.Left = pgbDownload.Top = btnCancel.Top = a;
                pgbDownload.Height = btnCancel.Height;
                btnCancel.Left = pgbDownload.Right + a;
                this.ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);
            }

            private void DownloadFile(string url, string filePath)
            {
                try
                {
                    using(UAWebClient client = new UAWebClient())
                    {
                        client.DownloadProgressChanged += (sender, e) =>
                        {
                            int value = e.ProgressPercentage;
                            this.Text = $"Downloading: {value}%";
                            pgbDownload.Value = value;
                            if(this.DialogResult == DialogResult.Cancel)
                            {
                                client.CancelAsync();
                                File.Delete(FilePath);
                            }
                        };
                        client.DownloadFileCompleted += (sender, e) =>
                        {
                            this.DialogResult = DialogResult.OK;
                        };
                        client.DownloadFileAsync(new Uri(url), filePath);
                    }
                }
                catch(Exception e)
                {
                    MessageBox.Show(e.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    this.DialogResult = DialogResult.Cancel;
                }
            }

            protected override void OnLoad(EventArgs e)
            {
                if(this.Owner == null && Form.ActiveForm != this) this.Owner = Form.ActiveForm;
                if(this.Owner == null) this.StartPosition = FormStartPosition.CenterScreen;
                else
                {
                    this.TopMost = this.Owner.TopMost;
                    this.StartPosition = FormStartPosition.CenterParent;
                }
                base.OnLoad(e);
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/IconDialog.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public sealed class IconDialog : CommonDialog
    {
        [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "#62", SetLastError = true)]
        private static extern bool PickIconDlg(IntPtr hWnd, StringBuilder pszFileName, int cchFileNameMax, ref int pnIconIndex);

        private const int MAXLENGTH = 260;
        private int iconIndex;
        public int IconIndex { get => iconIndex; set => iconIndex = value; }
        public string IconPath { get; set; }

        public override void Reset() { }

        protected override bool RunDialog(IntPtr hwndOwner)
        {
            StringBuilder sb = new StringBuilder(IconPath, MAXLENGTH);
            bool flag = PickIconDlg(hwndOwner, sb, MAXLENGTH, ref iconIndex);
            IconPath = flag ? sb.ToString() : null;
            return flag;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/InputDialog.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public sealed class InputDialog : CommonDialog
    {
        /// <summary>输入对话框标题</summary>
        public string Title { get; set; } = Application.ProductName;
        /// <summary>输入对话框文本框文本</summary>
        public string Text { get; set; }
        public Size Size { get; set; }

        public override void Reset() { }

        protected override bool RunDialog(IntPtr hwndOwner)
        {
            using(InputBox frm = new InputBox())
            {
                frm.Text = Title;
                frm.InputedText = this.Text;
                frm.Size = this.Size;
                Form owner = (Form)Control.FromHandle(hwndOwner);
                if(owner != null) frm.TopMost = owner.TopMost;
                bool flag = frm.ShowDialog() == DialogResult.OK;
                this.Text = flag ? frm.InputedText : null;
                return flag;
            }
        }

        sealed class InputBox : Form
        {
            public InputBox()
            {
                this.AcceptButton = btnOK;
                this.CancelButton = btnCancel;
                this.Font = SystemFonts.MessageBoxFont;
                this.SizeGripStyle = SizeGripStyle.Hide;
                this.StartPosition = FormStartPosition.CenterParent;
                this.MaximizeBox = MinimizeBox = ShowIcon = ShowInTaskbar = false;
                this.Controls.AddRange(new Control[] { txtInput, btnOK, btnCancel });
                txtInput.Font = new Font(txtInput.Font.FontFamily, txtInput.Font.Size + 2F);
                txtInput.CanResizeFont();
                InitializeComponents();
            }

            public string InputedText
            {
                get => txtInput.Text;
                set => txtInput.Text = value;
            }

            readonly TextBox txtInput = new TextBox
            {
                Font = SystemFonts.MenuFont,
                ScrollBars = ScrollBars.Vertical,
                Multiline = true
            };
            readonly Button btnOK = new Button
            {
                Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
                DialogResult = DialogResult.OK,
                Text = ResourceString.OK,
                AutoSize = true
            };
            readonly Button btnCancel = new Button
            {
                Anchor = AnchorStyles.Bottom | AnchorStyles.Right,
                DialogResult = DialogResult.Cancel,
                Text = ResourceString.Cancel,
                AutoSize = true
            };

            private void InitializeComponents()
            {
                this.SuspendLayout();
                int a = 20.DpiZoom();
                txtInput.Location = new Point(a, a);
                txtInput.Size = new Size(340, 24).DpiZoom();
                this.ClientSize = new Size(txtInput.Width + a * 2, txtInput.Height + btnOK.Height + a * 3);
                btnCancel.Top = btnOK.Top = txtInput.Bottom + a;
                btnCancel.Left = txtInput.Right - btnCancel.Width;
                btnOK.Left = btnCancel.Left - btnOK.Width - a;
                this.ResumeLayout();
                this.MinimumSize = this.Size;
                this.Resize += (sender, e) =>
                {
                    txtInput.Width = this.ClientSize.Width - 2 * a;
                    txtInput.Height = btnCancel.Top - 2 * a;
                };
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/MyCheckBox.cs
================================================
using BluePointLilac.Methods;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    [DefaultProperty("Checked")]
    public class MyCheckBox : PictureBox
    {
        public MyCheckBox()
        {
            this.Image = TurnOff;
            this.Cursor = Cursors.Hand;
            this.SizeMode = PictureBoxSizeMode.AutoSize;
        }

        private bool? _Checked = null;
        public bool Checked
        {
            get => _Checked == true;
            set
            {
                if(_Checked == value) return;
                this.Image = SwitchImage(value);
                if(_Checked == null)
                {
                    _Checked = value;
                    return;
                }
                if(PreCheckChanging != null && !PreCheckChanging.Invoke())
                {
                    this.Image = SwitchImage(!value);
                    return;
                }
                else CheckChanging?.Invoke();
                if(PreCheckChanged != null && !PreCheckChanged.Invoke())
                {
                    this.Image = SwitchImage(!value);
                    return;
                }
                else
                {
                    _Checked = value;
                    CheckChanged?.Invoke();
                }
            }
        }

        public Func<bool> PreCheckChanging;
        public Func<bool> PreCheckChanged;
        public Action CheckChanging;
        public Action CheckChanged;

        public Image TurnOnImage { get; set; } = TurnOn;
        public Image TurnOffImage { get; set; } = TurnOff;

        private Image SwitchImage(bool value)
        {
            return value ? TurnOnImage : TurnOffImage;
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if(e.Button == MouseButtons.Left) this.Checked = !this.Checked;
        }

        private static readonly Image TurnOn = DrawImage(true);
        private static readonly Image TurnOff = DrawImage(false);

        private static Image DrawImage(bool value)
        {
            int w = 80.DpiZoom();
            int r1 = 16.DpiZoom();
            float r2 = 13F.DpiZoom();
            int d1 = r1 * 2;
            float d2 = r2 * 2;
            float a = r1 - r2;
            Bitmap bitmap = new Bitmap(w, d1);
            using(Graphics g = Graphics.FromImage(bitmap))
            {
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;
                using(GraphicsPath path = new GraphicsPath())
                {
                    path.AddArc(new RectangleF(0, 0, d1, d1), 90, 180);
                    path.AddLine(new PointF(r1, 0), new PointF(w - r1, 0));
                    path.AddArc(new RectangleF(w - d1, 0, d1, d1), -90, 180);
                    path.AddLine(new PointF(w - r1, d1), new PointF(r1, d1));
                    Color color = value ? Color.FromArgb(0, 138, 217) : Color.FromArgb(130, 136, 144);
                    using(Brush brush = new SolidBrush(color))
                    {
                        g.FillPath(brush, path);
                    }
                }
                using(GraphicsPath path = new GraphicsPath())
                {
                    path.AddArc(new RectangleF(a, a, d2, d2), 90, 180);
                    path.AddLine(new PointF(r1, a), new PointF(w - r1, a));
                    path.AddArc(new RectangleF(w - d2 - a, a, d2, d2), -90, 180);
                    path.AddLine(new PointF(w - r1, d2 + a), new PointF(r1, d2 + a));
                    Color color = value ? Color.FromArgb(0, 162, 255) : Color.FromArgb(153, 160, 169);
                    using(Brush brush = new SolidBrush(color))
                    {
                        g.FillPath(brush, path);
                    }
                }
                using(GraphicsPath path = new GraphicsPath())
                {
                    path.AddEllipse(new RectangleF(value ? (w - d2 - a) : a, a, d2, d2));
                    g.FillPath(Brushes.White, path);
                }
            }
            return bitmap;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/MyListBox.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public class MyListBox : Panel
    {
        public MyListBox()
        {
            this.AutoScroll = true;
            this.BackColor = Color.FromArgb(250, 250, 250);
        }

        protected override void OnMouseWheel(MouseEventArgs e)
        {
            //使滚动幅度与MyListItem的高度相配合,防止滚动过快导致来不及重绘界面变花
            base.OnMouseWheel(new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, Math.Sign(e.Delta) * 50.DpiZoom()));
        }
    }

    public class MyList : FlowLayoutPanel
    {
        public MyListBox Owner
        {
            get => (MyListBox)this.Parent;
            set => this.Parent = value;
        }

        public MyList(MyListBox owner) : this()
        {
            this.Owner = owner;
        }

        public MyList()
        {
            this.AutoSize = true;
            this.WrapContents = true;
            this.Dock = DockStyle.Top;
            this.DoubleBuffered = true;
            this.AutoSizeMode = AutoSizeMode.GrowAndShrink;
        }

        private MyListItem hoveredItem;
        public MyListItem HoveredItem
        {
            get => hoveredItem;
            set
            {
                if(hoveredItem == value) return;
                if(hoveredItem != null)
                {
                    hoveredItem.ForeColor = Color.FromArgb(90, 90, 90);
                    //hoveredItem.BackColor = Color.FromArgb(250, 250, 250);
                    //hoveredItem.Font = new Font(hoveredItem.Font, FontStyle.Regular);
                }
                hoveredItem = value;
                if(hoveredItem != null)
                {
                    value.ForeColor = Color.FromArgb(0, 138, 217);
                    //value.BackColor = Color.FromArgb(200, 230, 250);
                    //value.Font = new Font(hoveredItem.Font, FontStyle.Bold);
                    value.Focus();
                }
                HoveredItemChanged?.Invoke(this, null);
            }
        }

        public event EventHandler HoveredItemChanged;

        public void AddItem(MyListItem item)
        {
            this.SuspendLayout();
            item.Parent = this;
            item.MouseEnter += (sender, e) => HoveredItem = item;
            this.MouseWheel += (sender, e) => item.ContextMenuStrip?.Close();
            void ResizeItem() => item.Width = Owner.Width - item.Margin.Horizontal;
            Owner.Resize += (sender, e) => ResizeItem();
            ResizeItem();
            this.ResumeLayout();
        }

        public void AddItems(MyListItem[] items)
        {
            Array.ForEach(items, item => AddItem(item));
        }

        public void AddItems(List<MyListItem> items)
        {
            items.ForEach(item => AddItem(item));
        }

        public void SetItemIndex(MyListItem item, int newIndex)
        {
            this.Controls.SetChildIndex(item, newIndex);
        }

        public int GetItemIndex(MyListItem item)
        {
            return Controls.GetChildIndex(item);
        }

        public void InsertItem(MyListItem item, int index)
        {
            if(item == null) return;
            this.AddItem(item);
            this.SetItemIndex(item, index);
        }

        public virtual void ClearItems()
        {
            if(this.Controls.Count == 0) return;
            this.SuspendLayout();
            for(int i = this.Controls.Count - 1; i >= 0; i--)
            {
                Control ctr = this.Controls[i];
                this.Controls.Remove(ctr);
                ctr.Dispose();
            }
            this.ResumeLayout();
        }

        public void SortItemByText()
        {
            List<MyListItem> items = new List<MyListItem>();
            foreach(MyListItem item in this.Controls) items.Add(item);
            this.Controls.Clear();
            items.Sort(new TextComparer());
            items.ForEach(item => this.AddItem(item));
        }

        public class TextComparer : IComparer<MyListItem>
        {
            public int Compare(MyListItem x, MyListItem y)
            {
                if(x.Equals(y)) return 0;
                string[] strs = { x.Text, y.Text };
                Array.Sort(strs);
                if(strs[0] == x.Text) return -1;
                else return 1;
            }
        }
    }

    public class MyListItem : Panel
    {
        public MyListItem()
        {
            this.SuspendLayout();
            this.HasImage = true;
            this.DoubleBuffered = true;
            this.Height = 50.DpiZoom();
            this.Margin = new Padding(0);
            this.Font = SystemFonts.IconTitleFont;
            this.ForeColor = Color.FromArgb(80, 80, 80);
            this.BackColor = Color.FromArgb(250, 250, 250);
            this.Controls.AddRange(new Control[] { lblSeparator, flpControls, lblText, picImage });
            this.Resize += (Sender, e) => pnlScrollbar.Height = this.ClientSize.Height;
            flpControls.MouseClick += (sender, e) => this.OnMouseClick(e);
            flpControls.MouseEnter += (sender, e) => this.OnMouseEnter(e);
            flpControls.MouseDown += (sender, e) => this.OnMouseDown(e);
            lblSeparator.SetEnabled(false);
            lblText.SetEnabled(false);
            CenterControl(lblText);
            CenterControl(picImage);
            AddCtr(pnlScrollbar, 0);
            this.ResumeLayout();
        }

        public Image Image
        {
            get => picImage.Image;
            set => picImage.Image = value;
        }
        public new string Text
        {
            get => lblText.Text;
            set => lblText.Text = value;
        }
        public new Font Font
        {
            get => lblText.Font;
            set => lblText.Font = value;
        }
        public new Color ForeColor
        {
            get => lblText.ForeColor;
            set => lblText.ForeColor = value;
        }

        private bool hasImage;
        public bool HasImage
        {
            get => hasImage;
            set
            {
                hasImage = value;
                picImage.Visible = value;
                lblText.Left = (value ? 60 : 20).DpiZoom();
            }
        }

        private readonly Label lblText = new Label
        {
            AutoSize = true,
            Name = "Text"
        };
        private readonly PictureBox picImage = new PictureBox
        {
            SizeMode = PictureBoxSizeMode.AutoSize,
            Left = 20.DpiZoom(),
            Enabled = false,
            Name = "Image"
        };
        private readonly FlowLayoutPanel flpControls = new FlowLayoutPanel
        {
            AutoSizeMode = AutoSizeMode.GrowAndShrink,
            FlowDirection = FlowDirection.RightToLeft,
            Anchor = AnchorStyles.Right,
            AutoSize = true,
            Name = "Controls"
        };
        private readonly Label lblSeparator = new Label
        {
            BackColor = Color.FromArgb(220, 220, 220),
            Dock = DockStyle.Bottom,
            Name = "Separator",
            Height = 1
        };//分割线
        private readonly Panel pnlScrollbar = new Panel
        {
            Width = SystemInformation.VerticalScrollBarWidth,
            Enabled = false
        };//预留滚动条宽度

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e); OnMouseEnter(null);
        }

        private void CenterControl(Control ctr)
        {
            void reSize()
            {
                if(ctr.Parent == null) return;
                int top = (this.ClientSize.Height - ctr.Height) / 2;
                ctr.Top = top;
                if(ctr.Parent == flpControls)
                {
                    ctr.Margin = new Padding(0, top, ctr.Margin.Right, top);
                }
            }
            ctr.Parent.Resize += (sender, e) => reSize();
            ctr.Resize += (sender, e) => reSize();
            reSize();
        }

        public void AddCtr(Control ctr)
        {
            AddCtr(ctr, 20.DpiZoom());
        }

        public void AddCtr(Control ctr, int space)
        {
            this.SuspendLayout();
            ctr.Parent = flpControls;
            ctr.Margin = new Padding(0, 0, space, 0);
            ctr.MouseEnter += (sender, e) => this.OnMouseEnter(e);
            ctr.MouseDown += (sender, e) => this.OnMouseEnter(e);
            CenterControl(ctr);
            this.ResumeLayout();
        }

        public void AddCtrs(Control[] ctrs)
        {
            Array.ForEach(ctrs, ctr => AddCtr(ctr));
        }

        public void RemoveCtrAt(int index)
        {
            if(flpControls.Controls.Count > index) flpControls.Controls.RemoveAt(index + 1);
        }

        public int GetCtrIndex(Control ctr)
        {
            return flpControls.Controls.GetChildIndex(ctr, true) - 1;
        }

        public void SetCtrIndex(Control ctr, int newIndex)
        {
            flpControls.Controls.SetChildIndex(ctr, newIndex + 1);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/MyMainForm.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public class MyMainForm : Form
    {
        public MyMainForm()
        {
            this.SuspendLayout();
            this.Text = Application.ProductName;
            this.ForeColor = Color.FromArgb(80, 80, 80);
            this.BackColor = Color.FromArgb(250, 250, 250);
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
            this.Controls.AddRange(new Control[] { MainBody, SideBar, StatusBar, ToolBar });
            SideBar.Resize += (sender, e) => this.OnResize(null);
            this.ClientSize = new Size(850, 610).DpiZoom();
            this.MinimumSize = this.Size;
            MainBody.Dock = DockStyle.Left;
            StatusBar.CanMoveForm();
            ToolBar.CanMoveForm();
            this.ResumeLayout();
        }

        public readonly MyToolBar ToolBar = new MyToolBar();
        public readonly MySideBar SideBar = new MySideBar();
        public readonly MyStatusBar StatusBar = new MyStatusBar();
        public readonly MyListBox MainBody = new MyListBox();

        /// <summary>窗体移动时是否临时挂起MainBody</summary>
        public bool SuspendMainBodyWhenMove { get; set; } = false;
        /// <summary>窗体调整大小时是否临时挂起MainBody</summary>
        public bool SuspendMainBodyWhenResize { get; set; } = true;

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            MainBody.Width = this.ClientSize.Width - SideBar.Width;
        }

        protected override void WndProc(ref Message m)
        {
            const int WM_NCLBUTTONDBLCLK = 0x00A3;
            const int WM_SYSCOMMAND = 0x0112;
            const int SC_MAXIMIZE = 0xF030;
            const int SC_MINIMIZE = 0xF020;
            const int SC_RESTORE = 0xF120;
            const int SC_MOVE = 0xF012;
            const int SC_SIZE = 0xF000;
            const int HT_CAPTION = 0x2;
            bool suspend = false;//临时挂起MainBody
            switch(m.Msg)
            {
                case WM_SYSCOMMAND:
                    switch(m.WParam.ToInt32())
                    {
                        //解决控件过多移动窗体时延迟问题
                        case SC_MOVE:
                        //解决控件过多调整窗体大小时延迟问题
                        case SC_SIZE:
                            suspend = this.SuspendMainBodyWhenMove; break;
                        //解决控件过多最大化、最小化、还原重绘卡顿问题
                        case SC_RESTORE:
                        case SC_MINIMIZE:
                        case SC_MAXIMIZE:
                            suspend = this.SuspendMainBodyWhenResize; break;
                    }
                    break;
                case WM_NCLBUTTONDBLCLK:
                    switch(m.WParam.ToInt32())
                    {
                        //双击标题栏最大化和还原窗口
                        case HT_CAPTION:
                            suspend = this.SuspendMainBodyWhenResize; break;
                    }
                    break;
            }
            if(suspend)
            {
                this.SuspendLayout();
                MainBody.SuspendLayout();
                this.Controls.Remove(MainBody);
                base.WndProc(ref m);
                this.Controls.Add(MainBody);
                MainBody.BringToFront();
                MainBody.ResumeLayout();
                this.ResumeLayout();
            }
            else base.WndProc(ref m);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/MySideBar.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public sealed class MySideBar : Panel
    {
        public MySideBar()
        {
            this.Dock = DockStyle.Left;
            this.ItemHeight = 30.DpiZoom();
            this.Font = SystemFonts.MenuFont;
            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);
            this.ForeColor = Color.FromArgb(80, 80, 80);
            this.BackColor = Color.FromArgb(245, 245, 245);
            this.BackgroundImageLayout = ImageLayout.None;
            this.Controls.AddRange(new Control[] { LblSeparator, PnlSelected, PnlHovered });
            PnlHovered.Paint += PaintItem;
            PnlSelected.Paint += PaintItem;
            this.SelectedIndex = -1;
        }

        private string[] itemNames;
        public string[] ItemNames
        {
            get => itemNames;
            set
            {
                itemNames = value;
                if(value != null && !IsFixedWidth)
                {
                    int maxWidth = 0;
                    Array.ForEach(value, str => maxWidth = Math.Max(maxWidth, GetItemWidth(str)));
                    this.Width = maxWidth + 2 * HorizontalSpace;
                }
                PnlHovered.Width = PnlSelected.Width = this.Width;
                PaintItems();
                SelectedIndex = -1;
            }
        }

        private int itemHeight;
        public int ItemHeight
        {
            get => itemHeight;
            set => PnlHovered.Height = PnlSelected.Height = itemHeight = value;
        }//项上下边缘距离
        public int TopSpace { get; set; } = 2.DpiZoom();//第一项顶部与上边缘的距离
        public int HorizontalSpace { get; set; } = 20.DpiZoom();//项文字与项左右边缘距离
        private float VerticalSpace => (itemHeight - TextHeight) * 0.5F;//项文字与项上下边缘距离
        private int TextHeight => TextRenderer.MeasureText(" ", Font).Height;//项文字高度
        public bool IsFixedWidth { get; set; } = true;//是否固定宽度

        public Color SeparatorColor
        {
            get => LblSeparator.BackColor;
            set => LblSeparator.BackColor = value;
        }//分隔线颜色
        public Color SelectedBackColor
        {
            get => PnlSelected.BackColor;
            set => PnlSelected.BackColor = value;
        }
        public Color HoveredBackColor
        {
            get => PnlHovered.BackColor;
            set => PnlHovered.BackColor = value;
        }
        public Color SelectedForeColor
        {
            get => PnlSelected.ForeColor;
            set => PnlSelected.ForeColor = value;
        }
        public Color HoveredForeColor
        {
            get => PnlHovered.ForeColor;
            set => PnlHovered.ForeColor = value;
        }

        readonly Panel PnlSelected = new Panel
        {
            BackColor = Color.FromArgb(40, 140, 210),
            ForeColor = Color.White,
            Enabled = false
        };
        readonly Panel PnlHovered = new Panel
        {
            BackColor = Color.FromArgb(80, 180, 250),
            ForeColor = Color.White,
            Enabled = false
        };
        readonly Label LblSeparator = new Label
        {
            BackColor = Color.FromArgb(220, 220, 220),
            Dock = DockStyle.Right,
            Width = 1,
        };

        /// <summary>获取项目宽度</summary>
        public int GetItemWidth(string str)
        {
            return TextRenderer.MeasureText(str, Font).Width + 2 * HorizontalSpace;
        }

        /// <summary>绘制所有项目作为底图</summary>
        private void PaintItems()
        {
            this.BackgroundImage = new Bitmap(Width, ItemHeight * ItemNames.Length);
            using(Graphics g = Graphics.FromImage(BackgroundImage))
            {
                g.Clear(BackColor);
                if(itemNames == null) return;
                for(int i = 0; i < itemNames.Length; i++)
                {
                    if(itemNames[i] != null)
                    {
                        g.DrawString(itemNames[i], Font, new SolidBrush(ForeColor),
                            new PointF(HorizontalSpace, TopSpace + i * ItemHeight + VerticalSpace));
                    }
                    else
                    {
                        g.DrawLine(new Pen(SeparatorColor),
                            new PointF(HorizontalSpace, TopSpace + (i + 0.5F) * ItemHeight),
                            new PointF(Width - HorizontalSpace, TopSpace + (i + 0.5F) * ItemHeight)
                        );
                    }
                }
            }
        }

        /// <summary>刷新选中的项目</summary>
        private void RefreshItem(Panel panel, int index)
        {
            panel.CreateGraphics().Clear(panel.BackColor);
            panel.Top = index < 0 ? -ItemHeight : (TopSpace + index * ItemHeight);
            panel.Text = index < 0 ? null : ItemNames[index];
            panel.Refresh();
        }

        /// <summary>绘制选中的项目</summary>
        private void PaintItem(object sender, PaintEventArgs e)
        {
            Control ctr = (Control)sender;
            e.Graphics.DrawString(ctr.Text, Font,
                new SolidBrush(ctr.ForeColor),
                new PointF(HorizontalSpace, VerticalSpace));
        }

        /// <summary>显示选中的项目</summary>
        private void ShowItem(Panel panel, MouseEventArgs e)
        {
            if(itemNames == null) return;
            int index = (e.Y - TopSpace) / ItemHeight;
            if(index >= itemNames.Length || index < 0 || string.IsNullOrEmpty(itemNames[index]) || index == SelectedIndex)
            {
                this.Cursor = Cursors.Default;
                HoveredIndex = SelectedIndex;
            }
            else
            {
                this.Cursor = Cursors.Hand;
                if(panel == PnlSelected) SelectedIndex = index;
                else HoveredIndex = index;
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            ShowItem(PnlHovered, e);
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if(e.Button == MouseButtons.Left) ShowItem(PnlSelected, e);
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            HoveredIndex = SelectedIndex;
        }

        public event EventHandler SelectIndexChanged;

        public event EventHandler HoverIndexChanged;

        private int selectIndex;
        public int SelectedIndex
        {
            get => selectIndex;
            set
            {
                if(selectIndex == value) return;
                HoveredIndex = value;
                RefreshItem(PnlSelected, value);
                selectIndex = value;
                SelectIndexChanged?.Invoke(this, null);
            }
        }

        private int hoverIndex;
        public int HoveredIndex
        {
            get => hoverIndex;
            set
            {
                if(hoverIndex == value) return;
                RefreshItem(PnlHovered, value);
                hoverIndex = value;
                HoverIndexChanged?.Invoke(this, null);
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/MyStatusBar.cs
================================================
using BluePointLilac.Methods;
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public sealed class MyStatusBar : Panel
    {
        public static readonly string DefaultText = $"Ver: {Application.ProductVersion}    {Application.CompanyName}";

        public MyStatusBar()
        {
            this.Text = DefaultText;
            this.Height = 30.DpiZoom();
            this.Dock = DockStyle.Bottom;
            this.Font = SystemFonts.StatusFont;
            this.BackColor = Color.FromArgb(70, 130, 200);
            this.ForeColor = Color.White;
        }

        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]
        public override string Text { get => base.Text; set => base.Text = value; }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            string txt = this.Text;
            int left = this.Height / 3;
            for(int i = this.Text.Length - 1; i >= 0; i--)
            {
                Size size = TextRenderer.MeasureText(txt, this.Font);
                if(size.Width < ClientSize.Width - 2 * left)
                {
                    using(Brush brush = new SolidBrush(this.ForeColor))
                    {
                        int top = (this.Height - size.Height) / 2;
                        e.Graphics.Clear(this.BackColor);
                        e.Graphics.DrawString(txt, this.Font, brush, left, top);
                        break;
                    }
                }
                txt = this.Text.Substring(0, i) + "...";
            }
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e); this.Refresh();
        }
        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e); this.Refresh();
        }
        protected override void OnFontChanged(EventArgs e)
        {
            base.OnFontChanged(e); this.Refresh();
        }
        protected override void OnForeColorChanged(EventArgs e)
        {
            base.OnForeColorChanged(e); this.Refresh();
        }
        protected override void OnBackColorChanged(EventArgs e)
        {
            base.OnBackColorChanged(e); this.Refresh();
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/MyToolBar.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public sealed class MyToolBar : FlowLayoutPanel
    {
        public MyToolBar()
        {
            this.Height = 80.DpiZoom();
            this.Dock = DockStyle.Top;
            this.DoubleBuffered = true;
            this.BackColor = Color.FromArgb(85, 145, 215);
        }

        private MyToolBarButton selectedButton;
        public MyToolBarButton SelectedButton
        {
            get => selectedButton;
            set
            {
                if(selectedButton == value) return;
                if(selectedButton != null)
                {
                    selectedButton.Opacity = 0;
                    selectedButton.Cursor = Cursors.Hand;
                }
                selectedButton = value;
                if(selectedButton != null)
                {
                    selectedButton.Opacity = 0.4F;
                    selectedButton.Cursor = Cursors.Default;
                }
                SelectedButtonChanged?.Invoke(this, null);
            }
        }

        public event EventHandler SelectedButtonChanged;

        public int SelectedIndex
        {
            get
            {
                if(SelectedButton == null) return -1;
                else return Controls.GetChildIndex(SelectedButton);
            }
            set
            {
                if(value < 0 || value >= this.Controls.Count) SelectedButton = null;
                else SelectedButton = (MyToolBarButton)Controls[value];
            }
        }

        public void AddButton(MyToolBarButton button)
        {
            this.SuspendLayout();
            button.Parent = this;
            button.Margin = new Padding(12, 4, 0, 0).DpiZoom();
            button.MouseDown += (sender, e) =>
            {
                if(e.Button == MouseButtons.Left && button.CanBeSelected) SelectedButton = button;
            };
            button.MouseEnter += (sender, e) =>
            {
                if(button != SelectedButton) button.Opacity = 0.2F;
            };
            button.MouseLeave += (sender, e) =>
            {
                if(button != SelectedButton) button.Opacity = 0;
            };
            this.ResumeLayout();
        }

        public void AddButtons(MyToolBarButton[] buttons)
        {
            int maxWidth = 72.DpiZoom();
            Array.ForEach(buttons, button => maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(button.Text, button.Font).Width));
            Array.ForEach(buttons, button => { button.Width = maxWidth; AddButton(button); });
        }
    }

    public sealed class MyToolBarButton : Panel
    {
        public MyToolBarButton(Image image, string text)
        {
            this.SuspendLayout();
            this.DoubleBuffered = true;
            this.Cursor = Cursors.Hand;
            this.Size = new Size(72, 72).DpiZoom();
            this.Controls.AddRange(new Control[] { picImage, lblText });
            lblText.Resize += (sender, e) => this.OnResize(null);
            picImage.Top = 6.DpiZoom();
            lblText.Top = 52.DpiZoom();
            lblText.SetEnabled(false);
            this.Image = image;
            this.Text = text;
            this.ResumeLayout();
        }

        readonly PictureBox picImage = new PictureBox
        {
            SizeMode = PictureBoxSizeMode.StretchImage,
            Size = new Size(40, 40).DpiZoom(),
            BackColor = Color.Transparent,
            Enabled = false
        };

        readonly Label lblText = new Label
        {
            BackColor = Color.Transparent,
            Font = SystemFonts.MenuFont,
            ForeColor = Color.White,
            AutoSize = true,
        };

        public Image Image
        {
            get => picImage.Image;
            set => picImage.Image = value;
        }
        public new string Text
        {
            get => lblText.Text;
            set => lblText.Text = value;
        }
        public float Opacity
        {
            get => BackColor.A / 255;
            set => BackColor = Color.FromArgb((int)(value * 255), Color.White);
        }
        public bool CanBeSelected { get; set; } = true;

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            lblText.Left = (this.Width - lblText.Width) / 2;
            picImage.Left = (this.Width - picImage.Width) / 2;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/PictureButton.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public class PictureButton : PictureBox
    {
        public PictureButton(Image image)
        {
            this.BaseImage = image;
            this.SizeMode = PictureBoxSizeMode.AutoSize;
            this.Cursor = Cursors.Hand;
        }

        private Image baseImage;
        public Image BaseImage
        {
            get => baseImage;
            set
            {
                baseImage = value;
                this.Image = ToolStripRenderer.CreateDisabledImage(value);
            }
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e); this.Image = BaseImage;
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            this.Image = ToolStripRenderer.CreateDisabledImage(BaseImage);
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if(e.Button == MouseButtons.Left) base.OnMouseDown(e);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/ReadOnlyTextBox.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public sealed class ReadOnlyTextBox : TextBox
    {
        public ReadOnlyTextBox()
        {
            this.ReadOnly = true;
            this.Multiline = true;
            this.ShortcutsEnabled = false;
            this.BackColor = Color.White;
            this.ForeColor = Color.FromArgb(80, 80, 80);
            this.Font = SystemFonts.MenuFont;
            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);
        }

        const int WM_SETFOCUS = 0x0007;
        const int WM_KILLFOCUS = 0x0008;
        protected override void WndProc(ref Message m)
        {
            switch(m.Msg)
            {
                case WM_SETFOCUS:
                    m.Msg = WM_KILLFOCUS; break;
            }
            base.WndProc(ref m);
        }

        private bool firstEnter = true;

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            if(firstEnter) this.Focus();
            firstEnter = false;
        }
    }

    public sealed class ReadOnlyRichTextBox : RichTextBox
    {
        public ReadOnlyRichTextBox()
        {
            this.ReadOnly = true;
            this.Dock = DockStyle.Fill;
            this.BackColor = Color.White;
            this.BorderStyle = BorderStyle.None;
            this.ForeColor = Color.FromArgb(80, 80, 80);
            this.Font = SystemFonts.MenuFont;
            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);
        }

        const int WM_SETFOCUS = 0x0007;
        const int WM_KILLFOCUS = 0x0008;

        protected override void WndProc(ref Message m)
        {
            switch(m.Msg)
            {
                case WM_SETFOCUS:
                    m.Msg = WM_KILLFOCUS; break;
            }
            base.WndProc(ref m);
        }

        private bool firstEnter = true;

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            if(firstEnter) this.Focus();
            firstEnter = false;
        }

        protected override void OnLinkClicked(LinkClickedEventArgs e)
        {
            base.OnLinkClicked(e);
            ExternalProgram.OpenWebUrl(e.LinkText);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/ResizeLimitedForm.cs
================================================
using System;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    /// <summary>限制水平、竖直方向调整大小的窗体</summary>
    public class ResizeLimitedForm : Form
    {
        /// <summary>水平方向可调整大小</summary>
        public bool HorizontalResizable { get; set; } = true;

        /// <summary>竖直方向可调整大小</summary>
        public bool VerticalResizable { get; set; } = true;

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if(m.Msg == WM_NCHITTEST && this.WindowState == FormWindowState.Normal)
            {
                IntPtr hNowhere = new IntPtr((int)HitTest.Nowhere);
                switch((HitTest)m.Result)
                {
                    case HitTest.Top:
                    case HitTest.Bottom:
                        if(!VerticalResizable) m.Result = hNowhere;
                        break;
                    case HitTest.Left:
                    case HitTest.Right:
                        if(!HorizontalResizable) m.Result = hNowhere;
                        break;
                    case HitTest.TopLeft:
                    case HitTest.TopRight:
                    case HitTest.BottomLeft:
                    case HitTest.BottomRight:
                        if(!VerticalResizable || !HorizontalResizable) m.Result = hNowhere;
                        break;
                }
            }
        }

        const int WM_NCHITTEST = 0x84;//光标移动或鼠标按下、释放时的消息
        /// <summary>鼠标击中位置</summary>
        enum HitTest : int
        {
            Error = -2,
            Transparent = -1,
            Nowhere = 0,
            Client = 1,
            TitleBar = 2,
            SysMenu = 3,
            Size = 4,
            GrowBox = 5,
            Hscroll = 6,
            Vscroll = 7,
            MinButton = 8,
            MaxButton = 9,
            Left = 10,
            Right = 11,
            Top = 12,
            TopLeft = 13,
            TopRight = 14,
            Bottom = 15,
            BottomLeft = 16,
            BottomRight = 17,
            Border = 18,
            Close = 20,
            Help = 21
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/SelectDialog.cs
================================================
using BluePointLilac.Methods;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Controls
{
    public class SelectDialog : CommonDialog
    {
        public string Title { get; set; }
        public string Selected { get; set; }
        public int SelectedIndex { get; set; }
        public string[] Items { get; set; }
        public bool CanEdit { get; set; }

        public override void Reset() { }

        protected override bool RunDialog(IntPtr hwndOwner)
        {
            using(SelectForm frm = new SelectForm())
            {
                frm.Text = this.Title;
                frm.Items = this.Items;
                if(this.Selected != null) frm.Selected = this.Selected;
                else frm.SelectedIndex = this.SelectedIndex;
                frm.CanEdit = this.CanEdit;
                Form owner = (Form)Control.FromHandle(hwndOwner);
                if(owner != null) frm.TopMost = owner.TopMost;
                bool flag = frm.ShowDialog() == DialogResult.OK;
                if(flag)
                {
                    this.Selected = frm.Selected;
                    this.SelectedIndex = frm.SelectedIndex;
                }
                return flag;
            }
        }

        sealed class SelectForm : Form
        {
            public SelectForm()
            {
                this.SuspendLayout();
                this.AcceptButton = btnOK;
                this.CancelButton = btnCancel;
                this.Font = SystemFonts.MenuFont;
                this.ShowIcon = this.ShowInTaskbar = false;
                this.MaximizeBox = this.MinimizeBox = false;
                this.FormBorderStyle = FormBorderStyle.FixedSingle;
                this.StartPosition = FormStartPosition.CenterParent;
                this.InitializeComponents();
                this.ResumeLayout();
            }

            public string Selected
            {
                get => cmbItems.Text;
                set => cmbItems.Text = value;
            }

            public string[] Items
            {
                get
                {
                    string[] value = new string[cmbItems.Items.Count];
                    cmbItems.Items.CopyTo(value, 0);
                    return value;
                }
                set
                {
                    cmbItems.Items.Clear();
                    cmbItems.Items.AddRange(value);
                }
            }

            public bool CanEdit
            {
                get => cmbItems.DropDownStyle == ComboBoxStyle.DropDown;
                set => cmbItems.DropDownStyle = value ? ComboBoxStyle.DropDown : ComboBoxStyle.DropDownList;
            }

            public int SelectedIndex
            {
                get => cmbItems.SelectedIndex;
                set => cmbItems.SelectedIndex = value;
            }

            readonly Button btnOK = new Button
            {
                DialogResult = DialogResult.OK,
                Text = ResourceString.OK,
                AutoSize = true
            };
            readonly Button btnCancel = new Button
            {
                DialogResult = DialogResult.Cancel,
                Text = ResourceString.Cancel,
                AutoSize = true
            };
            readonly ComboBox cmbItems = new ComboBox
            {
                AutoCompleteMode = AutoCompleteMode.SuggestAppend,
                AutoCompleteSource = AutoCompleteSource.ListItems,
                DropDownHeight = 294.DpiZoom(),
                ImeMode = ImeMode.Disable
            };

            private void InitializeComponents()
            {
                this.Controls.AddRange(new Control[] { cmbItems, btnOK, btnCancel });
                int a = 20.DpiZoom();
                cmbItems.Left = a;
                cmbItems.Width = 85.DpiZoom();
                cmbItems.Top = btnOK.Top = btnCancel.Top = a;
                btnOK.Left = cmbItems.Right + a;
                btnCancel.Left = btnOK.Right + a;
                this.ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);
                cmbItems.AutosizeDropDownWidth();
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Controls/UAWebClient.cs
================================================
using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml;

namespace BluePointLilac.Controls
{
    public sealed class UAWebClient : WebClient
    {
        public UAWebClient()
        {
            //此类主要为了解决访问Github的一些问题
            //请求被中止: 未能创建 SSL/TLS 安全通道; 基础连接已经关闭: 发送时发生错误,一般添加TLS12即可
            //TLS12------0xc00,TLS11------0x300,TLS------0xc0,SSL------0x30;
            ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc00 | 0x300 | 0xc0 | 0x30);
            //网络传输默认文本编码 UTF-8
            this.Encoding = Encoding.UTF8;
            //远程服务器返回错误: (403) 已禁止
            //浏览器 F12 console 输入 console.log(navigator.userAgent); 获取 User Agent
            this.Headers.Add("User-Agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " +
                "Chrome/90.0.4430.212 Safari/537.36 Edg/90.0.818.66");
        }

        /// <summary>获取网页文本</summary>
        public string GetWebString(string url)
        {
            try
            {
                string str = this.DownloadString(url);
                str = str?.Replace("\n", Environment.NewLine);//换行符转换
                return str;
            }
            catch { return null; }
        }

        /// <summary>将网络文本写入本地文件</summary>
        /// <param name="filePath">本地文件路径</param>
        /// <param name="fileUrl">网络文件Raw路径</param>
        public bool WebStringToFile(string filePath, string fileUrl)
        {
            string contents = GetWebString(fileUrl);
            bool flag = contents != null;
            if(flag) File.WriteAllText(filePath, contents, Encoding.Unicode);
            return flag;
        }

        /// <summary>获取网页Json文本并加工为Xml</summary>
        public XmlDocument GetWebJsonToXml(string url)
        {
            try
            {
                byte[] bytes = this.DownloadData(url);
                using(XmlReader xReader = JsonReaderWriterFactory.CreateJsonReader(bytes, XmlDictionaryReaderQuotas.Max))
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(xReader);
                    return doc;
                }
            }
            catch { return null; }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs
================================================
using System;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class ComboBoxExtension
    {
        public static void AutosizeDropDownWidth(this ComboBox box)
        {
            box.DropDown += (sender, e) =>
            {
                int maxWidth = 0;
                foreach(var item in box.Items)
                {
                    maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(item.ToString(), box.Font).Width);
                }
                maxWidth = Math.Max(maxWidth, box.Width);
                box.DropDownWidth = maxWidth;
            };
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ControlExtension.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class ControlExtension
    {
        [DllImport("user32.dll")]
        private static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);

        [DllImport("user32.dll")]
        private static extern bool ReleaseCapture();

        /// <summary>使控件能够移动所属窗体</summary>
        /// <param name="ctr">目标控件</param>
        public static void CanMoveForm(this Control ctr)
        {
            const int WM_NCLBUTTONDOWN = 0xA1;
            const int HT_CAPTION = 0x2;
            ctr.MouseMove += (sender, e) =>
            {
                if(e.Button != MouseButtons.Left) return;
                ReleaseCapture();
                PostMessage(ctr.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
            };
        }

        [DllImport("user32.dll")]
        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc);

        [DllImport("user32.dll")]
        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        /// <summary>通过Win32API禁用/启用目标控件</summary>
        /// <remarks>控件被禁用时仍可更改字体颜色,不需要同时设置ctr.Enabled=false</remarks>
        /// <param name="ctr">目标控件</param>
        /// <param name="enabled">启用为true,禁用为false</param>
        public static void SetEnabled(this Control ctr, bool enabled)
        {
            const int GWL_STYLE = -16;
            const int WS_DISABLED = 0x8000000;
            int value = GetWindowLong(ctr.Handle, GWL_STYLE);
            if(enabled) value &= ~WS_DISABLED;
            else value |= WS_DISABLED;
            SetWindowLong(ctr.Handle, GWL_STYLE, value);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/DirectoryEx.cs
================================================
using System.IO;

namespace BluePointLilac.Methods
{
    public static class DirectoryEx
    {
        public static void CopyTo(string srcDirPath, string dstDirPath)
        {
            DirectoryInfo srcDi = new DirectoryInfo(srcDirPath);
            DirectoryInfo dstDi = new DirectoryInfo(dstDirPath);
            dstDi.Create();
            foreach(FileInfo srcFi in srcDi.GetFiles())
            {
                string dstFilePath = $@"{dstDirPath}\{srcFi.Name}";
                srcFi.CopyTo(dstFilePath, true);
            }
            foreach(DirectoryInfo srcSubDi in srcDi.GetDirectories())
            {
                DirectoryInfo dstSubDi = dstDi.CreateSubdirectory(srcSubDi.Name);
                CopyTo(srcSubDi.FullName, dstSubDi.FullName);
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs
================================================
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    /// 代码用途:管理员UAC进程窗口拖放文件
    /// 代码来源1:https://zhuanlan.zhihu.com/p/48735364
    /// 代码来源2:https://github.com/volschin/sdimager/blob/master/ElevatedDragDropManager.cs
    /// 代码作者:雨少主(知乎)、volschin(Github)、蓝点lilac(转载、修改)
    /// 调用方法:var droper = new ElevatedFileDroper(control);
    /// droper.DragDrop += (sender, e) => MessageBox.Show(droper.DropFilePaths[0]);
    /// 备注:此类只能生效一个实例,不能将control.AllowDrop设为true,droper.DragDrop与control.DragDrop不共存

    public sealed class ElevatedFileDroper : IMessageFilter
    {
        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint message, ChangeFilterAction action, in ChangeFilterStruct pChangeFilterStruct);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags);

        [DllImport("shell32.dll", SetLastError = false)]
        private static extern void DragAcceptFiles(IntPtr hWnd, bool fAccept);

        [DllImport("shell32.dll", SetLastError = false, CharSet = CharSet.Unicode)]
        private static extern uint DragQueryFile(IntPtr hWnd, uint iFile, StringBuilder lpszFile, int cch);

        [DllImport("shell32.dll", SetLastError = false)]
        private static extern bool DragQueryPoint(IntPtr hDrop, out Point lppt);

        [DllImport("shell32.dll", SetLastError = false)]
        private static extern void DragFinish(IntPtr hDrop);

        [StructLayout(LayoutKind.Sequential)]
        struct ChangeFilterStruct
        {
            public uint CbSize;
            public ChangeFilterStatu ExtStatus;
        }

        enum ChangeWindowMessageFilterFlags : uint
        {
            MSGFLT_ADD = 1,
            MSGFLT_REMOVE = 2
        }

        enum ChangeFilterAction : uint
        {
            MSGFLT_RESET,
            MSGFLT_ALLOW,
            MSGFLT_DISALLOW
        }

        enum ChangeFilterStatu : uint
        {
            MSGFLTINFO_NONE,
            MSGFLTINFO_ALREADYALLOWED_FORWND,
            MSGFLTINFO_ALREADYDISALLOWED_FORWND,
            MSGFLTINFO_ALLOWED_HIGHER
        }

        const uint WM_COPYGLOBALDATA = 0x0049;
        const uint WM_COPYDATA = 0x004A;
        const uint WM_DROPFILES = 0x0233;

        public event EventHandler DragDrop;
        public string[] DropFilePaths { get; private set; }
        public Point DropPoint { get; private set; }

        public ElevatedFileDroper(Control ctr)
        {
            ctr.AllowDrop = false;
            DragAcceptFiles(ctr.Handle, true);
            Application.AddMessageFilter(this);
            ctr.Disposed += (sender, e) => Application.RemoveMessageFilter(this);

            if(ctr is Form frm)
            {
                double opacity = frm.Opacity;
                frm.Paint += (sender, e) =>
                {
                    if(frm.Opacity != opacity)
                    {
                        //窗体透明度变化时需要重新注册接受文件拖拽标识符
                        DragAcceptFiles(ctr.Handle, true);
                        opacity = frm.Opacity;
                    }
                };
            }

            Version ver = Environment.OSVersion.Version;
            bool isVistaOrHigher = ver >= new Version(6, 0);
            bool isWin7OrHigher = ver >= new Version(6, 1);
            var status = new ChangeFilterStruct { CbSize = 8 };
            if(isVistaOrHigher)
            {
                foreach(uint msg in new[] { WM_DROPFILES, WM_COPYGLOBALDATA, WM_COPYDATA })
                {
                    bool error = false;
                    if(isWin7OrHigher)
                    {
                        error = !ChangeWindowMessageFilterEx(ctr.Handle, msg, ChangeFilterAction.MSGFLT_ALLOW, in status);
                    }
                    else
                    {
                        error = !ChangeWindowMessageFilter(msg, ChangeWindowMessageFilterFlags.MSGFLT_ADD);
                    }
                    if(error) throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
        }

        public bool PreFilterMessage(ref Message m)
        {
            if(m.Msg != WM_DROPFILES) return false;
            IntPtr handle = m.WParam;
            uint fileCount = DragQueryFile(handle, uint.MaxValue, null, 0);
            string[] filePaths = new string[fileCount];
            for(uint i = 0; i < fileCount; i++)
            {
                StringBuilder sb = new StringBuilder(260);
                uint result = DragQueryFile(handle, i, sb, sb.Capacity);
                if(result > 0) filePaths[i] = sb.ToString();
            }
            DragQueryPoint(handle, out Point point);
            DragFinish(handle);
            DropPoint = point;
            DropFilePaths = filePaths;
            DragDrop?.Invoke(this, null);
            return true;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/EncodingType.cs
================================================
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace BluePointLilac.Methods
{
    /* 获取文本文件编码类型
     * 代码参考:https://www.cnblogs.com/guyun/p/4262587.html (Napoléon)*/
    public static class EncodingType
    {
        /// <summary>各种带BOM的编码BOM值</summary>
        private static readonly Dictionary<byte[], Encoding> EncodingBomBytes = new Dictionary<byte[], Encoding>
        {
            { new byte[] { 0xEF, 0xBB, 0xBF }, Encoding.UTF8 },                         //UTF-8         EF BB BF
            { new byte[] { 0xFF, 0xFE, 0x00, 0x00 }, Encoding.UTF32 },                  //UTF-32LE      FF FE 00 00
            { new byte[] { 0xFF, 0xFE }, Encoding.Unicode },                            //UTF-16LE      FF FE
            { new byte[] { 0xFE, 0xFF }, Encoding.BigEndianUnicode },                   //UTF-16BE      FE FF
            { new byte[] { 0x2B, 0x2F, 0x76 }, Encoding.UTF7 },                         //UTF-7         2B 2F 76
            { new byte[] { 0x00, 0x00, 0xFE, 0xFF }, new UTF32Encoding(true, true) },   //UTF-32BE      00 00 FE FF
        };

        /// <summary>获取给定的文件的编码类型</summary> 
        /// <param name=“filePath“>文件路径</param> 
        /// <returns>文件的编码类型</returns> 
        public static Encoding GetType(string filePath)
        {
            byte[] fs = File.ReadAllBytes(filePath);
            foreach(var kv in EncodingBomBytes)
            {
                if(fs.Length < kv.Key.Length) continue;
                int i = -1;
                bool flag = kv.Key.All(s => { i++; return s == fs[i]; });
                if(flag) return kv.Value;
            }
            if(IsUTF8Bytes(fs)) return Encoding.UTF8; //不带BOM的UTF-8
            return Encoding.Default;
        }

        /// <summary>判断是否是不带 BOM 的 UTF8 格式</summary> 
        /// <param name=“bytes“></param> 
        private static bool IsUTF8Bytes(byte[] bytes)
        {
            int count = 1; //计算当前正分析的字符应还有的字节数 
            for(int i = 0; i < bytes.Length; i++)
            {
                byte curByte = bytes[i];//当前分析的字节. 
                if(count == 1)
                {
                    if(curByte >= 0x80)
                    {
                        //判断当前 
                        while(((curByte <<= 1) & 0x80) != 0) count++;
                        //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X 
                        if(count == 1 || count > 6) return false;
                    }
                }
                else
                {
                    //若是UTF-8 此时第一位必须为1 
                    if((curByte & 0xC0) != 0x80) return false;
                    else count--;
                }
            }
            //if(count > 1) throw new Exception("非预期的byte格式");
            return true;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs
================================================
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace BluePointLilac.Methods
{
    /// <summary>外部程序</summary>
    public static class ExternalProgram
    {
        /// <summary>在Regedit中跳转指定路径并定位指定键名</summary>
        /// <param name="regPath">注册表项路径</param>
        /// <param name="valueName">注册表键名</param>
        /// <param name="moreOpen">窗口是否多开</param>
        public static void JumpRegEdit(string regPath, string valueName = null, bool moreOpen = false)
        {
            //还有一种方法,修改HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit
            //中的LastKey键值(记录上次关闭注册表编辑器时的注册表路径)为要跳转的注册表项路径regPath,
            //再使用Process.Start("regedit.exe", "-m")打开注册表编辑器
            //优点:代码少、不会有Bug。缺点:不能定位具体键,没有逐步展开效果
            if(regPath == null) return;
            Process process;
            IntPtr hMain = FindWindow("RegEdit_RegEdit", null);
            if(hMain != IntPtr.Zero && !moreOpen)
            {
                GetWindowThreadProcessId(hMain, out int id);
                process = Process.GetProcessById(id);
            }
            else
            {
                //注册表编辑器窗口多开
                process = Process.Start("regedit.exe", "-m");
                process.WaitForInputIdle();
                hMain = process.MainWindowHandle;
            }

            ShowWindowAsync(hMain, SW_SHOWNORMAL);
            SetForegroundWindow(hMain);
            IntPtr hTree = FindWindowEx(hMain, IntPtr.Zero, "SysTreeView32", null);
            IntPtr hList = FindWindowEx(hMain, IntPtr.Zero, "SysListView32", null);

            SetForegroundWindow(hTree);
            SetFocus(hTree);
            process.WaitForInputIdle();
            SendMessage(hTree, WM_KEYDOWN, VK_HOME, null);
            Thread.Sleep(100);
            process.WaitForInputIdle();
            SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);
            foreach(char chr in Encoding.Default.GetBytes(regPath))
            {
                process.WaitForInputIdle();
                if(chr == '\\')
                {
                    Thread.Sleep(100);
                    SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);
                }
                else
                {
                    SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null);
                }
            }

            if(string.IsNullOrEmpty(valueName)) return;
            using(RegistryKey key = RegistryEx.GetRegistryKey(regPath))
            {
                if(key?.GetValue(valueName) == null) return;
            }
            Thread.Sleep(100);
            SetForegroundWindow(hList);
            SetFocus(hList);
            process.WaitForInputIdle();
            SendMessage(hList, WM_KEYDOWN, VK_HOME, null);
            foreach(char chr in Encoding.Default.GetBytes(valueName))
            {
                process.WaitForInputIdle();
                SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null);
            }
            process.Dispose();
        }

        /// <summary>在Explorer中选中指定文件或文件夹</summary>
        /// <param name="filePath">文件或文件夹路径</param>
        /// <param name="moreOpen">窗口是否多开</param>
        public static void JumpExplorer(string filePath, bool moreOpen = false)
        {
            if(filePath == null) return;
            if(!moreOpen)
            {
                IntPtr pidlList = ILCreateFromPathW(filePath);
                if(pidlList == IntPtr.Zero) return;
                SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0);
                ILFree(pidlList);
            }
            else
            {
                using(Process process = new Process())
                {
                    process.StartInfo.FileName = "explorer.exe";
                    process.StartInfo.Arguments = $"/select, {filePath}";
                    process.Start();
                }
            }
        }

        /// <summary>在Explorer中打开指定目录</summary>
        /// <param name="dirPath">目录路径</param>
        public static void OpenDirectory(string dirPath)
        {
            if(!Directory.Exists(dirPath)) return;
            using(Process process = new Process())
            {
                process.StartInfo.FileName = dirPath;
                process.Start();
            }
        }

        /// <summary>打开文件或文件夹的属性对话框</summary>
        /// <param name="filePath">文件或文件夹路径</param>
        public static bool ShowPropertiesDialog(string filePath)
        {
            SHELLEXECUTEINFO info = new SHELLEXECUTEINFO
            {
                lpVerb = "Properties",
                //显示详细信息选项卡, 此处有语言差异
                //lpParameters = ResourceString.GetDirectString("@shell32.dll,-31433"),//"详细信息",
                lpFile = filePath,
                nShow = SW_SHOW,
                fMask = SEE_MASK_INVOKEIDLIST,
                cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO))
            };
            return ShellExecuteEx(ref info);
        }

        /// <summary>打开指定未关联打开方式的扩展名的打开方式对话框</summary>
        /// <param name="extension">文件扩展名</param>
        public static void ShowOpenWithDialog(string extension)
        {
            //Win10 调用 SHOpenWithDialog API 或调用 OpenWith.exe -override "%1"
            //或调用 rundll32.exe shell32.dll,OpenAs_RunDLL %1 能显示打开方式对话框,但都不能设置默认应用
            //以下方法只针对未关联打开方式的扩展名显示系统打开方式对话框,对于已关联打开方式的扩展名会报错
            string tempPath = $"{Path.GetTempPath()}{Guid.NewGuid()}{extension}";
            File.WriteAllText(tempPath, "");
            using(Process process = new Process())
            {
                process.StartInfo = new ProcessStartInfo
                {
                    UseShellExecute = true,
                    FileName = tempPath,
                    Verb = "openas"
                };
                process.Start();
            }
            File.Delete(tempPath);
        }

        /// <summary>重启Explorer</summary>
        public static void RestartExplorer()
        {
            using(Process process = new Process())
            {
                //有些系统有tskill.exe可以直接调用tskill explorer命令
                process.StartInfo = new ProcessStartInfo
                {
                    FileName = "taskkill.exe",
                    Arguments = "-f -im explorer.exe",
                    WindowStyle = ProcessWindowStyle.Hidden
                };
                process.Start();
                process.WaitForExit();
                process.StartInfo = new ProcessStartInfo("explorer.exe");
                process.Start();
            }
        }

        /// <summary>调用默认浏览器打开指定网址</summary>
        /// <param name="url">网址</param>
        public static void OpenWebUrl(string url)
        {
            if(url == null) return;
            //替换网址转义符
            url = url.Replace("%", "%25").Replace("#", "%23").Replace("&", "%26").Replace("+", "%2B");
            using(Process process = new Process())
            {
                //通过explorer来调用默认浏览器打开链接,避免管理员权限影响
                process.StartInfo = new ProcessStartInfo($"\"{url}\"");
                process.Start();
            }
        }

        /// <summary>导出指定注册表项的.reg文件</summary>
        /// <param name="regPath">注册表项路径</param>
        /// <param name="filePath">.reg文件保存路径</param>
        public static void ExportRegistry(string regPath, string filePath)
        {
            using(Process process = new Process())
            {
                process.StartInfo.FileName = "regedit.exe";
                process.StartInfo.Arguments = $"/e \"{filePath}\" \"{regPath}\"";
                process.Start();
                process.WaitForExit();
            }
        }

        /// <summary>打开记事本显示指定文本</summary>
        /// <param name="text">要显示的文本</param>
        public static void OpenNotepadWithText(string text)
        {
            using(Process process = Process.Start("notepad.exe"))
            {
                process.WaitForInputIdle();
                IntPtr handle = FindWindowEx(process.MainWindowHandle, IntPtr.Zero, "Edit", null);
                SendMessage(handle, WM_SETTEXT, 0, text);
            }
        }

        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOW = 5;
        private const uint SEE_MASK_INVOKEIDLIST = 12;
        private const int WM_SETTEXT = 0xC;
        private const int WM_KEYDOWN = 0x100;
        private const int WM_CHAR = 0x102;
        private const int VK_HOME = 0x24;
        private const int VK_RIGHT = 0x27;

        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport("user32.dll")]
        private static extern bool SetFocus(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);

        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpszClass, string lpszWindow);

        [DllImport("user32.dll")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChild, string lpszClass, string lpszWindow);

        [DllImport("user32.dll")]
        private static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);

        [DllImport("shell32.dll", ExactSpelling = true)]
        private static extern void ILFree(IntPtr pidlList);

        [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
        private static extern IntPtr ILCreateFromPathW(string pszPath);

        [DllImport("shell32.dll", ExactSpelling = true)]
        private static extern IntPtr SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);

        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        private static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct SHELLEXECUTEINFO
        {
            public int cbSize;
            public uint fMask;
            public IntPtr hwnd;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpVerb;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpFile;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpParameters;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpDirectory;
            public int nShow;
            public IntPtr hInstApp;
            public IntPtr lpIDList;
            [MarshalAs(UnmanagedType.LPTStr)]
            public string lpClass;
            public IntPtr hkeyClass;
            public uint dwHotKey;
            public IntPtr hIcon;
            public IntPtr hProcess;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/FileExtension.cs
================================================
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace BluePointLilac.Methods
{
    public static class FileExtension
    {
        [Flags]
        enum AssocF
        {
            Init_NoRemapCLSID = 0x1,
            Init_ByExeName = 0x2,
            Open_ByExeName = 0x2,
            Init_DefaultToStar = 0x4,
            Init_DefaultToFolder = 0x8,
            NoUserSettings = 0x10,
            NoTruncate = 0x20,
            Verify = 0x40,
            RemapRunDll = 0x80,
            NoFixUps = 0x100,
            IgnoreBaseClass = 0x200
        }

        public enum AssocStr
        {
            Command = 1,
            Executable,
            FriendlyDocName,
            FriendlyAppName,
            NoOpen,
            ShellNewValue,
            DDECommand,
            DDEIfExec,
            DDEApplication,
            DDETopic
        }

        [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref uint pcchOut);

        public const string FILEEXTSPATH = @"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts";
        private const string HKCRCLASSES = @"HKEY_CURRENT_USER\SOFTWARE\Classes";
        private const string HKLMCLASSES = @"HKEY_LOCAL_MACHINE\SOFTWARE\Classes";

        public static string GetExtentionInfo(AssocStr assocStr, string extension)
        {
            uint pcchOut = 0;
            AssocQueryString(AssocF.Verify, assocStr, extension, null, null, ref pcchOut);
            StringBuilder pszOut = new StringBuilder((int)pcchOut);
            AssocQueryString(AssocF.Verify, assocStr, extension, null, pszOut, ref pcchOut);
            return pszOut.ToString();
        }

        public static string GetOpenMode(string extension)
        {
            if(string.IsNullOrEmpty(extension)) return null;
            string mode;
            bool CheckMode()
            {
                if(mode.IsNullOrWhiteSpace()) return false;
                if(mode.Length > 255) return false;
                if(mode.ToLower().StartsWith(@"applications\")) return false;
                using(RegistryKey root = Registry.ClassesRoot)
                using(RegistryKey key = root.OpenSubKey(mode))
                {
                    return key != null;
                }
            }
            mode = Registry.GetValue($@"{FILEEXTSPATH}\{extension}\UserChoice", "ProgId", null)?.ToString();
            if(CheckMode()) return mode;
            mode = Registry.GetValue($@"{HKLMCLASSES}\{extension}", "", null)?.ToString();
            if(CheckMode()) return mode;
            mode = Registry.GetValue($@"{HKCRCLASSES}\{extension}", "", null)?.ToString();
            if(CheckMode()) return mode;
            return null;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/FormExtension.cs
================================================
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class FormExtension
    {
        /// <summary>移动窗体时同时移动另一个窗体</summary>
        /// <param name="frm1">主动移动的窗体</param>
        /// <param name="frm2">同时被移动的窗体</param>
        public static void MoveAsMove(this Form frm1, Form frm2)
        {
            if(frm2 == null) return;
            Point pLast = Point.Empty;
            frm1.Load += (sender, e) => pLast = frm1.Location;
            frm1.LocationChanged += (sender, e) =>
            {
                if(pLast == Point.Empty) return;
                frm2.Left += frm1.Left - pLast.X;
                frm2.Top += frm1.Top - pLast.Y;
                pLast = frm1.Location;
            };
        }

        /// <summary>给窗体添加ESC键关闭功能</summary>
        /// <param name="frm">指定窗口</param>
        /// <param name="dr">关闭窗口时的对话框返回值</param>
        /// <remarks>也可以重写Form的ProcessDialogKey事件,
        /// 这个方法更简单,但遍历窗体控件时切记多了一个不可见的关闭按钮</remarks>
        public static void AddEscapeButton(this Form frm, DialogResult dr = DialogResult.Cancel)
        {
            Button btn = new Button
            {
                Parent = frm,
                Size = Size.Empty,
                DialogResult = dr
            };
            frm.CancelButton = btn;
            frm.Disposed += (sender, e) => btn.Dispose();
            frm.FormClosing += (sender, e) => btn.PerformClick();
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/GuidEx.cs
================================================
using System;
using System.Text.RegularExpressions;

namespace BluePointLilac.Methods
{
    //为兼容.Net Framework 3.5,无法引用Microsoft.CSharp.dll(中的Guid.TryParse)写了这个扩展方法
    public static class GuidEx
    {
        public static bool TryParse(string str, out Guid guid)
        {
            if(IsGuid(str))
            {
                guid = new Guid(str);
                return true;
            }
            else
            {
                guid = Guid.Empty;
                return false;
            }
        }

        private static readonly Regex GuidRegex = new Regex(@"[A-F0-9]{8}(\-[A-F0-9]{4}){3}\-[A-F0-9]{12}", RegexOptions.IgnoreCase);

        public static bool IsGuid(string str)
        {
            if(string.IsNullOrEmpty(str)) return false;
            if(str.Length == 38 && str.StartsWith("{") && str.EndsWith("}") && GuidRegex.IsMatch(str)) return true;
            if(str.Length == 36 && GuidRegex.IsMatch(str)) return true;
            return false;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/HighDpi.cs
================================================
using System.Drawing;
using System.Windows;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    /// <summary>处理不同DPI缩放比下的像素绘制和字体显示问题</summary>
    /// <remarks>使用此类需要添加引用 PresentationFramework
    /// 还应在配置清单App.manifest中启用DPI感知自动缩放
    /// Font为矢量类型,Point、Size、Rectangle、Padding等为像素类型。
    /// 在不同DPI缩放下,矢量类型等比缩放,像素类型保持不变,故会出现排版显示问题。
    /// 解决方案一:项目中所有用到的像素类型实例值都取与缩放比之积,矢量类型不变。
    /// 解决方案二:项目中所有用到的矢量类型实例都取与缩放比之商,像素类型不变</remarks>
    public static class HighDpi
    {
        /// <summary>DPI缩放比</summary>
        public static readonly double DpiScale = Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;

        public static Point DpiZoom(this Point point) => new Point(DpiZoom(point.X), DpiZoom(point.Y));

        public static PointF DpiZoom(this PointF point) => new PointF(DpiZoom(point.X), DpiZoom(point.Y));

        public static Size DpiZoom(this Size size) => new Size(DpiZoom(size.Width), DpiZoom(size.Height));

        public static SizeF DpiZoom(this SizeF size) => new SizeF(DpiZoom(size.Width), DpiZoom(size.Height));

        public static Rectangle DpiZoom(this Rectangle r) => new Rectangle(DpiZoom(r.Location), DpiZoom(r.Size));

        public static RectangleF DpiZoom(this RectangleF r) => new RectangleF(DpiZoom(r.Location), DpiZoom(r.Size));

        public static Padding DpiZoom(this Padding p) => new Padding(DpiZoom(p.Left), DpiZoom(p.Top), DpiZoom(p.Right), DpiZoom(p.Bottom));

        public static Font DpiZoom(this Font font) => new Font(font.FontFamily, font.Size / DpiZoom(1F), font.Style);

        public static int DpiZoom(this int num) => (int)(num * DpiScale);

        public static float DpiZoom(this float num) => (float)(num * DpiScale);

        public static double DpiZoom(this double num) => num * DpiScale;
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ImageExtension.cs
================================================
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace BluePointLilac.Methods
{
    public static class ImageExtension
    {
        public static Image ToTransparent(this Image image, float opacity = 0.5F)
        {
            Bitmap bitmap = new Bitmap(image.Width, image.Height);
            using(Graphics g = Graphics.FromImage(bitmap))
            using(ImageAttributes attributes = new ImageAttributes())
            {
                ColorMatrix matrix = new ColorMatrix { Matrix33 = opacity };
                attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
                g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                    0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
            }
            return bitmap;
        }

        public static Image ResizeImage(this Image image, int width, int height)
        {
            //return image.GetThumbnailImage(width, height, null, System.IntPtr.Zero);//质量稍微低一点
            if(image.Width == width && image.Height == height) return image;
            Bitmap destImage = new Bitmap(width, height);
            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
            using(Graphics g = Graphics.FromImage(destImage))
            {
                g.CompositingMode = CompositingMode.SourceCopy;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;

                using(ImageAttributes attributes = new ImageAttributes())
                {
                    attributes.SetWrapMode(WrapMode.TileFlipXY);
                    g.DrawImage(image, new Rectangle(0, 0, width, height),
                        0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
                }
            }
            return destImage;
        }

        public static Image ResizeImage(this Image image, double scale)
        {
            if(scale == 1) return image;
            int width = (int)(image.Width * scale);
            int height = (int)(image.Height * scale);
            return image.ResizeImage(width, height);
        }

        public static Image ResizeImage(this Image image, Size newSize)
        {
            if(newSize == image.Size) return image;
            return image.ResizeImage(newSize.Width, newSize.Height);
        }

        public static Image RotateImage(this Image image, RotateFlipType rotateType)
        {
            Bitmap bitmap = new Bitmap(image);
            bitmap.RotateFlip(rotateType);
            return bitmap;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/IniReader.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace BluePointLilac.Methods
{
    public sealed class IniReader
    {
        public IniReader() { }

        public IniReader(StringBuilder sb) => LoadStringBuilder(sb);

        public IniReader(string filePath) => LoadFile(filePath);

        private readonly Dictionary<string, Dictionary<string, string>> RootDic
            = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);

        public string[] Sections => RootDic.Keys.ToArray();

        public void LoadStringBuilder(StringBuilder sb)
        {
            RootDic.Clear();
            if(sb.ToString().IsNullOrWhiteSpace()) return;
            List<string> lines = sb.ToString().Split(new[] { "\r\n", "\n" },
                StringSplitOptions.RemoveEmptyEntries).ToList();//拆分为行
            lines.ForEach(line => line.Trim());
            ReadLines(lines);
        }

        public void LoadFile(string filePath)
        {
            RootDic.Clear();
            if(!File.Exists(filePath)) return;
            List<string> lines = new List<string>();
            using(StreamReader reader = new StreamReader(filePath, EncodingType.GetType(filePath)))
            {
                while(!reader.EndOfStream)
                {
                    string line = reader.ReadLine().Trim();
                    if(line != string.Empty) lines.Add(line);
                }
            }
            ReadLines(lines);
        }

        private void ReadLines(List<string> lines)
        {
            lines.RemoveAll(
                line => line.StartsWith(";") || line.StartsWith("#")//移除注释
                || (!line.StartsWith("[") && !line.Contains("=")));//移除非section行且非key行

            if(lines.Count == 0) return;

            List<int> indexs = new List<int> { 0 };
            for(int i = 1; i < lines.Count; i++)
            {
                if(lines[i].StartsWith("[")) indexs.Add(i);//获取section行号
            }
            indexs.Add(lines.Count);

            for(int i = 0; i < indexs.Count - 1; i++)
            {
                string section = lines[indexs[i]];
                int m = section.IndexOf(']') - 1;
                if(m < 0) continue;
                section = section.Substring(1, m);
                if(RootDic.ContainsKey(section)) continue;
                var keyValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                RootDic.Add(section, keyValues);

                for(int j = indexs[i] + 1; j < indexs[i + 1]; j++)
                {
                    int k = lines[j].IndexOf('=');
                    string key = lines[j].Substring(0, k).TrimEnd();
                    string value = lines[j].Substring(k + 1).TrimStart();
                    if(keyValues.ContainsKey(key)) continue;
                    keyValues.Add(key, value);
                }
            }
        }

        public string GetValue(string section, string key)
        {
            if(RootDic.TryGetValue(section, out Dictionary<string, string> sectionDic))
                if(sectionDic.TryGetValue(key, out string value))
                    return value;
            return string.Empty;
        }

        public bool TryGetValue(string section, string key, out string value)
        {
            value = GetValue(section, key);
            return value != string.Empty;
        }

        public string[] GetSectionKeys(string section)
        {
            if(!RootDic.ContainsKey(section)) return null;
            else return RootDic[section].Keys.ToArray();
        }

        public bool RemoveSection(string section)
        {
            return RootDic.Remove(section);
        }

        public bool RemoveKey(string section, string key)
        {
            if(RootDic.ContainsKey(section))
            {
                return RootDic[section].Remove(key);
            }
            return false;
        }

        public void AddValue(string section, string key, string value)
        {
            if(RootDic.ContainsKey(section))
            {
                if(RootDic[section].ContainsKey(key))
                {
                    RootDic[section][key] = value;
                }
                else
                {
                    RootDic[section].Add(key, value);
                }
            }
            else
            {
                var dic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
                RootDic.Add(section, dic);
                dic.Add(key, value);
            }
        }

        public void SaveFile(string filePath)
        {
            List<string> lines = new List<string>();
            foreach(var item in RootDic)
            {
                lines.Add("[" + item.Key + "]");
                foreach(var key in item.Value)
                {
                    lines.Add(key.Key + " = " + key.Value);
                }
                lines.Add("");
            }
            Directory.CreateDirectory(Path.GetDirectoryName(filePath));
            FileAttributes attributes = FileAttributes.Normal;
            Encoding encoding = Encoding.Unicode;
            if(File.Exists(filePath))
            {
                encoding = EncodingType.GetType(filePath);
                attributes = File.GetAttributes(filePath);
                File.SetAttributes(filePath, FileAttributes.Normal);
            }
            File.WriteAllLines(filePath, lines.ToArray(), encoding);
            File.SetAttributes(filePath, attributes);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/IniWriter.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace BluePointLilac.Methods
{
    public sealed class IniWriter
    {
        public IniWriter() { }

        public IniWriter(string filePath)
        {
            this.FilePath = filePath;
        }

        public string FilePath { get; set; }

        public bool DeleteFileWhenEmpty { get; set; }

        private List<string> GetLines()
        {
            List<string> lines = new List<string>();
            if(!File.Exists(FilePath)) return lines;
            using(StreamReader reader = new StreamReader(FilePath, EncodingType.GetType(FilePath)))
            {
                while(!reader.EndOfStream)
                {
                    lines.Add(reader.ReadLine().Trim());
                }
            }
            return lines;
        }

        /// <param name="isGetValue">是否是获取value值</param>
        private void SetValue(string section, string key, ref string value, bool isGetValue)
        {
            if(section == null) return;
            List<string> lines = GetLines();
            string sectionLine = $"[{section}]";
            string keyLine = $"{key}={value}";
            int sectionRow = -1, keyRow = -1;//先假设不存在目标section和目标key
            int nextSectionRow = -1;//下一个section的行数
            for(int i = 0; i < lines.Count; i++)
            {
                if(lines[i].StartsWith(sectionLine, StringComparison.OrdinalIgnoreCase))
                {
                    sectionRow = i; break;//得到目标section所在行
                }
            }
            if(sectionRow >= 0)//如果目标section存在
            {
                for(int i = sectionRow + 1; i < lines.Count; i++)
                {
                    if(lines[i].StartsWith(";") || lines[i].StartsWith("#"))
                    {
                        continue;//跳过注释
                    }
                    if(lines[i].StartsWith("["))
                    {
                        nextSectionRow = i; break;//读取到下一个section
                    }
                    if(key != null && keyRow == -1)
                    {
                        int index = lines[i].IndexOf('=');
                        if(index < 0) continue;
                        string str = lines[i].Substring(0, index).TrimEnd();
                        if(str.Equals(key, StringComparison.OrdinalIgnoreCase))
                        {
                            if(isGetValue)//如果是获取Value值,直接返回
                            {
                                value = lines[i].Substring(index + 1).Trim();
                                return;
                            }
                            keyRow = i; continue;//得到目标key行
                        }
                    }
                }
            }

            if(isGetValue) return;

            if(sectionRow == -1)
            {
                if(key != null && value != null)
                {
                    lines.Add(string.Empty);//添加空行
                    //目标section不存在则添加到最后
                    lines.Add(sectionLine);
                    lines.Add(keyLine);
                }
            }
            else
            {
                if(keyRow == -1)
                {
                    if(key != null)
                    {
                        //存在下一个section时插入到其上方
                        if(nextSectionRow != -1)
                        {
                            //目标section存在但目标key不存在
                            keyRow = nextSectionRow;
                            lines.Insert(keyRow, keyLine);
                        }
                        else
                        {
                            //不存在下一个section则添加到最后
                            lines.Add(keyLine);
                        }
                    }
                    else
                    {
                        //key为null则删除整个section
                        int count;
                        if(nextSectionRow == -1) count = lines.Count - sectionRow;
                        else count = nextSectionRow - sectionRow;
                        lines.RemoveRange(sectionRow, count);
                    }
                }
                else
                {
                    if(value != null)
                    {
                        //目标section和目标key都存在
                        lines[keyRow] = keyLine;
                    }
                    else
                    {
                        //赋值为null则删除key
                        lines.RemoveAt(keyRow);
                    }
                }
            }

            Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
            FileAttributes attributes = FileAttributes.Normal;
            Encoding encoding = Encoding.Unicode;
            if(File.Exists(FilePath))
            {
                encoding = EncodingType.GetType(FilePath);
                attributes = File.GetAttributes(FilePath);
                File.SetAttributes(FilePath, FileAttributes.Normal);
            }
            File.WriteAllLines(FilePath, lines.ToArray(), encoding);
            File.SetAttributes(FilePath, attributes);

            if(DeleteFileWhenEmpty && lines.TrueForAll(line => line.IsNullOrWhiteSpace()))
            {
                File.Delete(FilePath);
            }
        }

        public void SetValue(string section, string key, object value)
        {
            SetValue(section, key, value.ToString());
        }

        public void SetValue(string section, string key, string value)
        {
            SetValue(section, key, ref value, false);
        }

        public void DeleteKey(string section, string key)
        {
            SetValue(section, key, null);
        }

        public void DeleteSection(string section)
        {
            SetValue(section, null, null);
        }

        /// <summary>一次读取只获取一个值,用此方法比IniReader.GetValue要快</summary>
        public string GetValue(string section, string key)
        {
            string value = string.Empty;
            SetValue(section, key, ref value, true);
            return value;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/MessageBoxEx.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    /// <summary>在窗体居中显示的MessageBox</summary>
    public static class MessageBoxEx
    {
        /// <summary>弹出一个消息框</summary>
        /// <param name="text">要在消息框中显示的文本</param>
        /// <param name="caption">要在消息框的标题栏中显示的文本</param>
        /// <param name="buttons">指定在消息框中显示哪些按钮</param>
        /// <param name="boxIcon">指定在消息框中显示哪个图标</param>
        /// <param name="owner">指定消息框的拥有者</param>
        /// <param name="defaultResult">指定默认结果,使对应按钮预先获取焦点</param>
        /// <param name="canMoveParent">能否移动父窗体</param>
        /// <returns>System.Windows.Forms.DialogResult 值之一</returns>
        public static DialogResult Show(string text, string caption = null,
            MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon boxIcon = MessageBoxIcon.None,
            IWin32Window owner = null, DialogResult defaultResult = DialogResult.None, bool canMoveParent = true)
        {
            using(MessageBoxForm frm = new MessageBoxForm(text, caption, buttons, boxIcon, defaultResult, canMoveParent))
            {
                return frm.ShowDialog(owner);
            }
        }

        /// <summary>弹出一个消息框</summary>
        /// <param name="text">要在消息框中显示的文本</param>
        /// <param name="caption">要在消息框的标题栏中显示的文本</param>
        /// <param name="buttonTexts">从右至左添加数组长度的个数的按钮,按钮文本为数组对应成员</param>
        /// <param name="boxImaage">指定在消息框中显示的图标图像</param>
        /// <param name="owner">指定消息框的拥有者</param>
        /// <param name="defaultResult">指定默认结果,使对应按钮预先获取焦点</param>
        /// <param name="canMoveParent">能否移动父窗体</param>
        /// <param name="closeBox">消息框关闭按钮是否可用</param>
        /// <returns>返回用户点击的按钮所显示的文本</returns>
        public static string Show(string text, string caption,
            string[] buttonTexts, Image boxImaage,
            IWin32Window owner = null, string defaultResult = null,
            bool canMoveParent = true, bool closeBox = true)
        {
            using(MessageBoxForm frm = new MessageBoxForm(text, caption, buttonTexts, boxImaage, defaultResult, canMoveParent, closeBox))
            {
                frm.ShowDialog(owner);
                return frm.Tag?.ToString();
            }
        }

        sealed class MessageBoxForm : Form
        {
            private MessageBoxForm(string text, string caption, bool canMoveParent)
            {
                lblText.Text = text;
                this.Text = caption;
                this.CanMoveParent = canMoveParent;
                this.Font = SystemFonts.MessageBoxFont;
                this.ShowIcon = this.ShowInTaskbar = false;
                this.MaximizeBox = this.MinimizeBox = false;
                this.FormBorderStyle = FormBorderStyle.FixedSingle;
                this.StartPosition = FormStartPosition.CenterParent;
            }

            public MessageBoxForm(string text, string caption,
                string[] buttonTexts, Image boxImage,
                string defaultResult, bool canMoveParent, bool closeBox) : this(text, caption, canMoveParent)
            {
                this.CloseBox = closeBox;
                this.InitializeComponents(buttonTexts, boxImage);
                foreach(Button button in flpButtons.Controls)
                {
                    button.Click += (sender, e) =>
                    {
                        this.Tag = button.Text;
                        this.Close();
                    };
                    this.Shown += (sender, e) =>
                    {
                        if(button.Text == defaultResult) button.Focus();
                    };
                }
            }

            public MessageBoxForm(string text, string caption,
                MessageBoxButtons buttons, MessageBoxIcon boxIcon,
                DialogResult defaultResult, bool canMoveParent) : this(text, caption, canMoveParent)
            {
                string[] buttonTexts = null;
                Image boxImage = null;
                switch(buttons)
                {
                    case MessageBoxButtons.OK:
                        buttonTexts = new[] { "OK" }; break;
                    case MessageBoxButtons.OKCancel:
                        buttonTexts = new[] { "Cancel", "OK" }; break;
                    case MessageBoxButtons.AbortRetryIgnore:
                        buttonTexts = new[] { "&Ignore", "&Retry", "&Abort" }; break;
                    case MessageBoxButtons.YesNoCancel:
                        buttonTexts = new[] { "Cancel", "&No", "&Yes" }; break;
                    case MessageBoxButtons.YesNo:
                        buttonTexts = new[] { "&No", "&Yes" }; break;
                    case MessageBoxButtons.RetryCancel:
                        buttonTexts = new[] { "Cancel", "&Retry" }; break;
                }
                switch(boxIcon)
                {
                    case MessageBoxIcon.Question:
                        boxImage = MessageBoxImage.Question; break;
                    case MessageBoxIcon.Error:
                        boxImage = MessageBoxImage.Error; break;
                    case MessageBoxIcon.Warning:
                        boxImage = MessageBoxImage.Warning; break;
                    case MessageBoxIcon.Information:
                        boxImage = MessageBoxImage.Information; break;
                }
                this.InitializeComponents(buttonTexts, boxImage);
                foreach(Button button in flpButtons.Controls)
                {
                    switch(button.Text)
                    {
                        case "OK":
                            if(buttons == MessageBoxButtons.OK)
                            {
                                this.CancelButton = button;
                                this.FormClosing += (sender, e) => button.PerformClick();
                            }
                            button.DialogResult = DialogResult.OK; break;
                        case "Cancel":
                            this.CancelButton = button;
                            button.DialogResult = DialogResult.Cancel; break;
                        case "&Yes":
                            button.DialogResult = DialogResult.Yes; break;
                        case "&No":
                            button.DialogResult = DialogResult.No; break;
                        case "&Abort":
                            button.DialogResult = DialogResult.Abort; break;
                        case "&Retry":
                            button.DialogResult = DialogResult.Retry; break;
                        case "&Ignore":
                            button.DialogResult = DialogResult.Ignore; break;
                    }
                    this.Shown += (sender, e) =>
                    {
                        if(button.DialogResult == defaultResult) button.Focus();
                    };
                }
                this.CloseBox = this.CancelButton != null;
            }

            private void InitializeComponents(string[] buttonTexts, Image boxImage)
            {
                this.SuspendLayout();
                int w1 = 36.DpiZoom();
                Size buttonSize = new Size(75, 27).DpiZoom();
                for(int i = 0; i < buttonTexts.Length; i++)
                {
                    Button button = new Button
                    {
                        Margin = new Padding(12, 0, 0, 0).DpiZoom(),
                        Text = buttonTexts[i],
                        Parent = flpButtons,
                        AutoSize = true,
                    };
                    button.Width = Math.Max(buttonSize.Width, button.Width);
                    button.Height = Math.Max(buttonSize.Height, button.Height);
                    buttonSize = button.Size;
                    w1 += button.Width + button.Margin.Horizontal;
                }
                picIcon.Image = boxImage;
                if(boxImage == null)
                {
                    picIcon.Visible = false;
                    lblText.Left = picIcon.Left;
                }
                pnlInfo.Controls.AddRange(new Control[] { picIcon, lblText });
                this.Controls.AddRange(new Control[] { pnlInfo, flpButtons });
                pnlInfo.Height = lblText.Height + lblText.Top * 2;
                if(picIcon.Height > lblText.Height / 2)
                {
                    picIcon.Top = (pnlInfo.Height - picIcon.Height) / 2;
                }
                int w2 = lblText.Right + picIcon.Left;
                int w = Math.Max(w1, w2);
                int h = pnlInfo.Height + flpButtons.Height;
                this.ClientSize = new Size(w, h);
                this.ResumeLayout();
            }

            readonly FlowLayoutPanel flpButtons = new FlowLayoutPanel
            {
                FlowDirection = FlowDirection.RightToLeft,
                Padding = new Padding(12.DpiZoom()),
                Dock = DockStyle.Bottom,
                Height = 50.DpiZoom(),
                WrapContents = false,
            };
            readonly Panel pnlInfo = new Panel
            {
                BackColor = Color.White,
                Dock = DockStyle.Top,
            };
            readonly PictureBox picIcon = new PictureBox
            {
                SizeMode = PictureBoxSizeMode.AutoSize,
                Location = new Point(32, 32).DpiZoom(),
            };
            readonly Label lblText = new Label
            {
                Location = new Point(68, 32).DpiZoom(),
                AutoSize = true,
            };

            readonly bool CloseBox = true;//关闭按钮可用性
            readonly bool CanMoveParent = true;//可移动父窗体

            protected override CreateParams CreateParams
            {
                get
                {
                    const int CP_NOCLOSE_BUTTON = 0x200;
                    CreateParams cp = base.CreateParams;
                    if(!CloseBox) cp.ClassStyle |= CP_NOCLOSE_BUTTON; //禁用关闭按钮
                    return cp;
                }
            }

            protected override void OnLoad(EventArgs e)
            {
                if(this.Owner == null && Form.ActiveForm != this) this.Owner = Form.ActiveForm;
                if(this.Owner == null) this.StartPosition = FormStartPosition.CenterScreen;
                else
                {
                    this.TopMost = this.Owner.TopMost;
                    this.StartPosition = FormStartPosition.CenterParent;
                    if(this.CanMoveParent) this.MoveAsMove(this.Owner);
                }
                base.OnLoad(e);
            }
        }
    }

    public static class MessageBoxImage
    {
        // SystemIcons 里面的图标不是扁平的,❌、⚠️、❔、ℹ️
        public static readonly Image Error = GetImage(-98);
        public static readonly Image Warning = GetImage(-84);
        public static readonly Image Question = GetImage(-99);
        public static readonly Image Information = GetImage(-81);

        private static Image GetImage(int index)
        {
            using(Icon icon = ResourceIcon.GetIcon("imageres.dll", index))
            {
                return icon?.ToBitmap();
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/RegTrustedInstaller.cs
================================================
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;

namespace BluePointLilac.Methods
{
    /// 获取TrustedInstaller权限注册表项的所有权
    /// 代码作者:JPBlanc(原作者)、蓝点lilac(转载、修改)
    /// 代码原文:https://gist.github.com/JPBlanc/ca0e4f1830e4ca18a526#file-write_a_registry_own_by_trustedinstaller-cs
    public class RegTrustedInstaller
    {
        static class NativeMethod
        {
            public const string TakeOwnership = "SeTakeOwnershipPrivilege";
            public const string Restore = "SeRestorePrivilege";

            [StructLayout(LayoutKind.Sequential)]
            public struct LUID
            {
                public int lowPart;
                public int highPart;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct LUID_AND_ATTRIBUTES
            {
                public LUID Luid;
                public int Attributes;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct TOKEN_PRIVILEGES
            {
                public int PrivilegeCount;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
                public LUID_AND_ATTRIBUTES[] Privileges;
            }

            [Flags]
            public enum PrivilegeAttributes
            {
                /// <summary>特权被禁用.</summary>
                Disabled = 0,
                /// <summary>默认特权.</summary>
                EnabledByDefault = 1,
                /// <summary>特权被激活.</summary>
                Enabled = 2,
                /// <summary>特权被废除.</summary>
                Removed = 4,
                /// <summary>用于访问对象或服务的特权.</summary>
                UsedForAccess = -2147483648
            }

            [Flags]
            public enum TokenAccessRights
            {
                /// <summary>向进程附加主令牌的权限.</summary>
                AssignPrimary = 0,
                /// <summary>复制访问令牌的权利.</summary>
                Duplicate = 1,
                /// <summary>向进程附加模拟访问令牌的权限.</summary>
                Impersonate = 4,
                /// <summary>查询访问令牌的权利.</summary>
                Query = 8,
                /// <summary>有权查询访问令牌的来源.</summary>
                QuerySource = 16,
                /// <summary>启用或禁用访问令牌中的特权的权限.</summary>
                AdjustPrivileges = 32,
                /// <summary>调整访问令牌中的组属性的权限.</summary>
                AdjustGroups = 64,
                /// <summary>更改访问令牌的默认所有者、主组或DACL的权限.</summary>
                AdjustDefault = 128,
                /// <summary>正确调整访问令牌的会话ID.</summary>
                AdjustSessionId = 256,
                /// <summary>为令牌组合所有可能的访问权限.</summary>
                AllAccess = AccessTypeMasks.StandardRightsRequired | AssignPrimary | Duplicate | Impersonate
                            | Query | QuerySource | AdjustPrivileges | AdjustGroups | AdjustDefault | AdjustSessionId,
                /// <summary>结合需要阅读的标准权利</summary>
                Read = AccessTypeMasks.StandardRightsRead | Query,
                /// <summary>组合了写入所需的标准权限</summary>
                Write = AccessTypeMasks.StandardRightsWrite | AdjustPrivileges | AdjustGroups | AdjustDefault,
                /// <summary>合并执行所需的标准权限</summary>
                Execute = AccessTypeMasks.StandardRightsExecute | Impersonate
            }

            [Flags]
            private enum AccessTypeMasks
            {
                Delete = 65536,
                ReadControl = 131072,
                WriteDAC = 262144,
                WriteOwner = 524288,
                Synchronize = 1048576,
                StandardRightsRequired = 983040,
                StandardRightsRead = ReadControl,
                StandardRightsWrite = ReadControl,
                StandardRightsExecute = ReadControl,
                StandardRightsAll = 2031616,
                SpecificRightsAll = 65535
            }

            [DllImport("advapi32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool AdjustTokenPrivileges([In] IntPtr accessTokenHandle, [In] bool disableAllPrivileges,
                [In] ref TOKEN_PRIVILEGES newState, [In] int bufferLength, [In, Out] ref TOKEN_PRIVILEGES previousState, [In, Out] ref int returnLength);

            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool LookupPrivilegeValue([In] string systemName, [In] string name, [In, Out] ref LUID luid);

            [DllImport("advapi32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool OpenProcessToken([In] IntPtr processHandle, [In] TokenAccessRights desiredAccess, [In, Out] ref IntPtr tokenHandle);

            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern int GetLastError();

            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern IntPtr GetCurrentProcess();

            public static bool TrySetPrivilege(string sPrivilege, bool enablePrivilege)
            {
                bool blRc;
                TOKEN_PRIVILEGES newTP = new TOKEN_PRIVILEGES();
                TOKEN_PRIVILEGES oldTP = new TOKEN_PRIVILEGES();
                LUID luid = new LUID();
                int retrunLength = 0;
                IntPtr processToken = IntPtr.Zero;

                //本地进程令牌恢复
                blRc = OpenProcessToken(GetCurrentProcess(), TokenAccessRights.AllAccess, ref processToken);
                if(blRc == false) return false;

                //恢复特权的唯一标识符空间
                blRc = LookupPrivilegeValue(null, sPrivilege, ref luid);
                if(blRc == false) return false;

                //建立或取消特权
                newTP.PrivilegeCount = 1;
                newTP.Privileges = new LUID_AND_ATTRIBUTES[64];
                newTP.Privileges[0].Luid = luid;

                if(enablePrivilege) newTP.Privileges[0].Attributes = (int)PrivilegeAttributes.Enabled;
                else newTP.Privileges[0].Attributes = (int)PrivilegeAttributes.Disabled;

                oldTP.PrivilegeCount = 64;
                oldTP.Privileges = new LUID_AND_ATTRIBUTES[64];
                blRc = AdjustTokenPrivileges(processToken, false, ref newTP, 16, ref oldTP, ref retrunLength);

                if(blRc == false) { GetLastError(); return false; }
                return true;
            }
        }

        /// <summary>获取注册表项权限</summary>
        /// <remarks>将注册表项所有者改为当前管理员用户</remarks>
        /// <param name="regPath">要获取权限的注册表完整路径</param>
        public static void TakeRegKeyOwnerShip(string regPath)
        {
            if(regPath.IsNullOrWhiteSpace()) return;
            RegistryKey key = null;
            WindowsIdentity id = null;
            //利用试错判断是否有写入权限
            try { key = RegistryEx.GetRegistryKey(regPath, true); }
            catch
            {
                try
                {
                    //获取当前用户的ID
                    id = WindowsIdentity.GetCurrent();

                    //添加TakeOwnership特权
                    bool flag = NativeMethod.TrySetPrivilege(NativeMethod.TakeOwnership, true);
                    if(!flag) throw new PrivilegeNotHeldException(NativeMethod.TakeOwnership);

                    //添加恢复特权(必须这样做才能更改所有者)
                    flag = NativeMethod.TrySetPrivilege(NativeMethod.Restore, true);
                    if(!flag) throw new PrivilegeNotHeldException(NativeMethod.Restore);

                    //打开没有权限的注册表路径
                    key = RegistryEx.GetRegistryKey(regPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);

                    RegistrySecurity security = key.GetAccessControl(AccessControlSections.All);

                    //得到真正所有者
                    //IdentityReference oldId = security.GetOwner(typeof(SecurityIdentifier));
                    //SecurityIdentifier siTrustedInstaller = new SecurityIdentifier(oldId.ToString());

                    //使进程用户成为所有者
                    security.SetOwner(id.User);
                    key.SetAccessControl(security);

                    //添加完全控制
                    RegistryAccessRule fullAccess = new RegistryAccessRule(id.User, RegistryRights.FullControl,
                        InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow);
                    security.AddAccessRule(fullAccess);
                    key.SetAccessControl(security);

                    //注册表操作(写入、删除)
                    //key.SetValue("temp", "");//示例

                    //恢复原有所有者
                    //security.SetOwner(siTrustedInstaller);
                    //key.SetAccessControl(security);

                    //收回原有权利
                    //security.RemoveAccessRule(fullAccess);
                    //key.SetAccessControl(security);

                    ///得到真正所有者、注册表操作、恢复原有所有者、收回原有权利,这四部分在原文中没有被注释掉
                    ///但是如果保留这四部分,会在恢复原有所有者这一步抛出异常,提示没有权限,
                    ///不过我发现经过上面的操作,虽然无法还原所有者权限,但是已经获取了注册表权限
                    ///即已经将TrustedInstaller权限更改为当前管理员用户权限,我要的目的已经达到了
                }
                catch { }
            }
            finally { key?.Close(); id?.Dispose(); }
        }

        /// <summary>获取注册表项及其子项、递归子级子项权限</summary>
        /// <remarks>将注册表项所有者改为当前管理员用户</remarks>
        /// <param name="regPath">要获取权限的注册表完整路径</param>
        public static void TakeRegTreeOwnerShip(string regPath)
        {
            if(regPath.IsNullOrWhiteSpace()) return;
            TakeRegKeyOwnerShip(regPath);
            try
            {
                using(RegistryKey key = RegistryEx.GetRegistryKey(regPath))
                {
                    if(key == null) return;
                    foreach(string subKeyName in key.GetSubKeyNames())
                    {
                        TakeRegTreeOwnerShip($@"{key.Name}\{subKeyName}");
                    }
                }
            }
            catch { }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/RegistryEx.cs
================================================
using Microsoft.Win32;
using System;
using System.Security.AccessControl;

namespace BluePointLilac.Methods
{
    public static class RegistryEx
    {
        public const string CLASSES_ROOT = "HKEY_CLASSES_ROOT";
        public const string CURRENT_USER = "HKEY_CURRENT_USER";
        public const string LOCAL_MACHINE = "HKEY_LOCAL_MACHINE";
        public const string CURRENT_CONFIG = "HKEY_CURRENT_CONFIG";
        public const string USERS = "HKEY_USERS";

        public const string HKCR = "HKCR";
        public const string HKCU = "HKCU";
        public const string HKLM = "HKLM";
        public const string HKCC = "HKCC";
        public const string HKU = "HKU";

        public static void CopyTo(this RegistryKey srcKey, RegistryKey dstKey)
        {
            foreach(string name in srcKey.GetValueNames())
            {
                dstKey.SetValue(name, srcKey.GetValue(name), srcKey.GetValueKind(name));
            }
            foreach(string name in srcKey.GetSubKeyNames())
            {
                using(RegistryKey srcSubKey = srcKey.OpenSubKey(name))
                using(RegistryKey dstSubKey = dstKey.CreateSubKey(name, true))
                    srcSubKey.CopyTo(dstSubKey);
            }
        }

        public static void CopyTo(string srcPath, string dstPath)
        {
            using(RegistryKey srcKey = GetRegistryKey(srcPath))
            using(RegistryKey dstKey = GetRegistryKey(dstPath, true, true))
            {
                CopyTo(srcKey, dstKey);
            }
        }

        public static void MoveTo(this RegistryKey srcKey, RegistryKey dstKey)
        {
            CopyTo(srcKey, dstKey);
            DeleteKeyTree(srcKey.Name, true);
        }

        public static void MoveTo(string srcPath, string dstPath)
        {
            CopyTo(srcPath, dstPath);
            DeleteKeyTree(srcPath, true);
        }

        public static RegistryKey CreateSubKey(this RegistryKey key, string subKeyName, bool writable)
        {
            using(key.CreateSubKey(subKeyName))
                return key.OpenSubKey(subKeyName, writable);
        }

        /// <summary>获取指定路径注册表项的上一级路径</summary>
        public static string GetParentPath(string regPath) => regPath.Substring(0, regPath.LastIndexOf('\\'));

        /// <summary>获取指定路径注册表项的项名</summary>
        public static string GetKeyName(string regPath) => regPath.Substring(regPath.LastIndexOf('\\') + 1);

        /// <summary>获取指定路径注册表项的根项项名</summary>
        public static string GetRootName(string regPath) => regPath.Substring(0, regPath.IndexOf('\\'));

        /// <summary>获取不包含根项部分的注册表路径</summary>
        public static string GetPathWithoutRoot(string regPath) => regPath.Substring(regPath.IndexOf('\\') + 1);

        /// <summary>删除指定路径的注册表项的指定名称的键值</summary>
        /// <param name="regPath">注册表项路径</param>
        /// <param name="valueName">要删除的键值名称</param>
        /// <param name="throwOnMissingValue">找不到键值时是否抛出异常</param>
        public static void DeleteValue(string regPath, string valueName, bool throwOnMissingValue = false)
        {
            GetRegistryKey(regPath, true)?.DeleteValue(valueName, throwOnMissingValue);
        }

        /// <summary>递归删除指定注册表项及所有子项</summary>
        /// <param name="regPath">注册表路径</param>
        /// <param name="throwOnMissingKey">找不到注册表项或者没有操作权限时是否抛出异常</param>
        public static void DeleteKeyTree(string regPath, bool throwOnMissingKey = false)
        {
            string dirPath = GetParentPath(regPath);
            string keyName = GetKeyName(regPath);
            try
            {
                GetRegistryKey(dirPath, true)?.DeleteSubKeyTree(keyName);
            }
            catch(Exception)
            {
                if(throwOnMissingKey) throw;
            }
        }

        /// <summary>获取指定注册表路径的根项RegistryKey和不包含根项部分的注册表路径</summary>
        /// <param name="regPath">注册表路径</param>
        /// <param name="root">成功解析返回一个RegistryKey,否则抛出异常</param>
        /// <param name="subRegPath">不包含根项的注册表路径</param>
        public static void GetRootAndSubRegPath(string regPath, out RegistryKey root, out string subRegPath)
        {
            string rootPath;
            int index = regPath.IndexOf('\\');
            if(index > 0)
            {
                rootPath = regPath.Substring(0, index).ToUpper();
                subRegPath = regPath.Substring(index + 1);
            }
            else
            {
                rootPath = regPath;
                subRegPath = string.Empty;
            }
            switch(rootPath)
            {
                case HKCR:
                case CLASSES_ROOT:
                    root = Registry.ClassesRoot;
                    break;
                case HKCU:
                case CURRENT_USER:
                    root = Registry.CurrentUser;
                    break;
                case HKLM:
                case LOCAL_MACHINE:
                    root = Registry.LocalMachine;
                    break;
                case HKU:
                case USERS:
                    root = Registry.Users;
                    break;
                case HKCC:
                case CURRENT_CONFIG:
                    root = Registry.CurrentConfig;
                    break;
                default:
                    throw new ArgumentNullException(regPath);
            }
        }

        /// <summary>获取指定注册表项路径的RegistryKey</summary>
        /// <param name="regPath">注册表项路径</param>
        /// <param name="writable">写入访问权限</param>
        /// <param name="create">是否创建新项</param>
        public static RegistryKey GetRegistryKey(string regPath, bool writable = false, bool create = false)
        {
            GetRootAndSubRegPath(regPath, out RegistryKey root, out string keyPath);
            using(root)
            {
                if(create) return root.CreateSubKey(keyPath, writable);
                else
                {
                    RegTrustedInstaller.TakeRegTreeOwnerShip(keyPath);
                    return root.OpenSubKey(keyPath, writable);
                }
            }
        }

        public static RegistryKey GetRegistryKey(string regPath, RegistryKeyPermissionCheck check, RegistryRights rights)
        {
            GetRootAndSubRegPath(regPath, out RegistryKey root, out string keyPath);
            using(root) return root.OpenSubKey(keyPath, check, rights);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ResourceIcon.cs
================================================
using Microsoft.Win32;
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class ResourceIcon
    {
        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        private static extern int ExtractIconEx(string lpFileName, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, uint nIcons);

        [DllImport("user32.dll", SetLastError = true)]
        private static extern bool DestroyIcon(IntPtr hIcon);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
        private static extern IntPtr LoadLibrary(string lpLibFileName);

        [DllImport("kernel32.dll")]
        private static extern bool FreeLibrary(IntPtr hLibModule);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern IntPtr LoadImage(IntPtr hInst, string lpFileName, uint uType, int cx, int cy, uint fuLoad);

        [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, FileInfoFlags uFlags);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct SHFILEINFO
        {
            public IntPtr hIcon;
            public int iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        }

        [Flags]
        public enum FileInfoFlags : uint
        {
            SHGFI_ICON = 0x000000100,               // get icon
            SHGFI_DISPLAYNAME = 0x000000200,        // get display name
            SHGFI_TYPENAME = 0x000000400,           // get type name
            SHGFI_ATTRIBUTES = 0x000000800,         // get attributes
            SHGFI_ICONLOCATION = 0x000001000,       // get icon location
            SHGFI_EXETYPE = 0x000002000,            // return exe type
            SHGFI_SYSICONINDEX = 0x000004000,       // get system icon index
            SHGFI_LINKOVERLAY = 0x000008000,        // put a link overlay on icon
            SHGFI_SELECTED = 0x000010000,           // show icon in selected state
            SHGFI_ATTR_SPECIFIED = 0x000020000,     // get only specified attributes
            SHGFI_LARGEICON = 0x000000000,          // get large icon
            SHGFI_SMALLICON = 0x000000001,          // get small icon
            SHGFI_OPENICON = 0x000000002,           // get open icon
            SHGFI_SHELLICONSIZE = 0x000000004,      // get shell size icon
            SHGFI_PIDL = 0x000000008,               // pszPath is a pidl
            SHGFI_USEFILEATTRIBUTES = 0x000000010,  // use passed dwFileAttribute
            SHGFI_ADDOVERLAYS = 0x000000020,        // apply the appropriate overlays
            SHGFI_OVERLAYINDEX = 0x000000040        // get the index of the overlay in the upper 8 bits of the iIcon
        }

        /// <summary>获取文件类型的关联图标</summary>
        /// <param name="extension">文件类型的扩展名,如.txt</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetExtensionIcon(string extension)
        {
            FileInfoFlags flags = FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_LARGEICON | FileInfoFlags.SHGFI_USEFILEATTRIBUTES;
            return GetIcon(extension, flags);
        }

        /// <summary>获取文件夹、磁盘驱动器的图标</summary>
        /// <param name="folderPath">文件夹或磁盘驱动器路径</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetFolderIcon(string folderPath)
        {
            FileInfoFlags flags = FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_LARGEICON;
            return GetIcon(folderPath, flags);
        }

        /// <summary>根据文件信息标志提取指定文件路径的图标</summary>
        /// <param name="filePath">文件路径</param>
        /// <param name="flags">文件信息标志</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetIcon(string filePath, FileInfoFlags flags)
        {
            SHFILEINFO info = new SHFILEINFO();
            IntPtr hInfo = SHGetFileInfo(filePath, 0, ref info, (uint)Marshal.SizeOf(info), flags);
            if(hInfo.Equals(IntPtr.Zero)) return null;
            Icon icon = (Icon)Icon.FromHandle(info.hIcon).Clone();
            DestroyIcon(info.hIcon); //释放资源
            return icon;
        }

        /// <summary>获取指定位置的图标</summary>
        /// <param name="iconLocation">图标位置</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetIcon(string iconLocation)
        {
            return GetIcon(iconLocation, out _, out _);
        }

        /// <summary>获取指定位置的图标</summary>
        /// <param name="iconLocation">图标位置</param>
        /// <param name="iconPath">返回图标文件路径</param>
        /// <param name="iconIndex">返回图标索引</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetIcon(string iconLocation, out string iconPath, out int iconIndex)
        {
            iconIndex = 0; iconPath = null;
            if(iconLocation.IsNullOrWhiteSpace()) return null;
            iconLocation = Environment.ExpandEnvironmentVariables(iconLocation).Replace("\"", "");
            int index = iconLocation.LastIndexOf(',');
            if(index == -1) iconPath = iconLocation;
            else
            {
                if(File.Exists(iconLocation)) iconPath = iconLocation;
                else
                {
                    bool flag = int.TryParse(iconLocation.Substring(index + 1), out iconIndex);
                    iconPath = flag ? iconLocation.Substring(0, index) : null;
                }
            }
            return GetIcon(iconPath, iconIndex);
        }

        /// <summary>获取指定文件中指定索引的图标</summary>
        /// <param name="iconPath">图标文件路径</param>
        /// <param name="iconIndex">图标索引</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetIcon(string iconPath, int iconIndex)
        {
            Icon icon = null;
            if(iconPath.IsNullOrWhiteSpace()) return icon;
            iconPath = Environment.ExpandEnvironmentVariables(iconPath).Replace("\"", "");

            if(Path.GetFileName(iconPath).ToLower() == "shell32.dll")
            {
                iconPath = "shell32.dll";//系统强制文件重定向
                icon = GetReplacedShellIcon(iconIndex);//注册表图标重定向
                if(icon != null) return icon;
            }

            IntPtr hInst = IntPtr.Zero;
            IntPtr[] hIcons = new[] { IntPtr.Zero };
            //iconIndex为负数就是指定资源标识符, 为正数就是该图标在资源文件中的顺序序号, 为-1时不能使用ExtractIconEx提取图标
            if(iconIndex == -1)
            {
                hInst = LoadLibrary(iconPath);
                hIcons[0] = LoadImage(hInst, "#1", 1, SystemInformation.IconSize.Width, SystemInformation.IconSize.Height, 0);
            }
            else ExtractIconEx(iconPath, iconIndex, hIcons, null, 1);

            try { icon = (Icon)Icon.FromHandle(hIcons[0]).Clone(); }
            catch { icon = null; }
            finally { DestroyIcon(hIcons[0]); FreeLibrary(hInst); }//释放资源
            return icon;
        }

        private const string ShellIconPath = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons";
        /// <summary>获取shell32.dll中的图标被替换后的图标</summary>
        /// <param name="iconIndex">图标索引</param>
        /// <returns>获取到的图标</returns>
        public static Icon GetReplacedShellIcon(int iconIndex)
        {
            string iconLocation = Registry.GetValue(ShellIconPath, iconIndex.ToString(), null)?.ToString();
            if(iconLocation != null) return GetIcon(iconLocation) ?? GetIcon("imageres.dll", 2);
            else return null;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ResourceString.cs
================================================
using System;
using System.Runtime.InteropServices;
using System.Text;

namespace BluePointLilac.Methods
{
    public static class ResourceString
    {
        //MSDN文档: https://docs.microsoft.com/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring
        //提取.pri文件资源: https://docs.microsoft.com/windows/uwp/app-resources/makepri-exe-command-options
        //.pri转储.xml资源列表: MakePri.exe dump /if [priPath] /of [xmlPath]

        [DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode,
            ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
        private static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, IntPtr ppvReserved);

        /// <summary>获取格式为"@[filename],-[strID]"或"@{[packageName]?ms-resource://[resPath]}"的直接字符串</summary>
        /// <param name="resStr">要转换的字符串</param>
        /// <returns>resStr为Null时返回值为string.Empty; resStr首字符为@但解析失败时返回string.Empty</returns>
        /// <remarks>[fileName]:文件路径; [strID]:字符串资源索引; [packageName]:UWP带版本号包名; [resPath]:pri资源路径</remarks>
        public static string GetDirectString(string resStr)
        {
            StringBuilder outBuff = new StringBuilder(1024);
            SHLoadIndirectString(resStr, outBuff, 1024, IntPtr.Zero);
            return outBuff.ToString();
        }

        public static readonly string OK = GetDirectString("@shell32.dll,-9752");
        public static readonly string Cancel = GetDirectString("@shell32.dll,-9751");
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/RichTextBoxExtension.cs
================================================
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Xml.Linq;

namespace BluePointLilac.Methods
{
    public static class RichTextBoxExtension
    {
        /// <summary>RichTextBox中ini语法高亮</summary>
        /// <param name="iniStr">要显示的ini文本</param>
        public static void LoadIni(this RichTextBox box, string iniStr)
        {
            string[] lines = iniStr.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
            for(int i = 0; i < lines.Length; i++)
            {
                string str = lines[i].Trim();
                if(str.StartsWith(";") || str.StartsWith("#"))
                {
                    box.AppendText(str, Color.SkyBlue);//注释
                }
                else if(str.StartsWith("["))
                {
                    if(str.Contains("]"))
                    {
                        int index = str.IndexOf(']');
                        box.AppendText(str.Substring(0, index + 1), Color.DarkCyan, null, true);//section
                        box.AppendText(str.Substring(index + 1), Color.SkyBlue);//section标签之后的内容视作注释
                    }
                    else box.AppendText(str, Color.SkyBlue);//section标签未关闭视作注释
                }
                else if(str.Contains("="))
                {
                    int index = str.IndexOf('=');
                    box.AppendText(str.Substring(0, index), Color.DodgerBlue);//key
                    box.AppendText(str.Substring(index), Color.DimGray);//value
                }
                else box.AppendText(str, Color.SkyBlue);//非section行和非key行视作注释
                if(i != lines.Length - 1) box.AppendText("\r\n");
            }
        }

        /// 代码原文:https://archive.codeplex.com/?p=xmlrichtextbox
        /// 本人(蓝点lilac)仅作简单修改,将原继承类改写为扩展方法
        /// <summary>RichTextBox中xml语法高亮</summary>
        /// <param name="xmlStr">要显示的xml文本</param>
        /// <remarks>可直接用WebBrowser的Url加载本地xml文件,但无法自定义颜色</remarks>
        public static void LoadXml(this RichTextBox box, string xmlStr)
        {
            XmlStateMachine machine = new XmlStateMachine();
            if(xmlStr.StartsWith("<?"))
            {
                string declaration = machine.GetXmlDeclaration(xmlStr);
                try
                {
                    xmlStr = XDocument.Parse(xmlStr, LoadOptions.PreserveWhitespace).ToString().Trim();
                    if(string.IsNullOrEmpty(xmlStr) && declaration == string.Empty) return;
                }
                catch { throw; }
                xmlStr = declaration + "\r\n" + xmlStr;
            }

            int location = 0;
            int failCount = 0;
            int tokenTryCount = 0;
            while(location < xmlStr.Length)
            {
                string token = machine.GetNextToken(xmlStr.Substring(location), out XmlTokenType ttype);
                Color color = machine.GetTokenColor(ttype);
                bool isBold = ttype == XmlTokenType.DocTypeName || ttype == XmlTokenType.NodeName;
                box.AppendText(token, color, null, isBold);
                location += token.Length;
                tokenTryCount++;

                // Check for ongoing failure
                if(token.Length == 0) failCount++;
                if(failCount > 10 || tokenTryCount > xmlStr.Length)
                {
                    string theRestOfIt = xmlStr.Substring(location, xmlStr.Length - location);
                    //box.AppendText(Environment.NewLine + Environment.NewLine + theRestOfIt); // DEBUG
                    box.AppendText(theRestOfIt);
                    break;
                }
            }
        }

        public static void AppendText(this RichTextBox box, string text, Color color = default, Font font = null, bool isBold = false)
        {
            FontStyle fontStyle = isBold ? FontStyle.Bold : FontStyle.Regular;
            box.SelectionFont = new Font(font ?? box.Font, fontStyle);
            box.SelectionColor = color != default ? color : box.ForeColor;
            box.SelectionStart = box.TextLength;
            box.SelectionLength = 0;
            box.AppendText(text);
            box.SelectionColor = box.ForeColor;
        }

        sealed class XmlStateMachine
        {
            public XmlTokenType CurrentState = XmlTokenType.Unknown;
            private string subString = string.Empty;
            private string token = string.Empty;

            public string GetNextToken(string s, out XmlTokenType ttype)
            {
                ttype = XmlTokenType.Unknown;
                // skip past any whitespace (token added to it at the end of method)
                string whitespace = GetWhitespace(s);
                subString = s.TrimStart();
                token = string.Empty;
                if(CurrentState == XmlTokenType.CDataStart)
                {
                    // check for empty CDATA
                    if(subString.StartsWith("]]>"))
                    {
                        CurrentState = XmlTokenType.CDataEnd;
                        token = "]]>";
                    }
                    else
                    {
                        CurrentState = XmlTokenType.CDataValue;
                        int n = subString.IndexOf("]]>");
                        token = subString.Substring(0, n);
                    }
                }
                else if(CurrentState == XmlTokenType.DocTypeStart)
                {
                    CurrentState = XmlTokenType.DocTypeName;
                    token = "DOCTYPE";
                }
                else if(CurrentState == XmlTokenType.DocTypeName)
                {
                    CurrentState = XmlTokenType.DocTypeDeclaration;
                    int n = subString.IndexOf("[");
                    token = subString.Substring(0, n);
                }
                else if(CurrentState == XmlTokenType.DocTypeDeclaration)
                {
                    CurrentState = XmlTokenType.DocTypeDefStart;
                    token = "[";
                }
                else if(CurrentState == XmlTokenType.DocTypeDefStart)
                {
                    if(subString.StartsWith("]>"))
                    {
                        CurrentState = XmlTokenType.DocTypeDefEnd;
                        token = "]>";
                    }
                    else
                    {
                        CurrentState = XmlTokenType.DocTypeDefValue;
                        int n = subString.IndexOf("]>");
                        token = subString.Substring(0, n);
                    }
                }
                else if(CurrentState == XmlTokenType.DocTypeDefValue)
                {
                    CurrentState = XmlTokenType.DocTypeDefEnd;
                    token = "]>";
                }
                else if(CurrentState == XmlTokenType.DoubleQuotationMarkStart)
                {
                    // check for empty attribute value
                    if(subString[0] == '\"')
                    {
                        CurrentState = XmlTokenType.DoubleQuotationMarkEnd;
                        token = "\"";
                    }
                    else
                    {
                        CurrentState = XmlTokenType.AttributeValue;
                        int n = subString.IndexOf("\"");
                        token = subString.Substring(0, n);
                    }
                }
                else if(CurrentState == XmlTokenType.SingleQuotationMarkStart)
                {
                    // check for empty attribute value
                    if(subString[0] == '\'')
                    {
                        CurrentState = XmlTokenType.SingleQuotationMarkEnd;
                        token = "\'";
                    }
                    else
                    {
                        CurrentState = XmlTokenType.AttributeValue;
                        int n = subString.IndexOf("'");
                        token = subString.Substring(0, n);
                    }
                }
                else if(CurrentState == XmlTokenType.CommentStart)
                {
                    // check for empty comment
                    if(subString.StartsWith("-->"))
                    {
                        CurrentState = XmlTokenType.CommentEnd;
                        token = "-->";
                    }
                    else
                    {
                        CurrentState = XmlTokenType.CommentValue;
                        token = ReadCommentValue(subString);
                    }
                }
                else if(CurrentState == XmlTokenType.NodeStart)
                {
                    CurrentState = XmlTokenType.NodeName;
                    token = ReadNodeName(subString);
                }
                else if(CurrentState == XmlTokenType.XmlDeclarationStart)
                {
                    CurrentState = XmlTokenType.NodeName;
                    token = ReadNodeName(subString);
                }
                else if(CurrentState == XmlTokenType.NodeName)
                {
                    if(subString[0] != '/' &&
                        subString[0] != '>')
                    {
                        CurrentState = XmlTokenType.AttributeName;
                        token = ReadAttributeName(subString);
                    }
                    else
                    {
                        HandleReservedXmlToken();
                    }
                }
                else if(CurrentState == XmlTokenType.NodeEndValueStart)
                {
                    if(subString[0] == '<')
                    {
                        HandleReservedXmlToken();
                    }
                    else
                    {
                        CurrentState = XmlTokenType.NodeValue;
                        token = ReadNodeValue(subString);
                    }
                }
                else if(CurrentState == XmlTokenType.DoubleQuotationMarkEnd)
                {
                    HandleAttributeEnd();
                }
                else if(CurrentState == XmlTokenType.SingleQuotationMarkEnd)
                {
                    HandleAttributeEnd();
                }
                else
                {
                    HandleReservedXmlToken();
                }
                if(token != string.Empty)
                {
                    ttype = CurrentState;
                    return whitespace + token;
                }
                return string.Empty;
            }

            public Color GetTokenColor(XmlTokenType ttype)
            {
                switch(ttype)
                {
                    case XmlTokenType.NodeValue:
                    case XmlTokenType.EqualSignStart:
                    case XmlTokenType.EqualSignEnd:
                    case XmlTokenType.DoubleQuotationMarkStart:
                    case XmlTokenType.DoubleQuotationMarkEnd:
                    case XmlTokenType.SingleQuotationMarkStart:
                    case XmlTokenType.SingleQuotationMarkEnd:
                        return Color.DimGray;
                    case XmlTokenType.XmlDeclarationStart:
                    case XmlTokenType.XmlDeclarationEnd:
                    case XmlTokenType.NodeStart:
                    case XmlTokenType.NodeEnd:
                    case XmlTokenType.NodeEndValueStart:
                    case XmlTokenType.CDataStart:
                    case XmlTokenType.CDataEnd:
                    case XmlTokenType.CommentStart:
                    case XmlTokenType.CommentEnd:
                    case XmlTokenType.AttributeValue:
                    case XmlTokenType.DocTypeStart:
                    case XmlTokenType.DocTypeEnd:
                    case XmlTokenType.DocTypeDefStart:
                    case XmlTokenType.DocTypeDefEnd:
                        return Color.DimGray;
                    case XmlTokenType.CDataValue:
                    case XmlTokenType.DocTypeDefValue:
                        return Color.SkyBlue;
                    case XmlTokenType.CommentValue:
                        return Color.SkyBlue;
                    case XmlTokenType.DocTypeName:
                    case XmlTokenType.NodeName:
                        return Color.DarkCyan;
                    case XmlTokenType.AttributeName:
                    case XmlTokenType.DocTypeDeclaration:
                        return Color.DodgerBlue;
                    default:
                        return Color.DimGray;
                }
            }

            public string GetXmlDeclaration(string s)
            {
                int start = s.IndexOf("<?");
                int end = s.IndexOf("?>");
                if(start > -1 && end > start)
                {
                    return s.Substring(start, end - start + 2);
                }
                return string.Empty;
            }

            private void HandleAttributeEnd()
            {
                if(subString.StartsWith(">"))
                {
                    HandleReservedXmlToken();
                }
                else if(subString.StartsWith("/>"))
                {
                    HandleReservedXmlToken();
                }
                else if(subString.StartsWith("?>"))
                {
                    HandleReservedXmlToken();
                }
                else
                {
                    CurrentState = XmlTokenType.AttributeName;
                    token = ReadAttributeName(subString);
                }
            }

            private void HandleReservedXmlToken()
            {
                // check if state changer
                // <, >, =, </, />, <![CDATA[, <!--, -->
                if(subString.StartsWith("<![CDATA["))
                {
                    CurrentState = XmlTokenType.CDataStart;
                    token = "<![CDATA[";
                }
                else if(subString.StartsWith("<!DOCTYPE"))
                {
                    CurrentState = XmlTokenType.DocTypeStart;
                    token = "<!";
                }
                else if(subString.StartsWith("</"))
                {
                    CurrentState = XmlTokenType.NodeStart;
                    token = "</";
                }
                else if(subString.StartsWith("<!--"))
                {
                    CurrentState = XmlTokenType.CommentStart;
                    token = "<!--";
                }
                else if(subString.StartsWith("<?"))
                {
                    CurrentState = XmlTokenType.XmlDeclarationStart;
                    token = "<?";
                }
                else if(subString.StartsWith("<"))
                {
                    CurrentState = XmlTokenType.NodeStart;
                    token = "<";
                }
                else if(subString.StartsWith("="))
                {
                    CurrentState = XmlTokenType.EqualSignStart;
                    token = "=";
                }
                else if(subString.StartsWith("?>"))
                {
                    CurrentState = XmlTokenType.XmlDeclarationEnd;
                    token = "?>";
                }
                else if(subString.StartsWith(">"))
                {
                    CurrentState = XmlTokenType.NodeEndValueStart;
                    token = ">";
                }
                else if(subString.StartsWith("-->"))
                {
                    CurrentState = XmlTokenType.CommentEnd;
                    token = "-->";
                }
                else if(subString.StartsWith("]>"))
                {
                    CurrentState = XmlTokenType.DocTypeEnd;
                    token = "]>";
                }
                else if(subString.StartsWith("]]>"))
                {
                    CurrentState = XmlTokenType.CDataEnd;
                    token = "]]>";
                }
                else if(subString.StartsWith("/>"))
                {
                    CurrentState = XmlTokenType.NodeEnd;
                    token = "/>";
                }
                else if(subString.StartsWith("\""))
                {
                    if(CurrentState == XmlTokenType.AttributeValue)
                    {
                        CurrentState = XmlTokenType.DoubleQuotationMarkEnd;
                    }
                    else
                    {
                        CurrentState = XmlTokenType.DoubleQuotationMarkStart;
                    }
                    token = "\"";
                }
                else if(subString.StartsWith("'"))
                {
                    if(CurrentState == XmlTokenType.AttributeValue)
                    {
                        CurrentState = XmlTokenType.SingleQuotationMarkEnd;
                    }
                    else
                    {
                        CurrentState = XmlTokenType.SingleQuotationMarkStart;
                    }
                    token = "'";
                }
            }

            private string ReadNodeName(string s)
            {
                string nodeName = "";
                for(int i = 0; i < s.Length; i++)
                {
                    if(s[i] == '/' || s[i] == ' ' || s[i] == '>') return nodeName;
                    else nodeName += s[i].ToString();
                }
                return nodeName;
            }

            private string ReadAttributeName(string s)
            {
                string attName = "";
                int n = s.IndexOf('=');
                if(n != -1) attName = s.Substring(0, n);
                return attName;
            }

            private string ReadNodeValue(string s)
            {
                string nodeValue = "";
                int n = s.IndexOf('<');
                if(n != -1) nodeValue = s.Substring(0, n);
                return nodeValue;
            }

            private string ReadCommentValue(string s)
            {
                string commentValue = "";
                int n = s.IndexOf("-->");
                if(n != -1) commentValue = s.Substring(0, n);
                return commentValue;
            }

            private string GetWhitespace(string s)
            {
                string whitespace = "";
                for(int i = 0; i < s.Length; i++)
                {
                    char c = s[i];
                    if(char.IsWhiteSpace(c)) whitespace += c;
                    else break;
                }
                return whitespace;
            }
        }

        enum XmlTokenType
        {
            Whitespace, XmlDeclarationStart, XmlDeclarationEnd, NodeStart, NodeEnd, NodeEndValueStart, NodeName,
            NodeValue, AttributeName, AttributeValue, EqualSignStart, EqualSignEnd, CommentStart, CommentValue,
            CommentEnd, CDataStart, CDataValue, CDataEnd, DoubleQuotationMarkStart, DoubleQuotationMarkEnd,
            SingleQuotationMarkStart, SingleQuotationMarkEnd, DocTypeStart, DocTypeName, DocTypeDeclaration,
            DocTypeDefStart, DocTypeDefValue, DocTypeDefEnd, DocTypeEnd, DocumentEnd, Unknown
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ShellLink.cs
================================================
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Windows.Forms;
using ComTypes = System.Runtime.InteropServices.ComTypes;

namespace BluePointLilac.Methods
{
    public class ShellLink : IDisposable
    {
        [ComImport]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [Guid("000214F9-0000-0000-C000-000000000046")]
        interface IShellLinkW
        {
            void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref WIN32_FIND_DATAW pfd, uint fFlags);
            void GetIDList(out IntPtr ppidl);
            void SetIDList(IntPtr pidl);
            void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
            void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
            void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
            void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
            void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
            void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
            void GetHotKey(out ushort pwHotkey);
            void SetHotKey(ushort wHotKey);
            void GetShowCmd(out int piShowCmd);
            void SetShowCmd(int iShowCmd);
            void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);
            void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
            void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);
            void Resolve(IntPtr hwnd, uint fFlags);
            void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
        }

        [ComImport]
        [ClassInterface(ClassInterfaceType.None)]
        [Guid("00021401-0000-0000-C000-000000000046")]
        private class CShellLink { }

        [ComImport]
        [Guid("45e2b4ae-b1c3-11d0-b92f-00a0c90312e1")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IShellLinkDataList
        {
            void AddDataBlock(IntPtr pDataBlock);
            void CopyDataBlock(uint dwSig, out IntPtr ppDataBlock);
            void RemoveDataBlock(uint dwSig);
            void GetFlags(out ShellLinkDataFlags pdwFlags);
            void SetFlags(ShellLinkDataFlags dwFlags);
        }

        [Flags]
        enum ShellLinkDataFlags : uint
        {
            Default = 0x00000000,
            HasIdList = 0x00000001,
            HasLinkInfo = 0x00000002,
            HasName = 0x00000004,
            HasRelpath = 0x00000008,
            HasWorkingdir = 0x00000010,
            HasArgs = 0x00000020,
            HasIconLocation = 0x00000040,
            Unicode = 0x00000080,
            ForceNoLinkInfo = 0x00000100,
            HasExpSz = 0x00000200,
            RunInSeparate = 0x00000400,
            HasLogo3Id = 0x00000800,
            HasDarwinId = 0x00001000,
            RunasUser = 0x00002000,
            HasExpIconSz = 0x00004000,
            NoPidlAlias = 0x00008000,
            ForceUncname = 0x00010000,
            RunWithShimlayer = 0x00020000,
            ForceNoLinktrack = 0x00040000,
            EnableTargetMetadata = 0x00080000,
            DisableLinkPathTracking = 0x00100000,
            DisableKnownfolderRelativeTracking = 0x00200000,
            NoKFAlias = 0x00400000,
            AllowLinkToLink = 0x00800000,
            UnaliasOnSave = 0x01000000,
            PreferEnvironmentPath = 0x02000000,
            KeepLocalIdListForUncTarget = 0x04000000,
            Valid = 0x07fff7ff,
            Reserved = 0x80000000
        }

        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]
        struct WIN32_FIND_DATAW
        {
            public uint dwFileAttributes;
            public ComTypes.FILETIME ftCreationTime;
            public ComTypes.FILETIME ftLastAccessTime;
            public ComTypes.FILETIME ftLastWriteTime;
            public uint nFileSizeHigh;
            public uint nFileSizeLow;
            public uint dwReserved0;
            public uint dwReserved1;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
            public string cFileName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
            public string cAlternateFileName;
        }

        public struct ICONLOCATION
        {
            public string IconPath;
            public int IconIndex;
        }

        private const int MAX_PATH = 260;
        private const int INFOTIPSIZE = 1024;

        private const uint SLGP_UNCPRIORITY = 2;
        private const int STGM_READWRITE = 2;

        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMINNOACTIVE = 7;
        private const int SW_SHOWNORMAL = 1;

        private IShellLinkW shellLinkW = null;
        private IPersistFile PersistFile => (IPersistFile)shellLinkW;
        private IShellLinkDataList LinkDataList => (IShellLinkDataList)shellLinkW;

        public string ShortcutPath { get; private set; }

        public string TargetPath
        {
            get
            {
                StringBuilder targetPath = new StringBuilder(MAX_PATH);
                WIN32_FIND_DATAW data = new WIN32_FIND_DATAW();
                shellLinkW.GetPath(targetPath, targetPath.Capacity, ref data, SLGP_UNCPRIORITY);
                return targetPath.ToString();
            }
            set
            {
                shellLinkW.SetPath(value);
            }
        }

        public string Arguments
        {
            get
            {
                StringBuilder arguments = new StringBuilder(INFOTIPSIZE);
                shellLinkW.GetArguments(arguments, arguments.Capacity);
                return arguments.ToString();
            }
            set
            {
                shellLinkW.SetArguments(value);
            }
        }

        public string WorkingDirectory
        {
            get
            {
                StringBuilder dirPath = new StringBuilder(MAX_PATH);
                shellLinkW.GetWorkingDirectory(dirPath, dirPath.Capacity);
                return dirPath.ToString();
            }
            set
            {
                shellLinkW.SetWorkingDirectory(value);
            }
        }

        public ICONLOCATION IconLocation
        {
            get
            {
                StringBuilder iconPath = new StringBuilder(MAX_PATH);
                shellLinkW.GetIconLocation(iconPath, iconPath.Capacity, out int iconIndex);
                return new ICONLOCATION { IconPath = iconPath.ToString(), IconIndex = iconIndex };
            }
            set
            {
                shellLinkW.SetIconLocation(value.IconPath, value.IconIndex);
            }
        }

        public string IconPath => IconLocation.IconPath;

        public int IconIndex => IconLocation.IconIndex;

        public string Description
        {
            get
            {
                StringBuilder description = new StringBuilder(INFOTIPSIZE);
                shellLinkW.GetDescription(description, description.Capacity);
                return description.ToString();
            }
            set
            {
                shellLinkW.SetDescription(value);
            }
        }

        public Keys HotKey
        {
            get
            {
                shellLinkW.GetHotKey(out ushort key);
                int hotKey = ((key & 0xFF00) << 8) | (key & 0xFF);
                return (Keys)hotKey;
            }
            set
            {
                if((value & Keys.Modifiers) == 0) throw new ArgumentException("Hotkey must include a modifier key.");
                ushort key = unchecked((ushort)(((int)(value & Keys.Modifiers) >> 8) | (int)(value & Keys.KeyCode)));
                shellLinkW.SetHotKey(key);
            }
        }

        public FormWindowState WindowStyle
        {
            get
            {
                shellLinkW.GetShowCmd(out int style);
                switch(style)
                {
                    case SW_SHOWMINIMIZED:
                    case SW_SHOWMINNOACTIVE:
                        return FormWindowState.Minimized;
                    case SW_SHOWMAXIMIZED:
                        return FormWindowState.Maximized;
                    case SW_SHOWNORMAL:
                    default:
                        return FormWindowState.Normal;
                }
            }
            set
            {
                int style;
                switch(value)
                {
                    case FormWindowState.Minimized:
                        style = SW_SHOWMINIMIZED; break;
                    case FormWindowState.Maximized:
                        style = SW_SHOWMAXIMIZED; break;
                    case FormWindowState.Normal:
                    default:
                        style = SW_SHOWNORMAL; break;
                }
                shellLinkW.SetShowCmd(style);
            }
        }

        public bool RunAsAdministrator
        {
            get
            {
                LinkDataList.GetFlags(out ShellLinkDataFlags flags);
                return (flags & ShellLinkDataFlags.RunasUser) == ShellLinkDataFlags.RunasUser;
            }
            set
            {
                LinkDataList.GetFlags(out ShellLinkDataFlags flags);
                if(value) flags |= ShellLinkDataFlags.RunasUser;
                else flags &= ~ShellLinkDataFlags.RunasUser;
                LinkDataList.SetFlags(flags);
            }
        }

        public ShellLink(string lnkPath = null)
        {
            try { shellLinkW = (IShellLinkW)new CShellLink(); }
            catch { throw new COMException("Failed to create ShellLink object."); }
            Load(lnkPath);
        }

        ~ShellLink() { Dispose(false); }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if(shellLinkW == null) return;
            Marshal.FinalReleaseComObject(shellLinkW);
            shellLinkW = null;
        }

        public void Save() { Save(this.ShortcutPath); }

        public void Save(string lnkPath)
        {
            PersistFile.Save(lnkPath, true);
        }

        public void Load() { Load(this.ShortcutPath); }

        public void Load(string lnkPath)
        {
            this.ShortcutPath = lnkPath;
            if(File.Exists(lnkPath)) PersistFile.Load(lnkPath, STGM_READWRITE);
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs
================================================
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class SingleInstance
    {
        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);

        /// <summary>判断单实例程序是否正在运行</summary>
        /// <remarks>若正在运行激活窗口</remarks>
        public static bool IsRunning()
        {
            using(Process current = Process.GetCurrentProcess())
            {
                foreach(Process process in Process.GetProcessesByName(current.ProcessName))
                {
                    using(process)
                    {
                        if(process.Id == current.Id) continue;
                        if(process.MainModule.FileName == current.MainModule.FileName)
                        {
                            const int SW_RESTORE = 9;
                            ShowWindowAsync(process.MainWindowHandle, SW_RESTORE);
                            SetForegroundWindow(process.MainWindowHandle);
                            return true;
                        }
                    }
                }
                return false;
            }
        }

        /// <summary>重启单实例程序</summary>
        /// <param name="args">重启程序时传入参数</param>
        /// <param name="updatePath">用于更新程序的新版本文件路径,为null则为普通重启</param>
        public static void Restart(string[] args = null, string updatePath = null)
        {
            string appPath = Application.ExecutablePath;
            string command = appPath;
            if(args != null && args.Length > 0) command += "," + string.Join(" ", args);
            List<string> contents = new List<string>();
            //vbs命令逐行执行不等待,故加些代码确定上一条命令执行是否完成
            contents.AddRange(new[]
            {
                "On Error Resume Next",
                "WScript.Sleep 1000",//等待程序结束
                "Dim wsh, fso",
                "Set wsh = CreateObject(\"WScript.Shell\")",
                "Set fso = CreateObject(\"Scripting.FileSystemObject\")",
            });

            if(File.Exists(updatePath))
            {
                contents.AddRange(new[]
                {
                    $"fso.DeleteFile \"{appPath}\"",
                    $"Do While fso.FileExists(\"{appPath}\")",
                        "WScript.Sleep 100",
                    "Loop",//确定文件删除完成
                    $"fso.MoveFile \"{updatePath}\",\"{appPath}\"",//更新文件
                    $"Do While fso.FileExists(\"{updatePath}\")",//确定文件已被移动
                        "WScript.Sleep 100",
                    $"Loop",
                });
            }
            contents.AddRange(new[]
            {
                $"wsh.Run \"{command}\"",
                "fso.DeleteFile(WScript.ScriptFullName)",//vbs自删命令
                "Set wsh = Nothing",
                "Set fso = Nothing",
            });

            string vbsPath = Path.GetTempPath() + Guid.NewGuid() + ".vbs";
            File.WriteAllLines(vbsPath, contents.ToArray(), Encoding.Unicode);
            Application.Exit();
            using(Process process = new Process())
            {
                process.StartInfo.FileName = "wscript.exe";
                process.StartInfo.Arguments = vbsPath;
                process.Start();
            }
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/StringExtension.cs
================================================
namespace BluePointLilac.Methods
{
    //为兼容.Net Framework 3.5,无法引用Microsoft.CSharp.dll(中的string.IsNullOrWhiteSpace)写了这个扩展方法
    public static class StringExtension
    {
        public static bool IsNullOrWhiteSpace(this string str)
        {
            if(string.IsNullOrEmpty(str)) return true;
            return str.Trim().Length == 0;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/TextBoxExtension.cs
================================================
using System.Drawing;
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class TextBoxExtension
    {
        /// <summary>TextBox仿RichTextBox按住Ctrl加鼠标滚轮放缩字体</summary>
        public static void CanResizeFont(this TextBox box)
        {
            box.MouseWheel += (sender, e) =>
            {
                if(Control.ModifierKeys != Keys.Control) return;
                float size = box.Font.Size;
                if(size < 8F && e.Delta < 0) return;
                if(size > 40F && e.Delta > 0) return;
                box.Font = new Font(box.Font.FontFamily, size + (e.Delta > 0 ? 1F : -1F));
            };
        }

        /// <summary>TextBox在文字未超出边界时隐藏滚动条,超出时显示</summary>
        public static void SetAutoShowScroll(this TextBox box, ScrollBars scrollBars)
        {

            void SetScrollVisible()
            {
                Size szBox = box.ClientSize;
                Size szText = TextRenderer.MeasureText(box.Text, box.Font);
                if((scrollBars | ScrollBars.Vertical) == ScrollBars.Vertical)
                {
                    if(szText.Height > szBox.Height)
                    {
                        box.ScrollBars = scrollBars | ScrollBars.Vertical;
                    }
                    else
                    {
                        box.ScrollBars = scrollBars & ~ScrollBars.Vertical;
                    }
                }
                if((scrollBars | ScrollBars.Horizontal) == ScrollBars.Horizontal)
                {
                    if(szText.Width > szBox.Width)
                    {
                        box.ScrollBars = scrollBars | ScrollBars.Horizontal;
                    }
                    else
                    {
                        box.ScrollBars = scrollBars & ~ScrollBars.Horizontal;
                    }
                }
            };
            box.TextChanged += (sender, e) => SetScrollVisible();
            box.FontChanged += (sender, e) => SetScrollVisible();
            box.ClientSizeChanged += (sender, e) => SetScrollVisible();
        }

        /// <summary>TextBox只读时可以使用Ctrl+A全选快捷键</summary>
        public static void CanSelectAllWhenReadOnly(this TextBox box)
        {
            box.KeyDown += (sender, e) =>
            {
                if(box.ReadOnly && e.Control && e.KeyCode == Keys.A) box.SelectAll();
            };
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/ToolTipBox.cs
================================================
using System.Windows.Forms;

namespace BluePointLilac.Methods
{
    public static class ToolTipBox
    {
        public static void SetToolTip(Control ctr, string tip)
        {
            if(tip.IsNullOrWhiteSpace()) return;
            ToolTip toolTip = new ToolTip { InitialDelay = 1 };
            toolTip.SetToolTip(ctr, tip);
            ctr.Disposed += (sender, e) => toolTip.Dispose();
        }

        public static void SetToolTip(ToolStripItem item, string tip)
        {
            //必须先设置item的Owner
            item.Owner.ShowItemToolTips = true;
            item.ToolTipText = tip;
        }
    }
}

================================================
FILE: ContextMenuManager/BluePointLilac.Methods/WinOsVersion.cs
================================================
using System;

namespace BluePointLilac.Methods
{
    // 判断Windows系统版本
    // https://docs.microsoft.com/windows/release-health/release-information
    public static class WinOsVersion
    {
        public static readonly Version Current = Environment.OSVersion.Version;
        public static readonly Version Win10 = new Version(10, 0);
        public static readonly Version Win8_1 = new Version(6, 3);
        public static readonly Version Win8 = new Version(6, 2);
        public static readonly Version Win7 = new Version(6, 1);
        public static readonly Version Vista = new Version(6, 0);
        public static readonly Version XP = new Version(5, 1);

        public static readonly Version Win10_1507 = new Version(10, 0, 10240);
        public static readonly Version Win10_1511 = new Version(10, 0, 10586);
        public static readonly Version Win10_1607 = new Version(10, 0, 14393);
        public static readonly Version Win10_1703 = new Version(10, 0, 15063);
        public static readonly Version Win10_1709 = new Version(10, 0, 16299);
        public static readonly Version Win10_1803 = new Version(10, 0, 17134);
        public static readonly Version Win10_1809 = new Version(10, 0, 17763);
        public static readonly Version Win10_1903 = new Version(10, 0, 18362);
        public static readonly Version Win10_1909 = new Version(10, 0, 18363);
        public static readonly Version Win10_2004 = new Version(10, 0, 19041);
        public static readonly Version Win10_20H2 = new Version(10, 0, 19042);
    }
}

================================================
FILE: ContextMenuManager/ContextMenuManager.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}</ProjectGuid>
    <OutputType>WinExe</OutputType>
    <RootNamespace>ContextMenuManager</RootNamespace>
    <AssemblyName>ContextMenuManager</AssemblyName>
    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <Deterministic>true</Deterministic>
    <IsWebBootstrapper>false</IsWebBootstrapper>
    <TargetFrameworkProfile />
    <PublishUrl>C:\Users\Lilac\Desktop\</PublishUrl>
    <Install>true</Install>
    <InstallFrom>Disk</InstallFrom>
    <UpdateEnabled>false</UpdateEnabled>
    <UpdateMode>Foreground</UpdateMode>
    <UpdateInterval>7</UpdateInterval>
    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
    <UpdatePeriodically>false</UpdatePeriodically>
    <UpdateRequired>false</UpdateRequired>
    <MapFileExtensions>true</MapFileExtensions>
    <ApplicationRevision>0</ApplicationRevision>
    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
    <UseApplicationTrust>false</UseApplicationTrust>
    <PublishWizardCompleted>true</PublishWizardCompleted>
    <BootstrapperEnabled>true</BootstrapperEnabled>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>send</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>
    <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
    <DocumentationFile>
    </DocumentationFile>
    <FileAlignment>4096</FileAlignment>
    <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>none</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <Prefer32Bit>false</Prefer32Bit>
    <FileAlignment>4096</FileAlignment>
    <DebugSymbols>false</DebugSymbols>
    <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
  </PropertyGroup>
  <PropertyGroup>
    <ApplicationIcon>Properties\AppIcon.ico</ApplicationIcon>
  </PropertyGroup>
  <PropertyGroup>
    <TargetZone>Custom</TargetZone>
  </PropertyGroup>
  <PropertyGroup>
    <GenerateManifests>false</GenerateManifests>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup>
    <SignManifests>false</SignManifests>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup>
    <Win32Resource>
    </Win32Resource>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup>
    <StartupObject>ContextMenuManager.Program</StartupObject>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup>
    <ManifestCertificateThumbprint>BEFE3AE42DB8F7604D715C01388001CABFF0FABF</ManifestCertificateThumbprint>
  </PropertyGroup>
  <PropertyGroup>
    <ManifestKeyFile>ContextMenuManager_TemporaryKey.pfx</ManifestKeyFile>
  </PropertyGroup>
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup />
  <PropertyGroup>
    <ApplicationManifest>Properties\App.manifest</ApplicationManifest>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="PresentationFramework" />
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Data" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Deployment" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Management" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.ServiceModel.Web" />
    <Reference Include="System.Web" />
    <Reference Include="System.Windows.Forms" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Xml.Linq" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="Controls\DetailedEditDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\DictionariesBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\DonateBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\EnhanceMenusDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\IBtnDeleteItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\LanguagesBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\SubItemsForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Controls\SwitchDicList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Methods\AppConfig.cs" />
    <Compile Include="BluePointLilac.Methods\FormExtension.cs" />
    <Compile Include="BluePointLilac.Methods\MessageBoxEx.cs" />
    <Compile Include="BluePointLilac.Methods\ToolTipBox.cs" />
    <Compile Include="BluePointLilac.Controls\ReadOnlyTextBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\ResizeLimitedForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\MyToolBar.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Methods\ComboBoxExtension.cs" />
    <Compile Include="Methods\DesktopIni.cs" />
    <Compile Include="BluePointLilac.Methods\DirectoryEx.cs" />
    <Compile Include="BluePointLilac.Methods\ElevatedFileDroper.cs" />
    <Compile Include="BluePointLilac.Methods\FileExtension.cs" />
    <Compile Include="BluePointLilac.Methods\GuidEx.cs" />
    <Compile Include="BluePointLilac.Methods\IniReader.cs" />
    <Compile Include="BluePointLilac.Methods\IniWriter.cs" />
    <Compile Include="Methods\AppMessageBox.cs" />
    <Compile Include="BluePointLilac.Methods\ExternalProgram.cs" />
    <Compile Include="BluePointLilac.Methods\RichTextBoxExtension.cs" />
    <Compile Include="BluePointLilac.Methods\SingleInstance.cs" />
    <Compile Include="BluePointLilac.Methods\StringExtension.cs" />
    <Compile Include="BluePointLilac.Methods\TextBoxExtension.cs" />
    <Compile Include="BluePointLilac.Controls\UAWebClient.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Methods\UwpHelper.cs" />
    <Compile Include="BluePointLilac.Methods\WinOsVersion.cs" />
    <Compile Include="BluePointLilac.Methods\ShellLink.cs" />
    <Compile Include="Methods\WinXHasher.cs" />
    <Compile Include="BluePointLilac.Controls\DownloadDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\FileExtensionDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\EnhanceMenusItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\EnhanceMenusList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\IEItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\IEList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\IBtnMoveUpDownItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\IProtectOpenItem.cs" />
    <Compile Include="Controls\Interfaces\ITsiAdministratorItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiGuidItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiShortcutCommandItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiRegExportItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\NewIEDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\NewLnkFileDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\SelectDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellExecuteDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellStoreDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\FoldSubItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiDeleteItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiCommandItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiFilePathItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiIconItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiTextItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiRegPathItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\IBtnShowMenuItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\IChkVisibleItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\Interfaces\ITsiWebSearchItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\NewItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\NewItemForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="Controls\AppSettingBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\GuidBlockedItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\GuidBlockedList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\NewOpenWithDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\NewShellDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\OpenWithList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\RuleItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\OpenWithItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ExplorerRestarter.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\SendToItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\SendToList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellNewItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellNewList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\DetailedEditList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\UwpModeItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\WinXGroupItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\WinXItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\WinXList.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="MainForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\IconDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\InputDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\MyCheckBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\MyListBox.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\MyMainForm.cs">
      <SubType>Form</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\MySideBar.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\MyStatusBar.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellSubMenuDialog.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Controls\PictureButton.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellExItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="Controls\ShellItem.cs">
      <SubType>Component</SubType>
    </Compile>
    <Compile Include="BluePointLilac.Methods\ControlExtension.cs" />
    <Compile Include="BluePointLilac.Methods\HighDpi.cs" />
    <Compile Include="BluePointLilac.Methods\RegistryEx.cs" />
    <Compile Include="BluePointLilac.Methods\RegTrustedInstaller.cs" />
    <Compile Include="Methods\AppString.cs" />
    <Compile Include="Methods\AppImage.cs" />
    <Compile Include="BluePointLilac.Methods\EncodingType.cs" />
    <Co
Download .txt
gitextract_o6208a9c/

├── .gitattributes
├── .gitignore
├── ContextMenuManager/
│   ├── App.config
│   ├── BluePointLilac.Controls/
│   │   ├── DownloadDialog.cs
│   │   ├── IconDialog.cs
│   │   ├── InputDialog.cs
│   │   ├── MyCheckBox.cs
│   │   ├── MyListBox.cs
│   │   ├── MyMainForm.cs
│   │   ├── MySideBar.cs
│   │   ├── MyStatusBar.cs
│   │   ├── MyToolBar.cs
│   │   ├── PictureButton.cs
│   │   ├── ReadOnlyTextBox.cs
│   │   ├── ResizeLimitedForm.cs
│   │   ├── SelectDialog.cs
│   │   └── UAWebClient.cs
│   ├── BluePointLilac.Methods/
│   │   ├── ComboBoxExtension.cs
│   │   ├── ControlExtension.cs
│   │   ├── DirectoryEx.cs
│   │   ├── ElevatedFileDroper.cs
│   │   ├── EncodingType.cs
│   │   ├── ExternalProgram.cs
│   │   ├── FileExtension.cs
│   │   ├── FormExtension.cs
│   │   ├── GuidEx.cs
│   │   ├── HighDpi.cs
│   │   ├── ImageExtension.cs
│   │   ├── IniReader.cs
│   │   ├── IniWriter.cs
│   │   ├── MessageBoxEx.cs
│   │   ├── RegTrustedInstaller.cs
│   │   ├── RegistryEx.cs
│   │   ├── ResourceIcon.cs
│   │   ├── ResourceString.cs
│   │   ├── RichTextBoxExtension.cs
│   │   ├── ShellLink.cs
│   │   ├── SingleInstance.cs
│   │   ├── StringExtension.cs
│   │   ├── TextBoxExtension.cs
│   │   ├── ToolTipBox.cs
│   │   └── WinOsVersion.cs
│   ├── ContextMenuManager.csproj
│   ├── Controls/
│   │   ├── AppSettingBox.cs
│   │   ├── DetailedEditDialog.cs
│   │   ├── DetailedEditList.cs
│   │   ├── DictionariesBox.cs
│   │   ├── DonateBox.cs
│   │   ├── EnhanceMenusDialog.cs
│   │   ├── EnhanceMenusItem.cs
│   │   ├── EnhanceMenusList.cs
│   │   ├── ExplorerRestarter.cs
│   │   ├── FileExtensionDialog.cs
│   │   ├── FoldSubItem.cs
│   │   ├── GuidBlockedItem.cs
│   │   ├── GuidBlockedList.cs
│   │   ├── IEItem.cs
│   │   ├── IEList.cs
│   │   ├── Interfaces/
│   │   │   ├── IBtnDeleteItem.cs
│   │   │   ├── IBtnMoveUpDownItem.cs
│   │   │   ├── IBtnShowMenuItem.cs
│   │   │   ├── IChkVisibleItem.cs
│   │   │   ├── IProtectOpenItem.cs
│   │   │   ├── ITsiAdministratorItem.cs
│   │   │   ├── ITsiCommandItem.cs
│   │   │   ├── ITsiDeleteItem.cs
│   │   │   ├── ITsiFilePathItem.cs
│   │   │   ├── ITsiGuidItem.cs
│   │   │   ├── ITsiIconItem.cs
│   │   │   ├── ITsiRegExportItem.cs
│   │   │   ├── ITsiRegPathItem.cs
│   │   │   ├── ITsiShortcutCommandItem.cs
│   │   │   ├── ITsiTextItem.cs
│   │   │   └── ITsiWebSearchItem.cs
│   │   ├── LanguagesBox.cs
│   │   ├── NewIEDialog.cs
│   │   ├── NewItem.cs
│   │   ├── NewItemForm.cs
│   │   ├── NewLnkFileDialog.cs
│   │   ├── NewOpenWithDialog.cs
│   │   ├── NewShellDialog.cs
│   │   ├── OpenWithItem.cs
│   │   ├── OpenWithList.cs
│   │   ├── RuleItem.cs
│   │   ├── SendToItem.cs
│   │   ├── SendToList.cs
│   │   ├── ShellExItem.cs
│   │   ├── ShellExecuteDialog.cs
│   │   ├── ShellItem.cs
│   │   ├── ShellList.cs
│   │   ├── ShellNewItem.cs
│   │   ├── ShellNewList.cs
│   │   ├── ShellStoreDialog.cs
│   │   ├── ShellSubMenuDialog.cs
│   │   ├── SubItemsForm.cs
│   │   ├── SwitchDicList.cs
│   │   ├── UwpModeItem.cs
│   │   ├── WinXGroupItem.cs
│   │   ├── WinXItem.cs
│   │   └── WinXList.cs
│   ├── MainForm.cs
│   ├── Methods/
│   │   ├── AppConfig.cs
│   │   ├── AppImage.cs
│   │   ├── AppMessageBox.cs
│   │   ├── AppString.cs
│   │   ├── DesktopIni.cs
│   │   ├── GuidInfo.cs
│   │   ├── ObjectPath.cs
│   │   ├── Updater.cs
│   │   ├── UwpHelper.cs
│   │   ├── WinXHasher.cs
│   │   └── XmlDicHelper.cs
│   ├── Program.cs
│   └── Properties/
│       ├── App.manifest
│       ├── AssemblyInfo.cs
│       ├── Resources/
│       │   ├── ShellNew/
│       │   │   ├── 0.c
│       │   │   ├── 0.html
│       │   │   ├── 0.reg
│       │   │   ├── 0.rtf
│       │   │   ├── 0.xlsx
│       │   │   └── 0.xml
│       │   └── Texts/
│       │       ├── AppLanguageDic.ini
│       │       ├── DetailedEditDic.xml
│       │       ├── EnhanceMenusDic.xml
│       │       ├── GuidInfosDic.ini
│       │       └── UwpModeItemsDic.xml
│       ├── Resources.Designer.cs
│       ├── Resources.resx
│       ├── Settings.Designer.cs
│       └── Settings.settings
├── ContextMenuManager.sln
├── Donate.md
├── LICENSE
├── Logo/
│   └── Logo.psd
├── README-en.md
├── README.md
├── Update.ini
└── languages/
    ├── ar-DZ عربية
    ├── de-DE.ini
    ├── en-US.ini
    ├── ja-JP.ini
    ├── ko-KR.ini
    ├── pt-BR.ini
    ├── ru-RU.ini
    ├── zh-CN.ini
    └── zh-TW.ini
Download .txt
SYMBOL INDEX (875 symbols across 112 files)

FILE: ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs
  class DownloadDialog (line 10) | sealed class DownloadDialog : CommonDialog
    method Reset (line 15) | public override void Reset() { }
    method RunDialog (line 17) | protected override bool RunDialog(IntPtr hwndOwner)
    class DownloadForm (line 29) | sealed class DownloadForm : Form
      method DownloadForm (line 31) | public DownloadForm()
      method InitializeComponents (line 59) | private void InitializeComponents()
      method DownloadFile (line 68) | private void DownloadFile(string url, string filePath)
      method OnLoad (line 99) | protected override void OnLoad(EventArgs e)

FILE: ContextMenuManager/BluePointLilac.Controls/IconDialog.cs
  class IconDialog (line 8) | public sealed class IconDialog : CommonDialog
    method PickIconDlg (line 10) | [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "#62...
    method Reset (line 18) | public override void Reset() { }
    method RunDialog (line 20) | protected override bool RunDialog(IntPtr hwndOwner)

FILE: ContextMenuManager/BluePointLilac.Controls/InputDialog.cs
  class InputDialog (line 8) | public sealed class InputDialog : CommonDialog
    method Reset (line 16) | public override void Reset() { }
    method RunDialog (line 18) | protected override bool RunDialog(IntPtr hwndOwner)
    class InputBox (line 33) | sealed class InputBox : Form
      method InputBox (line 35) | public InputBox()
      method InitializeComponents (line 76) | private void InitializeComponents()

FILE: ContextMenuManager/BluePointLilac.Controls/MyCheckBox.cs
  class MyCheckBox (line 10) | [DefaultProperty("Checked")]
    method MyCheckBox (line 13) | public MyCheckBox()
    method SwitchImage (line 60) | private Image SwitchImage(bool value)
    method OnMouseDown (line 65) | protected override void OnMouseDown(MouseEventArgs e)
    method DrawImage (line 74) | private static Image DrawImage(bool value)

FILE: ContextMenuManager/BluePointLilac.Controls/MyListBox.cs
  class MyListBox (line 9) | public class MyListBox : Panel
    method MyListBox (line 11) | public MyListBox()
    method OnMouseWheel (line 17) | protected override void OnMouseWheel(MouseEventArgs e)
  class MyList (line 24) | public class MyList : FlowLayoutPanel
    method MyList (line 32) | public MyList(MyListBox owner) : this()
    method MyList (line 37) | public MyList()
    method AddItem (line 73) | public void AddItem(MyListItem item)
    method AddItems (line 85) | public void AddItems(MyListItem[] items)
    method AddItems (line 90) | public void AddItems(List<MyListItem> items)
    method SetItemIndex (line 95) | public void SetItemIndex(MyListItem item, int newIndex)
    method GetItemIndex (line 100) | public int GetItemIndex(MyListItem item)
    method InsertItem (line 105) | public void InsertItem(MyListItem item, int index)
    method ClearItems (line 112) | public virtual void ClearItems()
    method SortItemByText (line 125) | public void SortItemByText()
    class TextComparer (line 134) | public class TextComparer : IComparer<MyListItem>
      method Compare (line 136) | public int Compare(MyListItem x, MyListItem y)
  class MyListItem (line 147) | public class MyListItem : Panel
    method MyListItem (line 149) | public MyListItem()
    method OnMouseDown (line 238) | protected override void OnMouseDown(MouseEventArgs e)
    method CenterControl (line 243) | private void CenterControl(Control ctr)
    method AddCtr (line 260) | public void AddCtr(Control ctr)
    method AddCtr (line 265) | public void AddCtr(Control ctr, int space)
    method AddCtrs (line 276) | public void AddCtrs(Control[] ctrs)
    method RemoveCtrAt (line 281) | public void RemoveCtrAt(int index)
    method GetCtrIndex (line 286) | public int GetCtrIndex(Control ctr)
    method SetCtrIndex (line 291) | public void SetCtrIndex(Control ctr, int newIndex)

FILE: ContextMenuManager/BluePointLilac.Controls/MyMainForm.cs
  class MyMainForm (line 8) | public class MyMainForm : Form
    method MyMainForm (line 10) | public MyMainForm()
    method OnResize (line 38) | protected override void OnResize(EventArgs e)
    method WndProc (line 44) | protected override void WndProc(ref Message m)

FILE: ContextMenuManager/BluePointLilac.Controls/MySideBar.cs
  class MySideBar (line 8) | public sealed class MySideBar : Panel
    method MySideBar (line 10) | public MySideBar()
    method GetItemWidth (line 102) | public int GetItemWidth(string str)
    method PaintItems (line 108) | private void PaintItems()
    method RefreshItem (line 134) | private void RefreshItem(Panel panel, int index)
    method PaintItem (line 143) | private void PaintItem(object sender, PaintEventArgs e)
    method ShowItem (line 152) | private void ShowItem(Panel panel, MouseEventArgs e)
    method OnMouseMove (line 169) | protected override void OnMouseMove(MouseEventArgs e)
    method OnMouseDown (line 174) | protected override void OnMouseDown(MouseEventArgs e)
    method OnMouseLeave (line 179) | protected override void OnMouseLeave(EventArgs e)

FILE: ContextMenuManager/BluePointLilac.Controls/MyStatusBar.cs
  class MyStatusBar (line 9) | public sealed class MyStatusBar : Panel
    method MyStatusBar (line 13) | public MyStatusBar()
    method OnPaint (line 26) | protected override void OnPaint(PaintEventArgs e)
    method OnResize (line 48) | protected override void OnResize(EventArgs e)
    method OnTextChanged (line 52) | protected override void OnTextChanged(EventArgs e)
    method OnFontChanged (line 56) | protected override void OnFontChanged(EventArgs e)
    method OnForeColorChanged (line 60) | protected override void OnForeColorChanged(EventArgs e)
    method OnBackColorChanged (line 64) | protected override void OnBackColorChanged(EventArgs e)

FILE: ContextMenuManager/BluePointLilac.Controls/MyToolBar.cs
  class MyToolBar (line 8) | public sealed class MyToolBar : FlowLayoutPanel
    method MyToolBar (line 10) | public MyToolBar()
    method AddButton (line 56) | public void AddButton(MyToolBarButton button)
    method AddButtons (line 76) | public void AddButtons(MyToolBarButton[] buttons)
  class MyToolBarButton (line 84) | public sealed class MyToolBarButton : Panel
    method MyToolBarButton (line 86) | public MyToolBarButton(Image image, string text)
    method OnResize (line 135) | protected override void OnResize(EventArgs e)

FILE: ContextMenuManager/BluePointLilac.Controls/PictureButton.cs
  class PictureButton (line 7) | public class PictureButton : PictureBox
    method PictureButton (line 9) | public PictureButton(Image image)
    method OnMouseEnter (line 27) | protected override void OnMouseEnter(EventArgs e)
    method OnMouseLeave (line 31) | protected override void OnMouseLeave(EventArgs e)
    method OnMouseDown (line 36) | protected override void OnMouseDown(MouseEventArgs e)

FILE: ContextMenuManager/BluePointLilac.Controls/ReadOnlyTextBox.cs
  class ReadOnlyTextBox (line 8) | public sealed class ReadOnlyTextBox : TextBox
    method ReadOnlyTextBox (line 10) | public ReadOnlyTextBox()
    method WndProc (line 23) | protected override void WndProc(ref Message m)
    method OnMouseEnter (line 35) | protected override void OnMouseEnter(EventArgs e)
  class ReadOnlyRichTextBox (line 43) | public sealed class ReadOnlyRichTextBox : RichTextBox
    method ReadOnlyRichTextBox (line 45) | public ReadOnlyRichTextBox()
    method WndProc (line 59) | protected override void WndProc(ref Message m)
    method OnMouseEnter (line 71) | protected override void OnMouseEnter(EventArgs e)
    method OnLinkClicked (line 78) | protected override void OnLinkClicked(LinkClickedEventArgs e)

FILE: ContextMenuManager/BluePointLilac.Controls/ResizeLimitedForm.cs
  class ResizeLimitedForm (line 7) | public class ResizeLimitedForm : Form
    method WndProc (line 15) | protected override void WndProc(ref Message m)
    type HitTest (line 43) | enum HitTest : int

FILE: ContextMenuManager/BluePointLilac.Controls/SelectDialog.cs
  class SelectDialog (line 8) | public class SelectDialog : CommonDialog
    method Reset (line 16) | public override void Reset() { }
    method RunDialog (line 18) | protected override bool RunDialog(IntPtr hwndOwner)
    class SelectForm (line 39) | sealed class SelectForm : Form
      method SelectForm (line 41) | public SelectForm()
      method InitializeComponents (line 108) | private void InitializeComponents()

FILE: ContextMenuManager/BluePointLilac.Controls/UAWebClient.cs
  class UAWebClient (line 10) | public sealed class UAWebClient : WebClient
    method UAWebClient (line 12) | public UAWebClient()
    method GetWebString (line 28) | public string GetWebString(string url)
    method WebStringToFile (line 42) | public bool WebStringToFile(string filePath, string fileUrl)
    method GetWebJsonToXml (line 51) | public XmlDocument GetWebJsonToXml(string url)

FILE: ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs
  class ComboBoxExtension (line 6) | public static class ComboBoxExtension
    method AutosizeDropDownWidth (line 8) | public static void AutosizeDropDownWidth(this ComboBox box)

FILE: ContextMenuManager/BluePointLilac.Methods/ControlExtension.cs
  class ControlExtension (line 7) | public static class ControlExtension
    method PostMessage (line 9) | [DllImport("user32.dll")]
    method ReleaseCapture (line 12) | [DllImport("user32.dll")]
    method CanMoveForm (line 17) | public static void CanMoveForm(this Control ctr)
    method SetWindowLong (line 29) | [DllImport("user32.dll")]
    method GetWindowLong (line 32) | [DllImport("user32.dll")]
    method SetEnabled (line 39) | public static void SetEnabled(this Control ctr, bool enabled)

FILE: ContextMenuManager/BluePointLilac.Methods/DirectoryEx.cs
  class DirectoryEx (line 5) | public static class DirectoryEx
    method CopyTo (line 7) | public static void CopyTo(string srcDirPath, string dstDirPath)

FILE: ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs
  class ElevatedFileDroper (line 18) | public sealed class ElevatedFileDroper : IMessageFilter
    method ChangeWindowMessageFilterEx (line 20) | [DllImport("user32.dll", SetLastError = true)]
    method ChangeWindowMessageFilter (line 24) | [DllImport("user32.dll", SetLastError = true)]
    method DragAcceptFiles (line 28) | [DllImport("shell32.dll", SetLastError = false)]
    method DragQueryFile (line 31) | [DllImport("shell32.dll", SetLastError = false, CharSet = CharSet.Unic...
    method DragQueryPoint (line 34) | [DllImport("shell32.dll", SetLastError = false)]
    method DragFinish (line 37) | [DllImport("shell32.dll", SetLastError = false)]
    type ChangeFilterStruct (line 40) | [StructLayout(LayoutKind.Sequential)]
    type ChangeWindowMessageFilterFlags (line 47) | enum ChangeWindowMessageFilterFlags : uint
    type ChangeFilterAction (line 53) | enum ChangeFilterAction : uint
    type ChangeFilterStatu (line 60) | enum ChangeFilterStatu : uint
    method ElevatedFileDroper (line 76) | public ElevatedFileDroper(Control ctr)
    method PreFilterMessage (line 119) | public bool PreFilterMessage(ref Message m)

FILE: ContextMenuManager/BluePointLilac.Methods/EncodingType.cs
  class EncodingType (line 10) | public static class EncodingType
    method GetType (line 26) | public static Encoding GetType(string filePath)
    method IsUTF8Bytes (line 42) | private static bool IsUTF8Bytes(byte[] bytes)

FILE: ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs
  class ExternalProgram (line 12) | public static class ExternalProgram
    method JumpRegEdit (line 18) | public static void JumpRegEdit(string regPath, string valueName = null...
    method JumpExplorer (line 87) | public static void JumpExplorer(string filePath, bool moreOpen = false)
    method OpenDirectory (line 110) | public static void OpenDirectory(string dirPath)
    method ShowPropertiesDialog (line 122) | public static bool ShowPropertiesDialog(string filePath)
    method ShowOpenWithDialog (line 139) | public static void ShowOpenWithDialog(string extension)
    method RestartExplorer (line 160) | public static void RestartExplorer()
    method OpenWebUrl (line 180) | public static void OpenWebUrl(string url)
    method ExportRegistry (line 196) | public static void ExportRegistry(string regPath, string filePath)
    method OpenNotepadWithText (line 209) | public static void OpenNotepadWithText(string text)
    method ShowWindowAsync (line 228) | [DllImport("user32.dll")]
    method SetForegroundWindow (line 231) | [DllImport("user32.dll")]
    method SetFocus (line 234) | [DllImport("user32.dll")]
    method GetWindowThreadProcessId (line 237) | [DllImport("user32.dll", CharSet = CharSet.Auto)]
    method FindWindow (line 240) | [DllImport("user32.dll")]
    method FindWindowEx (line 243) | [DllImport("user32.dll")]
    method SendMessage (line 246) | [DllImport("user32.dll")]
    method ILFree (line 249) | [DllImport("shell32.dll", ExactSpelling = true)]
    method ILCreateFromPathW (line 252) | [DllImport("shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = t...
    method SHOpenFolderAndSelectItems (line 255) | [DllImport("shell32.dll", ExactSpelling = true)]
    method ShellExecuteEx (line 258) | [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    type SHELLEXECUTEINFO (line 261) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

FILE: ContextMenuManager/BluePointLilac.Methods/FileExtension.cs
  class FileExtension (line 8) | public static class FileExtension
    type AssocF (line 10) | [Flags]
    type AssocStr (line 26) | public enum AssocStr
    method AssocQueryString (line 40) | [DllImport("shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)]
    method GetExtentionInfo (line 47) | public static string GetExtentionInfo(AssocStr assocStr, string extens...
    method GetOpenMode (line 56) | public static string GetOpenMode(string extension)

FILE: ContextMenuManager/BluePointLilac.Methods/FormExtension.cs
  class FormExtension (line 6) | public static class FormExtension
    method MoveAsMove (line 11) | public static void MoveAsMove(this Form frm1, Form frm2)
    method AddEscapeButton (line 30) | public static void AddEscapeButton(this Form frm, DialogResult dr = Di...

FILE: ContextMenuManager/BluePointLilac.Methods/GuidEx.cs
  class GuidEx (line 7) | public static class GuidEx
    method TryParse (line 9) | public static bool TryParse(string str, out Guid guid)
    method IsGuid (line 25) | public static bool IsGuid(string str)

FILE: ContextMenuManager/BluePointLilac.Methods/HighDpi.cs
  class HighDpi (line 14) | public static class HighDpi
    method DpiZoom (line 19) | public static Point DpiZoom(this Point point) => new Point(DpiZoom(poi...
    method DpiZoom (line 21) | public static PointF DpiZoom(this PointF point) => new PointF(DpiZoom(...
    method DpiZoom (line 23) | public static Size DpiZoom(this Size size) => new Size(DpiZoom(size.Wi...
    method DpiZoom (line 25) | public static SizeF DpiZoom(this SizeF size) => new SizeF(DpiZoom(size...
    method DpiZoom (line 27) | public static Rectangle DpiZoom(this Rectangle r) => new Rectangle(Dpi...
    method DpiZoom (line 29) | public static RectangleF DpiZoom(this RectangleF r) => new RectangleF(...
    method DpiZoom (line 31) | public static Padding DpiZoom(this Padding p) => new Padding(DpiZoom(p...
    method DpiZoom (line 33) | public static Font DpiZoom(this Font font) => new Font(font.FontFamily...
    method DpiZoom (line 35) | public static int DpiZoom(this int num) => (int)(num * DpiScale);
    method DpiZoom (line 37) | public static float DpiZoom(this float num) => (float)(num * DpiScale);
    method DpiZoom (line 39) | public static double DpiZoom(this double num) => num * DpiScale;

FILE: ContextMenuManager/BluePointLilac.Methods/ImageExtension.cs
  class ImageExtension (line 7) | public static class ImageExtension
    method ToTransparent (line 9) | public static Image ToTransparent(this Image image, float opacity = 0.5F)
    method ResizeImage (line 23) | public static Image ResizeImage(this Image image, int width, int height)
    method ResizeImage (line 47) | public static Image ResizeImage(this Image image, double scale)
    method ResizeImage (line 55) | public static Image ResizeImage(this Image image, Size newSize)
    method RotateImage (line 61) | public static Image RotateImage(this Image image, RotateFlipType rotat...

FILE: ContextMenuManager/BluePointLilac.Methods/IniReader.cs
  class IniReader (line 9) | public sealed class IniReader
    method IniReader (line 11) | public IniReader() { }
    method IniReader (line 13) | public IniReader(StringBuilder sb) => LoadStringBuilder(sb);
    method IniReader (line 15) | public IniReader(string filePath) => LoadFile(filePath);
    method LoadStringBuilder (line 22) | public void LoadStringBuilder(StringBuilder sb)
    method LoadFile (line 32) | public void LoadFile(string filePath)
    method ReadLines (line 48) | private void ReadLines(List<string> lines)
    method GetValue (line 84) | public string GetValue(string section, string key)
    method TryGetValue (line 92) | public bool TryGetValue(string section, string key, out string value)
    method GetSectionKeys (line 98) | public string[] GetSectionKeys(string section)
    method RemoveSection (line 104) | public bool RemoveSection(string section)
    method RemoveKey (line 109) | public bool RemoveKey(string section, string key)
    method AddValue (line 118) | public void AddValue(string section, string key, string value)
    method SaveFile (line 139) | public void SaveFile(string filePath)

FILE: ContextMenuManager/BluePointLilac.Methods/IniWriter.cs
  class IniWriter (line 8) | public sealed class IniWriter
    method IniWriter (line 10) | public IniWriter() { }
    method IniWriter (line 12) | public IniWriter(string filePath)
    method GetLines (line 21) | private List<string> GetLines()
    method SetValue (line 36) | private void SetValue(string section, string key, ref string value, bo...
    method SetValue (line 154) | public void SetValue(string section, string key, object value)
    method SetValue (line 159) | public void SetValue(string section, string key, string value)
    method DeleteKey (line 164) | public void DeleteKey(string section, string key)
    method DeleteSection (line 169) | public void DeleteSection(string section)
    method GetValue (line 175) | public string GetValue(string section, string key)

FILE: ContextMenuManager/BluePointLilac.Methods/MessageBoxEx.cs
  class MessageBoxEx (line 8) | public static class MessageBoxEx
    method Show (line 19) | public static DialogResult Show(string text, string caption = null,
    method Show (line 39) | public static string Show(string text, string caption,
    class MessageBoxForm (line 51) | sealed class MessageBoxForm : Form
      method MessageBoxForm (line 53) | private MessageBoxForm(string text, string caption, bool canMoveParent)
      method MessageBoxForm (line 65) | public MessageBoxForm(string text, string caption,
      method MessageBoxForm (line 85) | public MessageBoxForm(string text, string caption,
      method InitializeComponents (line 151) | private void InitializeComponents(string[] buttonTexts, Image boxImage)
      method OnLoad (line 228) | protected override void OnLoad(EventArgs e)
  class MessageBoxImage (line 243) | public static class MessageBoxImage
    method GetImage (line 251) | private static Image GetImage(int index)

FILE: ContextMenuManager/BluePointLilac.Methods/RegTrustedInstaller.cs
  class RegTrustedInstaller (line 12) | public class RegTrustedInstaller
    class NativeMethod (line 14) | static class NativeMethod
      type LUID (line 19) | [StructLayout(LayoutKind.Sequential)]
      type LUID_AND_ATTRIBUTES (line 26) | [StructLayout(LayoutKind.Sequential)]
      type TOKEN_PRIVILEGES (line 33) | [StructLayout(LayoutKind.Sequential)]
      type PrivilegeAttributes (line 41) | [Flags]
      type TokenAccessRights (line 56) | [Flags]
      type AccessTypeMasks (line 88) | [Flags]
      method AdjustTokenPrivileges (line 104) | [DllImport("advapi32.dll", SetLastError = true)]
      method LookupPrivilegeValue (line 109) | [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError =...
      method OpenProcessToken (line 113) | [DllImport("advapi32.dll", SetLastError = true)]
      method GetLastError (line 117) | [DllImport("kernel32.dll", SetLastError = true)]
      method GetCurrentProcess (line 120) | [DllImport("kernel32.dll", SetLastError = true)]
      method TrySetPrivilege (line 123) | public static bool TrySetPrivilege(string sPrivilege, bool enablePri...
    method TakeRegKeyOwnerShip (line 160) | public static void TakeRegKeyOwnerShip(string regPath)
    method TakeRegTreeOwnerShip (line 225) | public static void TakeRegTreeOwnerShip(string regPath)

FILE: ContextMenuManager/BluePointLilac.Methods/RegistryEx.cs
  class RegistryEx (line 7) | public static class RegistryEx
    method CopyTo (line 21) | public static void CopyTo(this RegistryKey srcKey, RegistryKey dstKey)
    method CopyTo (line 35) | public static void CopyTo(string srcPath, string dstPath)
    method MoveTo (line 44) | public static void MoveTo(this RegistryKey srcKey, RegistryKey dstKey)
    method MoveTo (line 50) | public static void MoveTo(string srcPath, string dstPath)
    method CreateSubKey (line 56) | public static RegistryKey CreateSubKey(this RegistryKey key, string su...
    method GetParentPath (line 63) | public static string GetParentPath(string regPath) => regPath.Substrin...
    method GetKeyName (line 66) | public static string GetKeyName(string regPath) => regPath.Substring(r...
    method GetRootName (line 69) | public static string GetRootName(string regPath) => regPath.Substring(...
    method GetPathWithoutRoot (line 72) | public static string GetPathWithoutRoot(string regPath) => regPath.Sub...
    method DeleteValue (line 78) | public static void DeleteValue(string regPath, string valueName, bool ...
    method DeleteKeyTree (line 86) | public static void DeleteKeyTree(string regPath, bool throwOnMissingKe...
    method GetRootAndSubRegPath (line 104) | public static void GetRootAndSubRegPath(string regPath, out RegistryKe...
    method GetRegistryKey (line 149) | public static RegistryKey GetRegistryKey(string regPath, bool writable...
    method GetRegistryKey (line 163) | public static RegistryKey GetRegistryKey(string regPath, RegistryKeyPe...

FILE: ContextMenuManager/BluePointLilac.Methods/ResourceIcon.cs
  class ResourceIcon (line 10) | public static class ResourceIcon
    method ExtractIconEx (line 12) | [DllImport("shell32.dll", CharSet = CharSet.Auto)]
    method DestroyIcon (line 15) | [DllImport("user32.dll", SetLastError = true)]
    method LoadLibrary (line 18) | [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true...
    method FreeLibrary (line 21) | [DllImport("kernel32.dll")]
    method LoadImage (line 24) | [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    method SHGetFileInfo (line 27) | [DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    type SHFILEINFO (line 30) | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    type FileInfoFlags (line 42) | [Flags]
    method GetExtensionIcon (line 68) | public static Icon GetExtensionIcon(string extension)
    method GetFolderIcon (line 77) | public static Icon GetFolderIcon(string folderPath)
    method GetIcon (line 87) | public static Icon GetIcon(string filePath, FileInfoFlags flags)
    method GetIcon (line 100) | public static Icon GetIcon(string iconLocation)
    method GetIcon (line 110) | public static Icon GetIcon(string iconLocation, out string iconPath, o...
    method GetIcon (line 133) | public static Icon GetIcon(string iconPath, int iconIndex)
    method GetReplacedShellIcon (line 166) | public static Icon GetReplacedShellIcon(int iconIndex)

FILE: ContextMenuManager/BluePointLilac.Methods/ResourceString.cs
  class ResourceString (line 7) | public static class ResourceString
    method SHLoadIndirectString (line 13) | [DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Un...
    method GetDirectString (line 21) | public static string GetDirectString(string resStr)

FILE: ContextMenuManager/BluePointLilac.Methods/RichTextBoxExtension.cs
  class RichTextBoxExtension (line 8) | public static class RichTextBoxExtension
    method LoadIni (line 12) | public static void LoadIni(this RichTextBox box, string iniStr)
    method LoadXml (line 48) | public static void LoadXml(this RichTextBox box, string xmlStr)
    method AppendText (line 87) | public static void AppendText(this RichTextBox box, string text, Color...
    class XmlStateMachine (line 98) | sealed class XmlStateMachine
      method GetNextToken (line 104) | public string GetNextToken(string s, out XmlTokenType ttype)
      method GetTokenColor (line 260) | public Color GetTokenColor(XmlTokenType ttype)
      method GetXmlDeclaration (line 303) | public string GetXmlDeclaration(string s)
      method HandleAttributeEnd (line 314) | private void HandleAttributeEnd()
      method HandleReservedXmlToken (line 335) | private void HandleReservedXmlToken()
      method ReadNodeName (line 430) | private string ReadNodeName(string s)
      method ReadAttributeName (line 441) | private string ReadAttributeName(string s)
      method ReadNodeValue (line 449) | private string ReadNodeValue(string s)
      method ReadCommentValue (line 457) | private string ReadCommentValue(string s)
      method GetWhitespace (line 465) | private string GetWhitespace(string s)
    type XmlTokenType (line 478) | enum XmlTokenType

FILE: ContextMenuManager/BluePointLilac.Methods/ShellLink.cs
  class ShellLink (line 11) | public class ShellLink : IDisposable
    type IShellLinkW (line 13) | [ComImport]
      method GetPath (line 18) | void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder ps...
      method GetIDList (line 19) | void GetIDList(out IntPtr ppidl);
      method SetIDList (line 20) | void SetIDList(IntPtr pidl);
      method GetDescription (line 21) | void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBui...
      method SetDescription (line 22) | void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
      method GetWorkingDirectory (line 23) | void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] Stri...
      method SetWorkingDirectory (line 24) | void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string ps...
      method GetArguments (line 25) | void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuild...
      method SetArguments (line 26) | void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
      method GetHotKey (line 27) | void GetHotKey(out ushort pwHotkey);
      method SetHotKey (line 28) | void SetHotKey(ushort wHotKey);
      method GetShowCmd (line 29) | void GetShowCmd(out int piShowCmd);
      method SetShowCmd (line 30) | void SetShowCmd(int iShowCmd);
      method GetIconLocation (line 31) | void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBu...
      method SetIconLocation (line 32) | void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIco...
      method SetRelativePath (line 33) | void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPat...
      method Resolve (line 34) | void Resolve(IntPtr hwnd, uint fFlags);
      method SetPath (line 35) | void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
    class CShellLink (line 38) | [ComImport]
    type IShellLinkDataList (line 43) | [ComImport]
      method AddDataBlock (line 48) | void AddDataBlock(IntPtr pDataBlock);
      method CopyDataBlock (line 49) | void CopyDataBlock(uint dwSig, out IntPtr ppDataBlock);
      method RemoveDataBlock (line 50) | void RemoveDataBlock(uint dwSig);
      method GetFlags (line 51) | void GetFlags(out ShellLinkDataFlags pdwFlags);
      method SetFlags (line 52) | void SetFlags(ShellLinkDataFlags dwFlags);
    type ShellLinkDataFlags (line 55) | [Flags]
    type WIN32_FIND_DATAW (line 90) | [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unico...
    type ICONLOCATION (line 107) | public struct ICONLOCATION
    method ShellLink (line 271) | public ShellLink(string lnkPath = null)
    method Dispose (line 280) | public void Dispose()
    method Dispose (line 286) | protected virtual void Dispose(bool disposing)
    method Save (line 293) | public void Save() { Save(this.ShortcutPath); }
    method Save (line 295) | public void Save(string lnkPath)
    method Load (line 300) | public void Load() { Load(this.ShortcutPath); }
    method Load (line 302) | public void Load(string lnkPath)

FILE: ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs
  class SingleInstance (line 11) | public static class SingleInstance
    method ShowWindowAsync (line 13) | [DllImport("user32.dll")]
    method SetForegroundWindow (line 16) | [DllImport("user32.dll")]
    method IsRunning (line 21) | public static bool IsRunning()
    method Restart (line 46) | public static void Restart(string[] args = null, string updatePath = n...

FILE: ContextMenuManager/BluePointLilac.Methods/StringExtension.cs
  class StringExtension (line 4) | public static class StringExtension
    method IsNullOrWhiteSpace (line 6) | public static bool IsNullOrWhiteSpace(this string str)

FILE: ContextMenuManager/BluePointLilac.Methods/TextBoxExtension.cs
  class TextBoxExtension (line 6) | public static class TextBoxExtension
    method CanResizeFont (line 9) | public static void CanResizeFont(this TextBox box)
    method SetAutoShowScroll (line 22) | public static void SetAutoShowScroll(this TextBox box, ScrollBars scro...
    method CanSelectAllWhenReadOnly (line 58) | public static void CanSelectAllWhenReadOnly(this TextBox box)

FILE: ContextMenuManager/BluePointLilac.Methods/ToolTipBox.cs
  class ToolTipBox (line 5) | public static class ToolTipBox
    method SetToolTip (line 7) | public static void SetToolTip(Control ctr, string tip)
    method SetToolTip (line 15) | public static void SetToolTip(ToolStripItem item, string tip)

FILE: ContextMenuManager/BluePointLilac.Methods/WinOsVersion.cs
  class WinOsVersion (line 7) | public static class WinOsVersion

FILE: ContextMenuManager/Controls/AppSettingBox.cs
  class AppSettingBox (line 11) | sealed class AppSettingBox : MyList
    method AppSettingBox (line 13) | public AppSettingBox()
    method ClearItems (line 159) | public override void ClearItems()
    method LoadItems (line 164) | public void LoadItems()
    method ChangeConfigDir (line 184) | private void ChangeConfigDir()
    method ChangeEngineUrl (line 200) | private void ChangeEngineUrl()
    method ChangeUpdateFrequency (line 218) | private void ChangeUpdateFrequency()
    method GetUpdateSelectIndex (line 233) | private int GetUpdateSelectIndex()
    method GetEngineSelectIndex (line 248) | private int GetEngineSelectIndex()

FILE: ContextMenuManager/Controls/DetailedEditDialog.cs
  class DetailedEditDialog (line 8) | sealed class DetailedEditDialog : CommonDialog
    method Reset (line 12) | public override void Reset() { }
    method RunDialog (line 14) | protected override bool RunDialog(IntPtr hwndOwner)

FILE: ContextMenuManager/Controls/DetailedEditList.cs
  class DetailedEditList (line 13) | sealed class DetailedEditList : SwitchDicList
    method LoadItems (line 17) | public override void LoadItems()

FILE: ContextMenuManager/Controls/DictionariesBox.cs
  class DictionariesBox (line 12) | sealed class DictionariesBox : TabControl
    method DictionariesBox (line 14) | public DictionariesBox()
    method SaveFile (line 61) | private void SaveFile()
    method GetInitialText (line 95) | private string GetInitialText()
    method LoadText (line 116) | public void LoadText()

FILE: ContextMenuManager/Controls/DonateBox.cs
  class DonateBox (line 12) | sealed class DonateBox : Panel
    method DonateBox (line 14) | public DonateBox()
    method GetSingleQR (line 55) | private static Image GetSingleQR(int index)
    method OnResize (line 67) | protected override void OnResize(EventArgs e)
    method SwitchQR (line 79) | private void SwitchQR(object sender, MouseEventArgs e)
    method ShowDonateDialog (line 93) | private void ShowDonateDialog()
    class DonateListDialog (line 122) | sealed class DonateListDialog : CommonDialog
      method Reset (line 126) | public override void Reset() { }
      method RunDialog (line 128) | protected override bool RunDialog(IntPtr hwndOwner)
      class DonateListForm (line 142) | sealed class DonateListForm : Form
        method DonateListForm (line 144) | public DonateListForm()
        method OnResize (line 187) | protected override void OnResize(EventArgs e)
        method ShowDonateList (line 198) | public void ShowDonateList(string contents)

FILE: ContextMenuManager/Controls/EnhanceMenusDialog.cs
  class EnhanceMenusDialog (line 8) | sealed class EnhanceMenusDialog : CommonDialog
    method Reset (line 12) | public override void Reset() { }
    method RunDialog (line 14) | protected override bool RunDialog(IntPtr hwndOwner)

FILE: ContextMenuManager/Controls/EnhanceMenusItem.cs
  class EnhanceShellItem (line 14) | sealed class EnhanceShellItem : FoldSubItem, IChkVisibleItem
    method EnhanceShellItem (line 34) | public EnhanceShellItem()
    method WriteAttributesValue (line 40) | private static void WriteAttributesValue(XmlNode valueXN, string regPath)
    method WriteSubKeysValue (line 77) | private static void WriteSubKeysValue(XmlNode keyXN, string regPath)
    method WriteCommandValue (line 107) | private static void WriteCommandValue(XmlNode cmdXE, string regPath)
    method CreateCommandFile (line 138) | private static string CreateCommandFile(XmlNode xe)
  class EnhanceShellExItem (line 171) | sealed class EnhanceShellExItem : FoldSubItem, IChkVisibleItem
    method EnhanceShellExItem (line 201) | public EnhanceShellExItem()

FILE: ContextMenuManager/Controls/EnhanceMenusList.cs
  class EnhanceMenusList (line 9) | sealed class EnhanceMenusList : SwitchDicList
    method LoadItems (line 13) | public override void LoadItems()
    method LoadShellItems (line 58) | private void LoadShellItems(XmlNode shellXN, FoldGroupItem groupItem)
    method LoadShellExItems (line 121) | private void LoadShellExItems(XmlNode shellExXN, FoldGroupItem groupItem)

FILE: ContextMenuManager/Controls/ExplorerRestarter.cs
  class ExplorerRestarter (line 9) | sealed class ExplorerRestarter : MyListItem
    method ExplorerRestarter (line 11) | public ExplorerRestarter()
    method Show (line 46) | public static new void Show() => ShowHandler?.Invoke();
    method Hide (line 47) | public static new void Hide() => HideHandler?.Invoke();

FILE: ContextMenuManager/Controls/FileExtensionDialog.cs
  class FileExtensionDialog (line 9) | sealed class FileExtensionDialog : SelectDialog
    method FileExtensionDialog (line 17) | public FileExtensionDialog()
    method RunDialog (line 35) | protected override bool RunDialog(IntPtr hwndOwner)

FILE: ContextMenuManager/Controls/FoldSubItem.cs
  class FoldSubItem (line 13) | class FoldSubItem : MyListItem
    method Indent (line 17) | public void Indent()
  class FoldGroupItem (line 25) | class FoldGroupItem : MyListItem, IBtnShowMenuItem
    method FoldGroupItem (line 48) | public FoldGroupItem(string groupPath, PathType pathType)
    method SetVisibleWithSubItemCount (line 99) | public void SetVisibleWithSubItemCount()
    method Fold (line 112) | private void Fold()
    method FoldMe (line 119) | private void FoldMe(bool isFold)
    method FoldAll (line 128) | private void FoldAll(bool isFold)

FILE: ContextMenuManager/Controls/GuidBlockedItem.cs
  class GuidBlockedItem (line 11) | class GuidBlockedItem : MyListItem, IBtnShowMenuItem, ITsiWebSearchItem,...
    method GuidBlockedItem (line 13) | public GuidBlockedItem(string value)
    method InitializeComponents (line 75) | private void InitializeComponents()
    method DeleteMe (line 93) | public void DeleteMe()

FILE: ContextMenuManager/Controls/GuidBlockedList.cs
  class GuidBlockedList (line 12) | sealed class GuidBlockedList : MyList
    method LoadItems (line 18) | public void LoadItems()
    method LoadBlockedItems (line 24) | private void LoadBlockedItems()
    method AddNewItem (line 42) | private void AddNewItem()

FILE: ContextMenuManager/Controls/IEItem.cs
  class IEItem (line 12) | sealed class IEItem : MyListItem, ITsiRegPathItem, ITsiFilePathItem, ITs...
    method IEItem (line 17) | public IEItem(string regPath)
    method InitializeComponents (line 95) | private void InitializeComponents()
    method DeleteMe (line 115) | public void DeleteMe()

FILE: ContextMenuManager/Controls/IEList.cs
  class IEList (line 11) | sealed class IEList : MyList
    method LoadItems (line 15) | public void LoadItems()
    method LoadIEItems (line 21) | private void LoadIEItems()
    method AddNewItem (line 49) | private void AddNewItem()

FILE: ContextMenuManager/Controls/Interfaces/IBtnDeleteItem.cs
  type IBtnDeleteItem (line 7) | interface IBtnDeleteItem
    method DeleteMe (line 10) | void DeleteMe();
  class DeleteButton (line 13) | sealed class DeleteButton : PictureButton
    method DeleteButton (line 15) | public DeleteButton(IBtnDeleteItem item) : base(AppImage.Delete)

FILE: ContextMenuManager/Controls/Interfaces/IBtnMoveUpDownItem.cs
  type IBtnMoveUpDownItem (line 6) | interface IBtnMoveUpDownItem
  class MoveButton (line 12) | sealed class MoveButton : PictureButton
    method MoveButton (line 14) | public MoveButton(IBtnMoveUpDownItem item, bool isUp) : base(isUp ? Ap...

FILE: ContextMenuManager/Controls/Interfaces/IBtnShowMenuItem.cs
  type IBtnShowMenuItem (line 7) | interface IBtnShowMenuItem
  class MenuButton (line 13) | sealed class MenuButton : PictureButton
    method MenuButton (line 15) | public MenuButton(IBtnShowMenuItem item) : base(AppImage.Setting)

FILE: ContextMenuManager/Controls/Interfaces/IChkVisibleItem.cs
  type IChkVisibleItem (line 6) | interface IChkVisibleItem
  class VisibleCheckBox (line 12) | sealed class VisibleCheckBox : MyCheckBox
    method VisibleCheckBox (line 14) | public VisibleCheckBox(IChkVisibleItem item)

FILE: ContextMenuManager/Controls/Interfaces/IProtectOpenItem.cs
  type IProtectOpenItem (line 3) | interface IProtectOpenItem
    method TryProtectOpenItem (line 6) | bool TryProtectOpenItem();

FILE: ContextMenuManager/Controls/Interfaces/ITsiAdministratorItem.cs
  type ITsiAdministratorItem (line 8) | interface ITsiAdministratorItem
  class RunAsAdministratorItem (line 15) | sealed class RunAsAdministratorItem : ToolStripMenuItem
    method RunAsAdministratorItem (line 17) | public RunAsAdministratorItem(ITsiAdministratorItem item) : base(AppSt...

FILE: ContextMenuManager/Controls/Interfaces/ITsiCommandItem.cs
  type ITsiCommandItem (line 9) | interface ITsiCommandItem
  class ChangeCommandMenuItem (line 15) | sealed class ChangeCommandMenuItem : ToolStripMenuItem
    method ChangeCommandMenuItem (line 19) | public ChangeCommandMenuItem(ITsiCommandItem item) : base(AppString.Me...
    method ChangeCommand (line 28) | private string ChangeCommand(string command)

FILE: ContextMenuManager/Controls/Interfaces/ITsiDeleteItem.cs
  type ITsiDeleteItem (line 10) | interface ITsiDeleteItem
    method DeleteMe (line 13) | void DeleteMe();
  type ITsiRegDeleteItem (line 16) | interface ITsiRegDeleteItem : ITsiDeleteItem
  class DeleteMeMenuItem (line 22) | sealed class DeleteMeMenuItem : ToolStripMenuItem
    method DeleteMeMenuItem (line 24) | public DeleteMeMenuItem(ITsiDeleteItem item) : base(AppString.Menu.Del...

FILE: ContextMenuManager/Controls/Interfaces/ITsiFilePathItem.cs
  type ITsiFilePathItem (line 8) | interface ITsiFilePathItem
  class FileLocationMenuItem (line 16) | sealed class FileLocationMenuItem : ToolStripMenuItem
    method FileLocationMenuItem (line 18) | public FileLocationMenuItem(ITsiFilePathItem item) : base(AppString.Me...
  class FilePropertiesMenuItem (line 28) | sealed class FilePropertiesMenuItem : ToolStripMenuItem
    method FilePropertiesMenuItem (line 30) | public FilePropertiesMenuItem(ITsiFilePathItem item) : base(AppString....

FILE: ContextMenuManager/Controls/Interfaces/ITsiGuidItem.cs
  type ITsiGuidItem (line 10) | interface ITsiGuidItem
  class HandleGuidMenuItem (line 18) | sealed class HandleGuidMenuItem : ToolStripMenuItem
    method HandleGuidMenuItem (line 20) | public HandleGuidMenuItem(ITsiGuidItem item) : base(AppString.Menu.Han...
    method CopyGuid (line 39) | private void CopyGuid()
    method BlockGuid (line 47) | private void BlockGuid()
    method AddGuidDic (line 68) | private void AddGuidDic()
    method OpenClsidPath (line 117) | private void OpenClsidPath()
    method RefreshMenuItem (line 123) | private void RefreshMenuItem()
    class AddGuidDicDialog (line 140) | sealed class AddGuidDicDialog : CommonDialog
      method Reset (line 156) | public override void Reset() { }
      method RunDialog (line 158) | protected override bool RunDialog(IntPtr hwndOwner)
      class AddGuidDicForm (line 180) | sealed class AddGuidDicForm : Form
        method AddGuidDicForm (line 182) | public AddGuidDicForm()
        method InitializeComponents (line 248) | private void InitializeComponents()
        method SelectIcon (line 269) | private void SelectIcon()
  class DetailedEditButton (line 290) | sealed class DetailedEditButton : PictureButton
    method DetailedEditButton (line 292) | public DetailedEditButton(ITsiGuidItem item) : base(AppImage.SubItems)

FILE: ContextMenuManager/Controls/Interfaces/ITsiIconItem.cs
  type ITsiIconItem (line 9) | interface ITsiIconItem
  class ChangeIconMenuItem (line 19) | sealed class ChangeIconMenuItem : ToolStripMenuItem
    method ChangeIconMenuItem (line 21) | public ChangeIconMenuItem(ITsiIconItem item) : base(AppString.Menu.Cha...

FILE: ContextMenuManager/Controls/Interfaces/ITsiRegExportItem.cs
  type ITsiRegExportItem (line 9) | interface ITsiRegExportItem
  class RegExportMenuItem (line 17) | sealed class RegExportMenuItem : ToolStripMenuItem
    method RegExportMenuItem (line 19) | public RegExportMenuItem(ITsiRegExportItem item) : base(AppString.Menu...

FILE: ContextMenuManager/Controls/Interfaces/ITsiRegPathItem.cs
  type ITsiRegPathItem (line 7) | interface ITsiRegPathItem
  class RegLocationMenuItem (line 15) | sealed class RegLocationMenuItem : ToolStripMenuItem
    method RegLocationMenuItem (line 17) | public RegLocationMenuItem(ITsiRegPathItem item) : base(AppString.Menu...

FILE: ContextMenuManager/Controls/Interfaces/ITsiShortcutCommandItem.cs
  type ITsiShortcutCommandItem (line 10) | interface ITsiShortcutCommandItem
  class ShortcutCommandMenuItem (line 17) | sealed class ShortcutCommandMenuItem : ToolStripMenuItem
    method ShortcutCommandMenuItem (line 19) | public ShortcutCommandMenuItem(ITsiShortcutCommandItem item) : base(Ap...
    method ChangeCommand (line 27) | public bool ChangeCommand(ShellLink shellLink)
    class CommandDialog (line 41) | sealed class CommandDialog : CommonDialog
      method Reset (line 46) | public override void Reset() { }
      method RunDialog (line 48) | protected override bool RunDialog(IntPtr hwndOwner)
      class CommandForm (line 65) | sealed class CommandForm : ResizeLimitedForm
        method CommandForm (line 67) | public CommandForm()
        method InitializeComponents (line 117) | private void InitializeComponents()

FILE: ContextMenuManager/Controls/Interfaces/ITsiTextItem.cs
  type ITsiTextItem (line 8) | interface ITsiTextItem
  class ChangeTextMenuItem (line 15) | sealed class ChangeTextMenuItem : ToolStripMenuItem
    method ChangeTextMenuItem (line 17) | public ChangeTextMenuItem(ITsiTextItem item) : base(AppString.Menu.Cha...
    method ChangeText (line 26) | private string ChangeText(string text)

FILE: ContextMenuManager/Controls/Interfaces/ITsiWebSearchItem.cs
  type ITsiWebSearchItem (line 7) | interface ITsiWebSearchItem
  class WebSearchMenuItem (line 13) | sealed class WebSearchMenuItem : ToolStripMenuItem
    method WebSearchMenuItem (line 15) | public WebSearchMenuItem(ITsiWebSearchItem item) : base(AppString.Menu...

FILE: ContextMenuManager/Controls/LanguagesBox.cs
  class LanguagesBox (line 16) | sealed class LanguagesBox : FlowLayoutPanel
    method LanguagesBox (line 18) | public LanguagesBox()
    method OnResize (line 82) | protected override void OnResize(EventArgs e)
    method LoadLanguages (line 92) | public void LoadLanguages()
    method ChangeLanguage (line 171) | private void ChangeLanguage()
    method GetSelectIndex (line 195) | private int GetSelectIndex()
    method ShowLanguageDialog (line 202) | public void ShowLanguageDialog()
    class TranslateDialog (line 260) | sealed class TranslateDialog : CommonDialog
      method Reset (line 262) | public override void Reset() { }
      method RunDialog (line 264) | protected override bool RunDialog(IntPtr hwndOwner)
      class TranslateForm (line 273) | sealed class TranslateForm : Form
        method TranslateForm (line 275) | public TranslateForm()
        method TranslateForm (line 353) | static TranslateForm()
        method InitializeComponents (line 374) | private void InitializeComponents()
        method SelectFile (line 444) | private void SelectFile()
        method Save (line 456) | private void Save()

FILE: ContextMenuManager/Controls/NewIEDialog.cs
  class NewIEDialog (line 9) | sealed class NewIEDialog : CommonDialog
    method Reset (line 12) | public override void Reset() { }
    method RunDialog (line 14) | protected override bool RunDialog(IntPtr hwndOwner)
    class NewIEForm (line 25) | sealed class NewIEForm : NewItemForm
      method InitializeComponents (line 29) | protected override void InitializeComponents()
      method AddNewItem (line 59) | private void AddNewItem()

FILE: ContextMenuManager/Controls/NewItem.cs
  class NewItem (line 8) | class NewItem : MyListItem
    method NewItem (line 10) | public NewItem() : this(AppString.Other.NewItem) { }
    method NewItem (line 12) | public NewItem(string text)

FILE: ContextMenuManager/Controls/NewItemForm.cs
  class NewItemForm (line 10) | class NewItemForm : ResizeLimitedForm
    method NewItemForm (line 12) | public NewItemForm()
    method InitializeComponents (line 78) | protected virtual void InitializeComponents()

FILE: ContextMenuManager/Controls/NewLnkFileDialog.cs
  class NewLnkFileDialog (line 9) | sealed class NewLnkFileDialog : CommonDialog
    method Reset (line 15) | public override void Reset() { }
    method RunDialog (line 17) | protected override bool RunDialog(IntPtr hwndOwner)
    class NewLnkForm (line 34) | sealed class NewLnkForm : NewItemForm
      method InitializeComponents (line 50) | protected override void InitializeComponents()
      method BrowseFile (line 100) | private void BrowseFile()
      method BrowseFolder (line 127) | private void BrowseFolder()

FILE: ContextMenuManager/Controls/NewOpenWithDialog.cs
  class NewOpenWithDialog (line 10) | sealed class NewOpenWithDialog : CommonDialog
    method Reset (line 13) | public override void Reset() { }
    method RunDialog (line 15) | protected override bool RunDialog(IntPtr hwndOwner)
    class NewOpenWithForm (line 26) | sealed class NewOpenWithForm : NewItemForm
      method InitializeComponents (line 35) | protected override void InitializeComponents()
      method BrowseFile (line 72) | private void BrowseFile()
      method AddNewItem (line 86) | private void AddNewItem()

FILE: ContextMenuManager/Controls/NewShellDialog.cs
  class NewShellDialog (line 9) | sealed class NewShellDialog : CommonDialog
    method Reset (line 16) | public override void Reset() { }
    method RunDialog (line 18) | protected override bool RunDialog(IntPtr hwndOwner)
    class NewShellForm (line 33) | sealed class NewShellForm : NewItemForm
      method InitializeComponents (line 66) | protected override void InitializeComponents()
      method BrowseFile (line 107) | private void BrowseFile()
      method AddNewItem (line 157) | private void AddNewItem()

FILE: ContextMenuManager/Controls/OpenWithItem.cs
  class OpenWithItem (line 14) | sealed class OpenWithItem : MyListItem, IChkVisibleItem, IBtnShowMenuIte...
    method OpenWithItem (line 18) | public OpenWithItem(string regPath)
    method InitializeComponents (line 102) | private void InitializeComponents()
    method DeleteMe (line 124) | public void DeleteMe()

FILE: ContextMenuManager/Controls/OpenWithList.cs
  class OpenWithList (line 12) | sealed class OpenWithList : MyList
    method LoadItems (line 14) | public void LoadItems()
    method LoadOpenWithItems (line 27) | private void LoadOpenWithItems()
    method AddNewItem (line 60) | private void AddNewItem()

FILE: ContextMenuManager/Controls/RuleItem.cs
  class RuleItem (line 12) | class RuleItem : FoldSubItem, IBtnShowMenuItem, ITsiWebSearchItem
    method RuleItem (line 14) | public RuleItem(ItemInfo info)
  type ItemInfo (line 40) | public struct ItemInfo
  class VisibleRegRuleItem (line 48) | sealed class VisibleRegRuleItem : RuleItem, IChkVisibleItem, ITsiRegPath...
    type RegRule (line 50) | public struct RegRule
      method RegRule (line 57) | public RegRule(string regPath, string valueName, object turnOnValue,
    type RuleAndInfo (line 66) | public struct RuleAndInfo
    method VisibleRegRuleItem (line 72) | private VisibleRegRuleItem(ItemInfo info) : base(info)
    method VisibleRegRuleItem (line 80) | public VisibleRegRuleItem(RegRule[] rules, ItemInfo info)
    method VisibleRegRuleItem (line 83) | public VisibleRegRuleItem(RegRule rule, ItemInfo info)
    method VisibleRegRuleItem (line 86) | public VisibleRegRuleItem(RuleAndInfo ruleAndInfo)
  class NumberRegRuleItem (line 232) | sealed class NumberRegRuleItem : RuleItem, ITsiRegPathItem
    type RegRule (line 234) | public struct RegRule
    method NumberRegRuleItem (line 251) | public NumberRegRuleItem(RegRule rule, ItemInfo info) : base(info)
  class StringRegRuleItem (line 301) | sealed class StringRegRuleItem : RuleItem, ITsiRegPathItem
    type RegRule (line 303) | public struct RegRule
    method StringRegRuleItem (line 319) | public StringRegRuleItem(RegRule rule, ItemInfo info) : base(info)
  class VisbleIniRuleItem (line 356) | sealed class VisbleIniRuleItem : RuleItem, IChkVisibleItem
    type IniRule (line 358) | public struct IniRule
    method VisbleIniRuleItem (line 367) | public VisbleIniRuleItem(IniRule rule, ItemInfo info) : base(info)
  class NumberIniRuleItem (line 389) | sealed class NumberIniRuleItem : RuleItem
    type IniRule (line 391) | public struct IniRule
    method NumberIniRuleItem (line 401) | public NumberIniRuleItem(IniRule rule, ItemInfo info) : base(info)
  class StringIniRuleItem (line 455) | sealed class StringIniRuleItem : RuleItem
    type IniRule (line 457) | public struct IniRule
    method StringIniRuleItem (line 473) | public StringIniRuleItem(IniRule rule, ItemInfo info) : base(info)

FILE: ContextMenuManager/Controls/SendToItem.cs
  class SendToItem (line 12) | sealed class SendToItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem,...
    method SendToItem (line 15) | public SendToItem(string filePath)
    method InitializeComponents (line 188) | private void InitializeComponents()
    method DeleteMe (line 219) | public void DeleteMe()

FILE: ContextMenuManager/Controls/SendToList.cs
  class SendToList (line 10) | sealed class SendToList : MyList
    method LoadItems (line 15) | public void LoadItems()
    method AddNewItem (line 29) | private void AddNewItem()
    method AddDirItem (line 54) | private void AddDirItem()

FILE: ContextMenuManager/Controls/ShellExItem.cs
  class ShellExItem (line 11) | sealed class ShellExItem : FoldSubItem, IChkVisibleItem, IBtnShowMenuIte...
    method GetPathAndGuids (line 14) | public static Dictionary<string, Guid> GetPathAndGuids(string shellExP...
    method ShellExItem (line 46) | public ShellExItem(Guid guid, string regPath)
    method InitializeComponents (line 121) | private void InitializeComponents()
    method TryProtectOpenItem (line 144) | public bool TryProtectOpenItem()
    method DeleteMe (line 150) | public void DeleteMe()

FILE: ContextMenuManager/Controls/ShellExecuteDialog.cs
  class ShellExecuteDialog (line 10) | sealed class ShellExecuteDialog : CommonDialog
    method Reset (line 14) | public override void Reset() { }
    method RunDialog (line 16) | protected override bool RunDialog(IntPtr hwndOwner)
    method GetCommand (line 31) | public static string GetCommand(string fileName, string arguments, str...
    class ShellExecuteForm (line 43) | sealed class ShellExecuteForm : Form
      method ShellExecuteForm (line 47) | public ShellExecuteForm()
      method InitializeComponents (line 93) | private void InitializeComponents()
  class ShellExecuteCheckBox (line 134) | sealed class ShellExecuteCheckBox : CheckBox
    method ShellExecuteCheckBox (line 136) | public ShellExecuteCheckBox()
    method OnClick (line 149) | protected override void OnClick(EventArgs e)

FILE: ContextMenuManager/Controls/ShellItem.cs
  class ShellItem (line 14) | class ShellItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem, ITsiTex...
    type Positions (line 32) | enum Positions { Default, Top, Bottom }
    method ShellItem (line 34) | public ShellItem(string regPath)
    method InitializeComponents (line 389) | private void InitializeComponents()
    method DeleteIcon (line 434) | private void DeleteIcon()
    method UseShieldIcon (line 441) | private void UseShieldIcon()
    method RefreshMenuItem (line 459) | private void RefreshMenuItem()
    method ShowSubItems (line 516) | private void ShowSubItems()
    method TryProtectOpenItem (line 532) | public bool TryProtectOpenItem()
    method DeleteMe (line 539) | public virtual void DeleteMe()

FILE: ContextMenuManager/Controls/ShellList.cs
  class ShellList (line 16) | sealed class ShellList : MyList
    type Scenes (line 35) | public enum Scenes
    method GetDirectoryTypeName (line 62) | private static string GetDirectoryTypeName(string directoryType)
    method GetPerceivedTypeName (line 70) | private static string GetPerceivedTypeName(string perceivedType)
    type DropEffect (line 89) | private enum DropEffect { Default = 0, Copy = 1, Move = 2, CreateLink ...
    method GetDropEffectName (line 134) | private static string GetDropEffectName()
    method GetShellPath (line 166) | private static string GetShellPath(string scenePath) => $@"{scenePath}...
    method GetShellExPath (line 167) | private static string GetShellExPath(string scenePath) => $@"{scenePat...
    method GetSysAssExtPath (line 168) | private static string GetSysAssExtPath(string typeName) => typeName !=...
    method GetOpenMode (line 169) | private static string GetOpenMode(string extension) => FileExtension.G...
    method GetOpenModePath (line 170) | private static string GetOpenModePath(string extension) => extension !...
    method GetPerceivedType (line 171) | private static string GetPerceivedType(string extension) => Registry.G...
    method LoadItems (line 175) | public void LoadItems()
    method LoadItems (line 283) | private void LoadItems(string scenePath)
    method LoadShellItems (line 291) | private void LoadShellItems(string shellPath)
    method LoadShellExItems (line 304) | private void LoadShellExItems(string shellExPath)
    method GetDragDropGroupItem (line 338) | private FoldGroupItem GetDragDropGroupItem(string shellExPath)
    method AddNewItem (line 365) | private void AddNewItem(string scenePath)
    method AddNewShellItem (line 451) | private void AddNewShellItem(string scenePath)
    method AddNewShellExItem (line 473) | private void AddNewShellExItem(string scenePath)
    method LoadStoreItems (line 549) | private void LoadStoreItems()
    method LoadUwpModeItem (line 561) | private void LoadUwpModeItem()
    method LoadAnalysisItems (line 590) | private void LoadAnalysisItems()
    class SelectItem (line 645) | sealed class SelectItem : MyListItem
      method SelectItem (line 647) | public SelectItem(Scenes scene)
      method SetTextAndTip (line 662) | private void SetTextAndTip()
      method SetImage (line 709) | private void SetImage()
      method ShowSelectDialog (line 721) | private void ShowSelectDialog()
      method RefreshList (line 853) | private void RefreshList()
    class JumpItem (line 861) | sealed class JumpItem : MyListItem
      method JumpItem (line 863) | public JumpItem(Scenes scene)

FILE: ContextMenuManager/Controls/ShellNewItem.cs
  class ShellNewItem (line 37) | sealed class ShellNewItem : MyListItem, IChkVisibleItem, ITsiTextItem, I...
    method ShellNewItem (line 47) | public ShellNewItem(ShellNewList list, string regPath)
    method InitializeComponents (line 248) | private void InitializeComponents()
    method EditInitialData (line 288) | private void EditInitialData()
    method SetSortabled (line 302) | public void SetSortabled(bool isLocked)
    method MoveWithSeparator (line 307) | private void MoveWithSeparator(bool isBefore)
    method DeleteMe (line 316) | public void DeleteMe()

FILE: ContextMenuManager/Controls/ShellNewList.cs
  class ShellNewList (line 17) | sealed class ShellNewList : MyList
    method LoadItems (line 23) | public void LoadItems()
    method LoadUnlockItems (line 34) | private void LoadUnlockItems()
    method LoadLockItems (line 46) | private void LoadLockItems()
    method LoadItems (line 52) | private void LoadItems(List<string> extensions)
    method MoveItem (line 108) | public void MoveItem(ShellNewItem shellNewItem, bool isUp)
    method SaveSorting (line 121) | public void SaveSorting()
    method AddNewItem (line 136) | private void AddNewItem()
    method GetWebShellNewData (line 193) | private static byte[] GetWebShellNewData(string extension)
    class ShellNewLockItem (line 219) | public sealed class ShellNewLockItem : MyListItem, IChkVisibleItem, IB...
      method ShellNewLockItem (line 221) | public ShellNewLockItem(ShellNewList list)
      method Lock (line 281) | public static void Lock()
      method UnLock (line 292) | public static void UnLock()
    class ShellNewSeparator (line 312) | public sealed class ShellNewSeparator : MyListItem
      method ShellNewSeparator (line 314) | public ShellNewSeparator()

FILE: ContextMenuManager/Controls/ShellStoreDialog.cs
  class ShellStoreDialog (line 11) | sealed class ShellStoreDialog : CommonDialog
    method Reset (line 18) | public override void Reset() { }
    method RunDialog (line 20) | protected override bool RunDialog(IntPtr hwndOwner)
    class ShellStoreForm (line 31) | public sealed class ShellStoreForm : Form
      method ShellStoreForm (line 37) | public ShellStoreForm(string shellPath, Func<string, bool> filter, b...
      method InitializeComponents (line 94) | private void InitializeComponents()
      method OnResize (line 107) | protected override void OnResize(EventArgs e)
      method LoadItems (line 116) | private void LoadItems(bool isReference)
      method GetSelectedItems (line 142) | private void GetSelectedItems()
  class StoreShellItem (line 152) | sealed class StoreShellItem : ShellItem
    method StoreShellItem (line 154) | public StoreShellItem(string regPath, bool isPublic, bool isSelect = t...
    method DeleteMe (line 183) | public override void DeleteMe()

FILE: ContextMenuManager/Controls/ShellSubMenuDialog.cs
  class ShellSubMenuDialog (line 13) | sealed class ShellSubMenuDialog : CommonDialog
    method Reset (line 19) | public override void Reset() { }
    method RunDialog (line 21) | protected override bool RunDialog(IntPtr hwndOwner)
    class PulicMultiItemsList (line 71) | sealed class PulicMultiItemsList : MyList
      method LoadItems (line 82) | public void LoadItems()
      method AddNewItem (line 109) | private void AddNewItem()
      method AddReference (line 123) | private void AddReference()
      method AddSeparator (line 143) | private void AddSeparator()
      method SaveSorting (line 151) | private void SaveSorting()
      method MoveItem (line 156) | private void MoveItem(MyListItem item, bool isUp)
      method DeleteItem (line 178) | private void DeleteItem(MyListItem item)
      class SubShellItem (line 189) | sealed class SubShellItem : SubShellTypeItem
        method SubShellItem (line 191) | public SubShellItem(PulicMultiItemsList list, string keyName) : ba...
        method DeleteReference (line 204) | private void DeleteReference()
      class SeparatorItem (line 213) | sealed class SeparatorItem : SubSeparatorItem
        method SeparatorItem (line 215) | public SeparatorItem(PulicMultiItemsList list) : base()
        method DeleteMe (line 224) | public override void DeleteMe()
      class InvalidItem (line 230) | sealed class InvalidItem : MyListItem, IBtnDeleteItem, IBtnMoveUpDow...
        method InvalidItem (line 232) | public InvalidItem(PulicMultiItemsList list, string keyName)
        method DeleteMe (line 251) | public void DeleteMe()
    class PrivateMultiItemsList (line 258) | sealed class PrivateMultiItemsList : MyList
      method LoadItems (line 273) | public void LoadItems()
      method AddNewItem (line 309) | private void AddNewItem()
      method AddSeparator (line 323) | private void AddSeparator()
      method AddFromParentMenu (line 340) | private void AddFromParentMenu()
      method MoveItem (line 361) | public void MoveItem(MyListItem item, bool isUp)
      method GetItemRegPath (line 394) | private string GetItemRegPath(MyListItem item)
      method SetItemRegPath (line 400) | private void SetItemRegPath(MyListItem item, string regPath)
      class SubShellItem (line 406) | sealed class SubShellItem : SubShellTypeItem
        method SubShellItem (line 408) | public SubShellItem(PrivateMultiItemsList list, string regPath) : ...
        method SetItemTextValue (line 418) | private void SetItemTextValue()
      class SeparatorItem (line 436) | sealed class SeparatorItem : SubSeparatorItem
        method SeparatorItem (line 438) | public SeparatorItem(PrivateMultiItemsList list, string regPath)
        method DeleteMe (line 449) | public override void DeleteMe()
    class SubSeparatorItem (line 461) | class SubSeparatorItem : MyListItem, IBtnDeleteItem, IBtnMoveUpDownItem
      method SubSeparatorItem (line 463) | public SubSeparatorItem()
      method DeleteMe (line 477) | public virtual void DeleteMe() { }
    class SubShellTypeItem (line 480) | class SubShellTypeItem : ShellItem, IBtnMoveUpDownItem
      method SubShellTypeItem (line 482) | public SubShellTypeItem(string regPath) : base(regPath)
      method CanAddMore (line 495) | public static bool CanAddMore(MyList list)
    class SubNewItem (line 508) | sealed class SubNewItem : NewItem
      method SubNewItem (line 510) | public SubNewItem(bool isPublic)

FILE: ContextMenuManager/Controls/SubItemsForm.cs
  class SubItemsForm (line 9) | sealed class SubItemsForm : Form
    method SubItemsForm (line 11) | public SubItemsForm()
    method AddList (line 26) | public void AddList(MyList myList)

FILE: ContextMenuManager/Controls/SwitchDicList.cs
  class SwitchDicList (line 10) | class SwitchDicList : MyList
    method LoadItems (line 14) | public virtual void LoadItems()
    method AddSwitchItem (line 19) | public void AddSwitchItem()
  class SwitchDicItem (line 32) | sealed class SwitchDicItem : MyListItem
    method SwitchDicItem (line 34) | public SwitchDicItem()

FILE: ContextMenuManager/Controls/UwpModeItem.cs
  class UwpModeItem (line 11) | sealed class UwpModeItem : MyListItem, IChkVisibleItem, ITsiRegPathItem,...
    method UwpModeItem (line 14) | public UwpModeItem(string uwpName, Guid guid)
    method InitializeComponents (line 77) | private void InitializeComponents()
    method DeleteMe (line 96) | public void DeleteMe()

FILE: ContextMenuManager/Controls/WinXGroupItem.cs
  class WinXGroupItem (line 8) | sealed class WinXGroupItem : FoldGroupItem, IChkVisibleItem, ITsiDeleteI...
    method WinXGroupItem (line 10) | public WinXGroupItem(string groupPath) : base(groupPath, ObjectPath.Pa...
    method InitializeComponents (line 47) | private void InitializeComponents()
    method RestoreDefault (line 59) | private void RestoreDefault()
    method DeleteMe (line 79) | public void DeleteMe()

FILE: ContextMenuManager/Controls/WinXItem.cs
  class WinXItem (line 11) | sealed class WinXItem : FoldSubItem, IChkVisibleItem, IBtnShowMenuItem, ...
    method WinXItem (line 14) | public WinXItem(string filePath, FoldGroupItem group)
    method InitializeComponents (line 116) | private void InitializeComponents()
    method ChangeGroup (line 151) | private void ChangeGroup()
    method MoveItem (line 190) | private void MoveItem(bool isUp)
    method DeleteMe (line 220) | public void DeleteMe()

FILE: ContextMenuManager/Controls/WinXList.cs
  class WinXList (line 12) | sealed class WinXList : MyList
    method LoadItems (line 17) | public void LoadItems()
    method LoadWinXItems (line 26) | private void LoadWinXItems()
    method AddNewItem (line 60) | private void AddNewItem()
    method CreateNewGroup (line 124) | private void CreateNewGroup()
    method GetGroupNames (line 135) | public static string[] GetGroupNames()
    method GetSortedPaths (line 144) | private static string[] GetSortedPaths(string groupPath, out bool sorted)

FILE: ContextMenuManager/MainForm.cs
  class MainForm (line 13) | sealed class MainForm : MyMainForm
    method MainForm (line 15) | public MainForm()
    method JumpItem (line 212) | public void JumpItem(int toolBarIndex, int sideBarIndex)
    method RefreshApp (line 225) | private void RefreshApp()
    method SwitchTab (line 236) | private void SwitchTab()
    method SwitchItem (line 252) | private void SwitchItem()
    method ShowItemInfo (line 275) | private void ShowItemInfo()
    method HoveredToShowItemPath (line 293) | private void HoveredToShowItemPath()
    method DragDropToAnalysis (line 314) | private void DragDropToAnalysis()
    method SwitchGeneralItem (line 324) | private void SwitchGeneralItem()
    method SwitchTypeItem (line 342) | private void SwitchTypeItem()
    method SwitchOtherRuleItem (line 349) | private void SwitchOtherRuleItem()
    method SwitchAboutItem (line 370) | private void SwitchAboutItem()
    method ResizeSideBar (line 391) | private void ResizeSideBar()
    method AddContextMenus (line 398) | private void AddContextMenus()
    method FirstRunDownloadLanguage (line 479) | private void FirstRunDownloadLanguage()
    method CloseMainForm (line 494) | private void CloseMainForm()

FILE: ContextMenuManager/Methods/AppConfig.cs
  class AppConfig (line 12) | static class AppConfig
    method AppConfig (line 14) | static AppConfig()
    method GetGeneralValue (line 85) | private static string GetGeneralValue(string key)
    method SetGeneralValue (line 90) | private static void SetGeneralValue(string key, object value)
    method GetWindowValue (line 96) | private static string GetWindowValue(string key)
    method SetWindowValue (line 101) | private static void SetWindowValue(string key, object value)
    method ReloadConfig (line 107) | public static void ReloadConfig()
    method CreateDirectory (line 112) | private static void CreateDirectory()
    method LoadLanguage (line 127) | private static void LoadLanguage()

FILE: ContextMenuManager/Methods/AppImage.cs
  class AppImage (line 8) | static class AppImage
    method GetIconImage (line 94) | private static Image GetIconImage(string dllName, int iconIndex)

FILE: ContextMenuManager/Methods/AppMessageBox.cs
  class AppMessageBox (line 6) | public static class AppMessageBox
    method Show (line 8) | public static DialogResult Show(string text, MessageBoxButtons buttons...

FILE: ContextMenuManager/Methods/AppString.cs
  class AppString (line 8) | static class AppString
    method GetValue (line 13) | private static string GetValue(string section, string key)
    method LoadStrings (line 21) | public static void LoadStrings()
    class General (line 33) | public static class General
    class ToolBar (line 39) | public static class ToolBar
    class SideBar (line 49) | public static class SideBar
    class StatusBar (line 88) | public static class StatusBar
    class Menu (line 122) | public static class Menu
    class Dialog (line 166) | public static class Dialog
    class Message (line 219) | public static class Message
    class Tip (line 259) | public static class Tip
    class Other (line 281) | public static class Other

FILE: ContextMenuManager/Methods/DesktopIni.cs
  class DesktopIni (line 6) | static class DesktopIni
    method GetDesktopIniPath (line 10) | public static string GetDesktopIniPath(string filePath) => $@"{Path.Ge...
    method DeleteLocalizedFileNames (line 12) | public static void DeleteLocalizedFileNames(string filePath)
    method SetLocalizedFileNames (line 19) | public static void SetLocalizedFileNames(string filePath, string name)
    method GetLocalizedFileNames (line 26) | public static string GetLocalizedFileNames(string filePath, bool trans...

FILE: ContextMenuManager/Methods/GuidInfo.cs
  class GuidInfo (line 13) | static class GuidInfo
    type IconLocation (line 22) | public struct IconLocation
      method Tostring (line 26) | public string Tostring() => $"{IconPath},{IconIndex}";
    method ReloadDics (line 40) | public static void ReloadDics()
    method RemoveDic (line 51) | public static void RemoveDic(Guid guid)
    method TryGetValue (line 61) | private static bool TryGetValue(Guid guid, string key, out string value)
    method GetFilePath (line 72) | public static string GetFilePath(Guid guid)
    method GetClsidPath (line 123) | public static string GetClsidPath(Guid guid)
    method GetText (line 136) | public static string GetText(Guid guid)
    method GetImage (line 189) | public static Image GetImage(Guid guid)
    method GetIconLocation (line 202) | public static IconLocation GetIconLocation(Guid guid)
    method GetUwpName (line 226) | public static string GetUwpName(Guid guid)
    method GetAbsStr (line 239) | private static string GetAbsStr(Guid guid, string relStr, bool isName)

FILE: ContextMenuManager/Methods/ObjectPath.cs
  class ObjectPath (line 10) | static class ObjectPath
    type PathType (line 13) | public enum PathType { File, Directory, Registry }
    method GetFullFilePath (line 24) | public static bool GetFullFilePath(string fileName, out string fullPath)
    method ExtractFilePath (line 51) | public static string ExtractFilePath(string command)
    method RemoveIllegalChars (line 126) | public static string RemoveIllegalChars(string fileName)
    method ObjectPathExist (line 136) | public static bool ObjectPathExist(string path, PathType type)
    method GetNewPathWithIndex (line 155) | public static string GetNewPathWithIndex(string oldPath, PathType type...

FILE: ContextMenuManager/Methods/Updater.cs
  class Updater (line 10) | sealed class Updater
    method PeriodicUpdate (line 13) | public static void PeriodicUpdate()
    method Update (line 25) | public static void Update(bool isManual)
    method UpdateApp (line 34) | private static void UpdateApp(bool isManual)
    method UpdateText (line 100) | private static void UpdateText(bool isManual)
    method MachinedInfo (line 147) | private static string MachinedInfo(string info)

FILE: ContextMenuManager/Methods/UwpHelper.cs
  class UwpHelper (line 8) | static class UwpHelper
    method GetPackageName (line 13) | public static string GetPackageName(string uwpName)
    method GetRegPath (line 30) | public static string GetRegPath(string uwpName, Guid guid)
    method GetFilePath (line 37) | public static string GetFilePath(string uwpName, Guid guid)

FILE: ContextMenuManager/Methods/WinXHasher.cs
  class WinXHasher (line 15) | static class WinXHasher
    method HashData (line 17) | [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = t...
    method SHCreateItemFromParsingName (line 22) | [DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = fal...
    method PSGetPropertyKeyFromName (line 26) | [DllImport("propsys.dll", CharSet = CharSet.Unicode, SetLastError = tr...
    type IPropertyStore (line 29) | [ComImport]
      method GetCount (line 34) | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodC...
      method GetAt (line 37) | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodC...
      method GetValue (line 40) | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodC...
      method SetValue (line 43) | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodC...
      method Commit (line 46) | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodC...
    type IShellItem (line 50) | [ComImport]
      method BindToHandler (line 55) | void BindToHandler(IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] G...
      method GetParent (line 56) | void GetParent(out IShellItem ppsi);
      method GetDisplayName (line 57) | void GetDisplayName(uint sigdnName, out IntPtr ppszName);
      method GetAttributes (line 58) | void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
      method Compare (line 59) | void Compare(IShellItem psi, uint hint, out int piOrder);
    type IShellItem2 (line 62) | [ComImport]
      method BindToHandler (line 68) | [return: MarshalAs(UnmanagedType.Interface)]
      method GetParent (line 71) | IShellItem GetParent();
      method GetDisplayName (line 73) | [return: MarshalAs(UnmanagedType.LPWStr)]
      method GetAttributes (line 76) | uint GetAttributes(uint sfgaoMask);
      method Compare (line 78) | int Compare(IShellItem psi, uint hint);
      method GetPropertyStore (line 80) | [return: MarshalAs(UnmanagedType.Interface)]
      method GetPropertyStoreWithCreateObject (line 83) | [return: MarshalAs(UnmanagedType.Interface)]
      method GetPropertyStoreForKeys (line 86) | [return: MarshalAs(UnmanagedType.Interface)]
      method GetPropertyDescriptionList (line 89) | [return: MarshalAs(UnmanagedType.Interface)]
      method Update (line 92) | void Update(IBindCtx pbc);
      method GetProperty (line 94) | [SecurityCritical]
      method GetCLSID (line 97) | Guid GetCLSID(IntPtr key);
      method GetFileTime (line 99) | ComTypes.FILETIME GetFileTime(IntPtr key);
      method GetInt32 (line 101) | int GetInt32(IntPtr key);
      method GetString (line 103) | [return: MarshalAs(UnmanagedType.LPWStr)]
      method GetUInt32 (line 106) | uint GetUInt32(IntPtr key);
      method GetUInt64 (line 108) | ulong GetUInt64(IntPtr key);
      method GetBool (line 110) | [return: MarshalAs(UnmanagedType.Bool)]
    type PropertyKey (line 114) | [StructLayout(LayoutKind.Sequential, Pack = 4)]
    type PropVariant (line 121) | [StructLayout(LayoutKind.Explicit, Pack = 1)]
    type GPS (line 148) | [Flags]
    method HashLnk (line 163) | public static void HashLnk(string lnkPath)
    method GetGeneralizePath (line 210) | private static string GetGeneralizePath(string filePath)

FILE: ContextMenuManager/Methods/XmlDicHelper.cs
  class XmlDicHelper (line 12) | static class XmlDicHelper
    method ReloadDics (line 22) | public static void ReloadDics()
    method JudgeOSVersion (line 85) | public static bool JudgeOSVersion(XmlNode itemXN)
    method FileExists (line 118) | public static bool FileExists(XmlNode itemXN)
    method JudgeCulture (line 129) | public static bool JudgeCulture(XmlNode itemXN)
    method ConvertToBinary (line 139) | public static byte[] ConvertToBinary(string value)
    method GetValueKind (line 154) | public static RegistryValueKind GetValueKind(string type, RegistryValu...

FILE: ContextMenuManager/Program.cs
  class Program (line 9) | static class Program
    method Main (line 11) | [STAThread]

FILE: ContextMenuManager/Properties/Resources.Designer.cs
  class Resources (line 22) | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resource...
    method Resources (line 31) | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Mic...

FILE: ContextMenuManager/Properties/Resources/ShellNew/0.c
  function main (line 3) | int main()

FILE: ContextMenuManager/Properties/Settings.Designer.cs
  class Settings (line 14) | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
Condensed preview — 146 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (980K chars).
[
  {
    "path": ".gitattributes",
    "chars": 2518,
    "preview": "###############################################################################\n# Set default behavior to automatically "
  },
  {
    "path": ".gitignore",
    "chars": 4305,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": "ContextMenuManager/App.config",
    "chars": 313,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <startup>\n    \n  <supportedRuntime version=\"v4.0\" sku=\".NETFram"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs",
    "chars": 4156,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/IconDialog.cs",
    "chars": 978,
    "preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace BluePoint"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/InputDialog.cs",
    "chars": 3525,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyCheckBox.cs",
    "chars": 4433,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Drawing.Dra"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyListBox.cs",
    "chars": 9147,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Window"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyMainForm.cs",
    "chars": 3552,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MySideBar.cs",
    "chars": 7294,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyStatusBar.cs",
    "chars": 2320,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Windows.Form"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyToolBar.cs",
    "chars": 4499,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/PictureButton.cs",
    "chars": 1096,
    "preview": "using System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public class P"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/ReadOnlyTextBox.cs",
    "chars": 2342,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/ResizeLimitedForm.cs",
    "chars": 2133,
    "preview": "using System;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    /// <summary>限制水平、竖直方向调整大小的窗体</summa"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/SelectDialog.cs",
    "chars": 4187,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/UAWebClient.cs",
    "chars": 2284,
    "preview": "using System;\nusing System.IO;\nusing System.Net;\nusing System.Runtime.Serialization.Json;\nusing System.Text;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs",
    "chars": 625,
    "preview": "using System;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ComboBoxExtension"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ControlExtension.cs",
    "chars": 1724,
    "preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n   "
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/DirectoryEx.cs",
    "chars": 796,
    "preview": "using System.IO;\n\nnamespace BluePointLilac.Methods\n{\n    public static class DirectoryEx\n    {\n        public static vo"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs",
    "chars": 5179,
    "preview": "using System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Runtime.InteropServices;\nusing System.Tex"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/EncodingType.cs",
    "chars": 2794,
    "preview": "using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\n\nnamespace BluePointLilac.Meth"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs",
    "chars": 10879,
    "preview": "using Microsoft.Win32;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.InteropServices;\nu"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/FileExtension.cs",
    "chars": 2923,
    "preview": "using Microsoft.Win32;\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace BluePointLilac"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/FormExtension.cs",
    "chars": 1453,
    "preview": "using System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class FormExten"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/GuidEx.cs",
    "chars": 999,
    "preview": "using System;\nusing System.Text.RegularExpressions;\n\nnamespace BluePointLilac.Methods\n{\n    //为兼容.Net Framework 3.5,无法引"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/HighDpi.cs",
    "chars": 1812,
    "preview": "using System.Drawing;\nusing System.Windows;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    /// <su"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ImageExtension.cs",
    "chars": 2826,
    "preview": "using System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Drawing.Imaging;\n\nnamespace BluePointLilac.Methods\n{"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/IniReader.cs",
    "chars": 5601,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\n\nnamespace BlueP"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/IniWriter.cs",
    "chars": 6110,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/MessageBoxEx.cs",
    "chars": 11238,
    "preview": "using System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    /// <summary>在窗"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/RegTrustedInstaller.cs",
    "chars": 10087,
    "preview": "using Microsoft.Win32;\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Security.AccessControl;\nusing S"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/RegistryEx.cs",
    "chars": 6399,
    "preview": "using Microsoft.Win32;\nusing System;\nusing System.Security.AccessControl;\n\nnamespace BluePointLilac.Methods\n{\n    publi"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ResourceIcon.cs",
    "chars": 7894,
    "preview": "using Microsoft.Win32;\nusing System;\nusing System.Drawing;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ResourceString.cs",
    "chars": 1523,
    "preview": "using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{\n    public s"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/RichTextBoxExtension.cs",
    "chars": 19209,
    "preview": "using System;\nusing System.Drawing;\nusing System.Windows.Forms;\nusing System.Xml.Linq;\n\nnamespace BluePointLilac.Method"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ShellLink.cs",
    "chars": 10852,
    "preview": "using System;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Runtime.InteropServices.ComTypes;\nusi"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs",
    "chars": 3514,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.Interop"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/StringExtension.cs",
    "chars": 360,
    "preview": "namespace BluePointLilac.Methods\n{\n    //为兼容.Net Framework 3.5,无法引用Microsoft.CSharp.dll(中的string.IsNullOrWhiteSpace)写了这"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/TextBoxExtension.cs",
    "chars": 2397,
    "preview": "using System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class TextBoxEx"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ToolTipBox.cs",
    "chars": 618,
    "preview": "using System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ToolTipBox\n    {\n        public"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/WinOsVersion.cs",
    "chars": 1542,
    "preview": "using System;\n\nnamespace BluePointLilac.Methods\n{\n    // 判断Windows系统版本\n    // https://docs.microsoft.com/windows/releas"
  },
  {
    "path": "ContextMenuManager/ContextMenuManager.csproj",
    "chars": 19650,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbui"
  },
  {
    "path": "ContextMenuManager/Controls/AppSettingBox.cs",
    "chars": 10861,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nus"
  },
  {
    "path": "ContextMenuManager/Controls/DetailedEditDialog.cs",
    "chars": 1108,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Windows.Forms;\n\nnamespace Co"
  },
  {
    "path": "ContextMenuManager/Controls/DetailedEditList.cs",
    "chars": 13387,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Colle"
  },
  {
    "path": "ContextMenuManager/Controls/DictionariesBox.cs",
    "chars": 4984,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/DonateBox.cs",
    "chars": 10184,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/EnhanceMenusDialog.cs",
    "chars": 975,
    "preview": "using ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMen"
  },
  {
    "path": "ContextMenuManager/Controls/EnhanceMenusItem.cs",
    "chars": 8348,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Mic"
  },
  {
    "path": "ContextMenuManager/Controls/EnhanceMenusList.cs",
    "chars": 7245,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Xml;\n\n"
  },
  {
    "path": "ContextMenuManager/Controls/ExplorerRestarter.cs",
    "chars": 1567,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/FileExtensionDialog.cs",
    "chars": 1480,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/FoldSubItem.cs",
    "chars": 4863,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/GuidBlockedItem.cs",
    "chars": 4055,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/GuidBlockedList.cs",
    "chars": 2822,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nu"
  },
  {
    "path": "ContextMenuManager/Controls/IEItem.cs",
    "chars": 4717,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/IEList.cs",
    "chars": 2059,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collecti"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IBtnDeleteItem.cs",
    "chars": 705,
    "preview": "using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuMana"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IBtnMoveUpDownItem.cs",
    "chars": 479,
    "preview": "using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n  "
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IBtnShowMenuItem.cs",
    "chars": 813,
    "preview": "using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuMana"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IChkVisibleItem.cs",
    "chars": 1028,
    "preview": "using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n  "
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IProtectOpenItem.cs",
    "chars": 170,
    "preview": "namespace ContextMenuManager.Controls.Interfaces\n{\n    interface IProtectOpenItem\n    {\n        bool ItemVisible { get;"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiAdministratorItem.cs",
    "chars": 1597,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiCommandItem.cs",
    "chars": 1439,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nus"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiDeleteItem.cs",
    "chars": 2140,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiFilePathItem.cs",
    "chars": 1376,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiGuidItem.cs",
    "chars": 12772,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiIconItem.cs",
    "chars": 1455,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nus"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiRegExportItem.cs",
    "chars": 1922,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.For"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiRegPathItem.cs",
    "chars": 891,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManag"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiShortcutCommandItem.cs",
    "chars": 5433,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiTextItem.cs",
    "chars": 1442,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Windows.For"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiWebSearchItem.cs",
    "chars": 653,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManag"
  },
  {
    "path": "ContextMenuManager/Controls/LanguagesBox.cs",
    "chars": 21796,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/NewIEDialog.cs",
    "chars": 2179,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.For"
  },
  {
    "path": "ContextMenuManager/Controls/NewItem.cs",
    "chars": 754,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\n\nnamespace"
  },
  {
    "path": "ContextMenuManager/Controls/NewItemForm.cs",
    "chars": 4143,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/NewLnkFileDialog.cs",
    "chars": 5340,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.For"
  },
  {
    "path": "ContextMenuManager/Controls/NewOpenWithDialog.cs",
    "chars": 3847,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Diagnostics;\nusing System.IO"
  },
  {
    "path": "ContextMenuManager/Controls/NewShellDialog.cs",
    "chars": 7708,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.For"
  },
  {
    "path": "ContextMenuManager/Controls/OpenWithItem.cs",
    "chars": 5216,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/OpenWithList.cs",
    "chars": 2697,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nu"
  },
  {
    "path": "ContextMenuManager/Controls/RuleItem.cs",
    "chars": 18691,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/SendToItem.cs",
    "chars": 8823,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/SendToList.cs",
    "chars": 4076,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/ShellExItem.cs",
    "chars": 6524,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Mic"
  },
  {
    "path": "ContextMenuManager/Controls/ShellExecuteDialog.cs",
    "chars": 6374,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.IO;\nus"
  },
  {
    "path": "ContextMenuManager/Controls/ShellItem.cs",
    "chars": 23130,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/ShellList.cs",
    "chars": 44111,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nu"
  },
  {
    "path": "ContextMenuManager/Controls/ShellNewItem.cs",
    "chars": 13842,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/ShellNewList.cs",
    "chars": 13829,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/ShellStoreDialog.cs",
    "chars": 7408,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/ShellSubMenuDialog.cs",
    "chars": 21820,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/SubItemsForm.cs",
    "chars": 1504,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nus"
  },
  {
    "path": "ContextMenuManager/Controls/SwitchDicList.cs",
    "chars": 2056,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/Controls/UwpModeItem.cs",
    "chars": 3952,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/WinXGroupItem.cs",
    "chars": 3852,
    "preview": "using ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing System.IO;\nusing System.Windows.F"
  },
  {
    "path": "ContextMenuManager/Controls/WinXItem.cs",
    "chars": 9833,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing Contex"
  },
  {
    "path": "ContextMenuManager/Controls/WinXList.cs",
    "chars": 8160,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing Syst"
  },
  {
    "path": "ContextMenuManager/MainForm.cs",
    "chars": 19620,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls;\nusing ContextMenuManage"
  },
  {
    "path": "ContextMenuManager/Methods/AppConfig.cs",
    "chars": 11939,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Global"
  },
  {
    "path": "ContextMenuManager/Methods/AppImage.cs",
    "chars": 5334,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Properties;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nn"
  },
  {
    "path": "ContextMenuManager/Methods/AppMessageBox.cs",
    "chars": 451,
    "preview": "using BluePointLilac.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Methods\n{\n    public static cla"
  },
  {
    "path": "ContextMenuManager/Methods/AppString.cs",
    "chars": 17243,
    "preview": "using BluePointLilac.Methods;\nusing System;\nusing System.Reflection;\nusing System.Text;\n\nnamespace ContextMenuManager.Me"
  },
  {
    "path": "ContextMenuManager/Methods/DesktopIni.cs",
    "chars": 1316,
    "preview": "using BluePointLilac.Methods;\nusing System.IO;\n\nnamespace ContextMenuManager.Methods\n{\n    static class DesktopIni\n    "
  },
  {
    "path": "ContextMenuManager/Methods/GuidInfo.cs",
    "chars": 11291,
    "preview": "using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagn"
  },
  {
    "path": "ContextMenuManager/Methods/ObjectPath.cs",
    "chars": 7376,
    "preview": "using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nu"
  },
  {
    "path": "ContextMenuManager/Methods/Updater.cs",
    "chars": 7483,
    "preview": "using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;"
  },
  {
    "path": "ContextMenuManager/Methods/UwpHelper.cs",
    "chars": 2328,
    "preview": "using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.IO;\n\nnamespace ContextMenuManager.Metho"
  },
  {
    "path": "ContextMenuManager/Methods/WinXHasher.cs",
    "chars": 9498,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServ"
  },
  {
    "path": "ContextMenuManager/Methods/XmlDicHelper.cs",
    "chars": 6610,
    "preview": "using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Globa"
  },
  {
    "path": "ContextMenuManager/Program.cs",
    "chars": 606,
    "preview": "using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Windows.Forms;\n\nnamespace Co"
  },
  {
    "path": "ContextMenuManager/Properties/App.manifest",
    "chars": 1112,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n  <ass"
  },
  {
    "path": "ContextMenuManager/Properties/AssemblyInfo.cs",
    "chars": 577,
    "preview": "using System.Reflection;\nusing System.Runtime.InteropServices;\n\n[assembly: AssemblyTitle(\"Windows右键管理\")]\n[assembly: Ass"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.c",
    "chars": 49,
    "preview": "#include <stdio.h>\n \nint main()\n{\n    return 0;\n}"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.html",
    "chars": 115,
    "preview": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta charset=\"utf-8\">\n    <title></title>\n  </head>\n  <body>\n  </body>\n</html>"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.rtf",
    "chars": 7,
    "preview": "{\\rtf1}"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.xml",
    "chars": 38,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/AppLanguageDic.ini",
    "chars": 8912,
    "preview": ";此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典。\n;可帮助作者为此程序提供翻译并提交到Github,以下内容中等号右侧内容替换为翻译文本。\n;General - Translator 为翻译贡"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/DetailedEditDic.xml",
    "chars": 23776,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--每个程序为一个Group,Text为Group项显示文本,Guid用于判断用户是否安装此程序并决定是否显示该Group,不设置Guid则为常驻菜单,Reg"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/EnhanceMenusDic.xml",
    "chars": 50277,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--此文件为常用右键菜单字典, 可为此字典添加多语言翻译,添加一个Culture子项并设置为en-US、ja-JP等即可\nTip属性为鼠标悬浮在开关上时的提"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/GuidInfosDic.ini",
    "chars": 18411,
    "preview": ";<说明>:\n;由于ShellEx类型右键菜单的菜单名称和图标无法直接获取,只能通过制作字典给用户更直观的体验\n;此文件为依赖<GUID>的ShellEx类型右键菜单项目的名称和图标字典\n;<GUID>可通过右键程序内ShellEx项目\""
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/UwpModeItemsDic.xml",
    "chars": 686,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- 微软在Win10右键菜单中新增的UWP模块, 非Shell、ShellEx类型,\n但是可通过GUID锁定屏蔽来禁用相关右键菜单项目,\nGUID查找位置"
  },
  {
    "path": "ContextMenuManager/Properties/Resources.Designer.cs",
    "chars": 16216,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n/"
  },
  {
    "path": "ContextMenuManager/Properties/Resources.resx",
    "chars": 13435,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The prim"
  },
  {
    "path": "ContextMenuManager/Properties/Settings.Designer.cs",
    "chars": 984,
    "preview": "//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n/"
  },
  {
    "path": "ContextMenuManager/Properties/Settings.settings",
    "chars": 239,
    "preview": "<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\""
  },
  {
    "path": "ContextMenuManager.sln",
    "chars": 1133,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.3100"
  },
  {
    "path": "Donate.md",
    "chars": 6527,
    "preview": "# ContextMenuManager 捐赠名单\n\n## 捐赠说明\n\n> ContextMenuManager完全开源免费,如果你觉得此程序帮助到了你,可以对作者进行捐赠,金额请随意,谢谢支持!\n\n> 备注:收款码平台会隐藏付款方ID,可"
  },
  {
    "path": "LICENSE",
    "chars": 35147,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "README-en.md",
    "chars": 3965,
    "preview": "**[简体中文](README.md)** | **English**\n# ContextMenuManager\n![](Logo/Logo.png)\n------\n> 🖱️ A program to manage the Windows "
  },
  {
    "path": "README.md",
    "chars": 2433,
    "preview": "**简体中文** | **[English](README-en.md)**\n# ContextMenuManager\n![](Logo/Logo.png)\n------\n> 🖱️ 一个纯粹的Windows右键菜单管理程序\n\n## 程序下载"
  },
  {
    "path": "Update.ini",
    "chars": 231,
    "preview": ";自3.3.0.0版本以后使用新的更新模块,此文件不再使用\n\n[Update]\nVersion=3.3.3.0\nUrl=https://github.com/BluePointLilac/ContextMenuManager/release"
  },
  {
    "path": "languages/ar-DZ عربية",
    "chars": 15279,
    "preview": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionar"
  },
  {
    "path": "languages/de-DE.ini",
    "chars": 18815,
    "preview": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionar"
  },
  {
    "path": "languages/en-US.ini",
    "chars": 16567,
    "preview": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionar"
  },
  {
    "path": "languages/ja-JP.ini",
    "chars": 11109,
    "preview": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionar"
  },
  {
    "path": "languages/ko-KR.ini",
    "chars": 11139,
    "preview": ";이 파일은 ContextMenuManager 프로그램의 표시 텍스트 사전이며 사전의 새 줄 문자는 \\r\\n 또는 \\n로 이스케이프됩니다\r\n;작성자가 이 프로그램에 다른 언어 사전을 추가하는 것을 도와주려면 이 텍스"
  },
  {
    "path": "languages/zh-CN.ini",
    "chars": 8912,
    "preview": ";此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典。\n;可帮助作者为此程序提供翻译并提交到Github,以下内容中等号右侧内容替换为翻译文本。\n;General - Translator 为翻译贡"
  },
  {
    "path": "languages/zh-TW.ini",
    "chars": 8419,
    "preview": ";此檔案為 ContextMenuManager Windows右鍵管理程式 的顯示文字字典\n;翻譯:可幫助作者為此程式提供翻譯並提交到Github,以下內容中等號右側內容取代為翻譯文字,\n;General-Translator為翻譯貢獻"
  }
]

// ... and 5 more files (download for full content)

About this extraction

This page contains the full source code of the BluePointLilac/ContextMenuManager GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 146 files (916.3 KB), approximately 228.4k tokens, and a symbol index with 875 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!