[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n#*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# CodeRush\n.cr/\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc"
  },
  {
    "path": "ContextMenuManager/App.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <startup>\n    \n  <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.0\"/></startup>\n  <runtime>\n    <legacyCorruptedStateExceptionsPolicy enabled=\"true\"/>\n    <EnableWindowsFormsHighDpiAutoResizing enabled=\"true\"/>\n  </runtime>\n</configuration>\n"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    sealed class DownloadDialog : CommonDialog\n    {\n        public string Text { get; set; }\n        public string Url { get; set; }\n        public string FilePath { get; set; }\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(Process process = Process.GetCurrentProcess())\n            using(DownloadForm frm = new DownloadForm())\n            {\n                frm.Url = this.Url;\n                frm.Text = this.Text;\n                frm.FilePath = this.FilePath;\n                return frm.ShowDialog() == DialogResult.OK;\n            }\n        }\n\n        sealed class DownloadForm : Form\n        {\n            public DownloadForm()\n            {\n                this.SuspendLayout();\n                this.Font = SystemFonts.MessageBoxFont;\n                this.FormBorderStyle = FormBorderStyle.FixedSingle;\n                this.MinimizeBox = this.MaximizeBox = this.ShowInTaskbar = false;\n                this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\n                this.Controls.AddRange(new Control[] { pgbDownload, btnCancel });\n                this.Load += (sender, e) => DownloadFile(Url, FilePath);\n                this.InitializeComponents();\n                this.ResumeLayout();\n            }\n\n            readonly ProgressBar pgbDownload = new ProgressBar\n            {\n                Width = 200.DpiZoom(),\n                Maximum = 100\n            };\n            readonly Button btnCancel = new Button\n            {\n                DialogResult = DialogResult.Cancel,\n                Text = ResourceString.Cancel,\n                AutoSize = true\n            };\n\n            public string Url { get; set; }\n            public string FilePath { get; set; }\n\n            private void InitializeComponents()\n            {\n                int a = 20.DpiZoom();\n                pgbDownload.Left = pgbDownload.Top = btnCancel.Top = a;\n                pgbDownload.Height = btnCancel.Height;\n                btnCancel.Left = pgbDownload.Right + a;\n                this.ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);\n            }\n\n            private void DownloadFile(string url, string filePath)\n            {\n                try\n                {\n                    using(UAWebClient client = new UAWebClient())\n                    {\n                        client.DownloadProgressChanged += (sender, e) =>\n                        {\n                            int value = e.ProgressPercentage;\n                            this.Text = $\"Downloading: {value}%\";\n                            pgbDownload.Value = value;\n                            if(this.DialogResult == DialogResult.Cancel)\n                            {\n                                client.CancelAsync();\n                                File.Delete(FilePath);\n                            }\n                        };\n                        client.DownloadFileCompleted += (sender, e) =>\n                        {\n                            this.DialogResult = DialogResult.OK;\n                        };\n                        client.DownloadFileAsync(new Uri(url), filePath);\n                    }\n                }\n                catch(Exception e)\n                {\n                    MessageBox.Show(e.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);\n                    this.DialogResult = DialogResult.Cancel;\n                }\n            }\n\n            protected override void OnLoad(EventArgs e)\n            {\n                if(this.Owner == null && Form.ActiveForm != this) this.Owner = Form.ActiveForm;\n                if(this.Owner == null) this.StartPosition = FormStartPosition.CenterScreen;\n                else\n                {\n                    this.TopMost = this.Owner.TopMost;\n                    this.StartPosition = FormStartPosition.CenterParent;\n                }\n                base.OnLoad(e);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/IconDialog.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class IconDialog : CommonDialog\n    {\n        [DllImport(\"shell32.dll\", CharSet = CharSet.Unicode, EntryPoint = \"#62\", SetLastError = true)]\n        private static extern bool PickIconDlg(IntPtr hWnd, StringBuilder pszFileName, int cchFileNameMax, ref int pnIconIndex);\n\n        private const int MAXLENGTH = 260;\n        private int iconIndex;\n        public int IconIndex { get => iconIndex; set => iconIndex = value; }\n        public string IconPath { get; set; }\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            StringBuilder sb = new StringBuilder(IconPath, MAXLENGTH);\n            bool flag = PickIconDlg(hwndOwner, sb, MAXLENGTH, ref iconIndex);\n            IconPath = flag ? sb.ToString() : null;\n            return flag;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/InputDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class InputDialog : CommonDialog\n    {\n        /// <summary>输入对话框标题</summary>\n        public string Title { get; set; } = Application.ProductName;\n        /// <summary>输入对话框文本框文本</summary>\n        public string Text { get; set; }\n        public Size Size { get; set; }\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(InputBox frm = new InputBox())\n            {\n                frm.Text = Title;\n                frm.InputedText = this.Text;\n                frm.Size = this.Size;\n                Form owner = (Form)Control.FromHandle(hwndOwner);\n                if(owner != null) frm.TopMost = owner.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                this.Text = flag ? frm.InputedText : null;\n                return flag;\n            }\n        }\n\n        sealed class InputBox : Form\n        {\n            public InputBox()\n            {\n                this.AcceptButton = btnOK;\n                this.CancelButton = btnCancel;\n                this.Font = SystemFonts.MessageBoxFont;\n                this.SizeGripStyle = SizeGripStyle.Hide;\n                this.StartPosition = FormStartPosition.CenterParent;\n                this.MaximizeBox = MinimizeBox = ShowIcon = ShowInTaskbar = false;\n                this.Controls.AddRange(new Control[] { txtInput, btnOK, btnCancel });\n                txtInput.Font = new Font(txtInput.Font.FontFamily, txtInput.Font.Size + 2F);\n                txtInput.CanResizeFont();\n                InitializeComponents();\n            }\n\n            public string InputedText\n            {\n                get => txtInput.Text;\n                set => txtInput.Text = value;\n            }\n\n            readonly TextBox txtInput = new TextBox\n            {\n                Font = SystemFonts.MenuFont,\n                ScrollBars = ScrollBars.Vertical,\n                Multiline = true\n            };\n            readonly Button btnOK = new Button\n            {\n                Anchor = AnchorStyles.Bottom | AnchorStyles.Right,\n                DialogResult = DialogResult.OK,\n                Text = ResourceString.OK,\n                AutoSize = true\n            };\n            readonly Button btnCancel = new Button\n            {\n                Anchor = AnchorStyles.Bottom | AnchorStyles.Right,\n                DialogResult = DialogResult.Cancel,\n                Text = ResourceString.Cancel,\n                AutoSize = true\n            };\n\n            private void InitializeComponents()\n            {\n                this.SuspendLayout();\n                int a = 20.DpiZoom();\n                txtInput.Location = new Point(a, a);\n                txtInput.Size = new Size(340, 24).DpiZoom();\n                this.ClientSize = new Size(txtInput.Width + a * 2, txtInput.Height + btnOK.Height + a * 3);\n                btnCancel.Top = btnOK.Top = txtInput.Bottom + a;\n                btnCancel.Left = txtInput.Right - btnCancel.Width;\n                btnOK.Left = btnCancel.Left - btnOK.Width - a;\n                this.ResumeLayout();\n                this.MinimumSize = this.Size;\n                this.Resize += (sender, e) =>\n                {\n                    txtInput.Width = this.ClientSize.Width - 2 * a;\n                    txtInput.Height = btnCancel.Top - 2 * a;\n                };\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyCheckBox.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    [DefaultProperty(\"Checked\")]\n    public class MyCheckBox : PictureBox\n    {\n        public MyCheckBox()\n        {\n            this.Image = TurnOff;\n            this.Cursor = Cursors.Hand;\n            this.SizeMode = PictureBoxSizeMode.AutoSize;\n        }\n\n        private bool? _Checked = null;\n        public bool Checked\n        {\n            get => _Checked == true;\n            set\n            {\n                if(_Checked == value) return;\n                this.Image = SwitchImage(value);\n                if(_Checked == null)\n                {\n                    _Checked = value;\n                    return;\n                }\n                if(PreCheckChanging != null && !PreCheckChanging.Invoke())\n                {\n                    this.Image = SwitchImage(!value);\n                    return;\n                }\n                else CheckChanging?.Invoke();\n                if(PreCheckChanged != null && !PreCheckChanged.Invoke())\n                {\n                    this.Image = SwitchImage(!value);\n                    return;\n                }\n                else\n                {\n                    _Checked = value;\n                    CheckChanged?.Invoke();\n                }\n            }\n        }\n\n        public Func<bool> PreCheckChanging;\n        public Func<bool> PreCheckChanged;\n        public Action CheckChanging;\n        public Action CheckChanged;\n\n        public Image TurnOnImage { get; set; } = TurnOn;\n        public Image TurnOffImage { get; set; } = TurnOff;\n\n        private Image SwitchImage(bool value)\n        {\n            return value ? TurnOnImage : TurnOffImage;\n        }\n\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            base.OnMouseDown(e);\n            if(e.Button == MouseButtons.Left) this.Checked = !this.Checked;\n        }\n\n        private static readonly Image TurnOn = DrawImage(true);\n        private static readonly Image TurnOff = DrawImage(false);\n\n        private static Image DrawImage(bool value)\n        {\n            int w = 80.DpiZoom();\n            int r1 = 16.DpiZoom();\n            float r2 = 13F.DpiZoom();\n            int d1 = r1 * 2;\n            float d2 = r2 * 2;\n            float a = r1 - r2;\n            Bitmap bitmap = new Bitmap(w, d1);\n            using(Graphics g = Graphics.FromImage(bitmap))\n            {\n                g.InterpolationMode = InterpolationMode.HighQualityBicubic;\n                g.CompositingQuality = CompositingQuality.HighQuality;\n                g.PixelOffsetMode = PixelOffsetMode.HighQuality;\n                g.SmoothingMode = SmoothingMode.HighQuality;\n                using(GraphicsPath path = new GraphicsPath())\n                {\n                    path.AddArc(new RectangleF(0, 0, d1, d1), 90, 180);\n                    path.AddLine(new PointF(r1, 0), new PointF(w - r1, 0));\n                    path.AddArc(new RectangleF(w - d1, 0, d1, d1), -90, 180);\n                    path.AddLine(new PointF(w - r1, d1), new PointF(r1, d1));\n                    Color color = value ? Color.FromArgb(0, 138, 217) : Color.FromArgb(130, 136, 144);\n                    using(Brush brush = new SolidBrush(color))\n                    {\n                        g.FillPath(brush, path);\n                    }\n                }\n                using(GraphicsPath path = new GraphicsPath())\n                {\n                    path.AddArc(new RectangleF(a, a, d2, d2), 90, 180);\n                    path.AddLine(new PointF(r1, a), new PointF(w - r1, a));\n                    path.AddArc(new RectangleF(w - d2 - a, a, d2, d2), -90, 180);\n                    path.AddLine(new PointF(w - r1, d2 + a), new PointF(r1, d2 + a));\n                    Color color = value ? Color.FromArgb(0, 162, 255) : Color.FromArgb(153, 160, 169);\n                    using(Brush brush = new SolidBrush(color))\n                    {\n                        g.FillPath(brush, path);\n                    }\n                }\n                using(GraphicsPath path = new GraphicsPath())\n                {\n                    path.AddEllipse(new RectangleF(value ? (w - d2 - a) : a, a, d2, d2));\n                    g.FillPath(Brushes.White, path);\n                }\n            }\n            return bitmap;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyListBox.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public class MyListBox : Panel\n    {\n        public MyListBox()\n        {\n            this.AutoScroll = true;\n            this.BackColor = Color.FromArgb(250, 250, 250);\n        }\n\n        protected override void OnMouseWheel(MouseEventArgs e)\n        {\n            //使滚动幅度与MyListItem的高度相配合，防止滚动过快导致来不及重绘界面变花\n            base.OnMouseWheel(new MouseEventArgs(e.Button, e.Clicks, e.X, e.Y, Math.Sign(e.Delta) * 50.DpiZoom()));\n        }\n    }\n\n    public class MyList : FlowLayoutPanel\n    {\n        public MyListBox Owner\n        {\n            get => (MyListBox)this.Parent;\n            set => this.Parent = value;\n        }\n\n        public MyList(MyListBox owner) : this()\n        {\n            this.Owner = owner;\n        }\n\n        public MyList()\n        {\n            this.AutoSize = true;\n            this.WrapContents = true;\n            this.Dock = DockStyle.Top;\n            this.DoubleBuffered = true;\n            this.AutoSizeMode = AutoSizeMode.GrowAndShrink;\n        }\n\n        private MyListItem hoveredItem;\n        public MyListItem HoveredItem\n        {\n            get => hoveredItem;\n            set\n            {\n                if(hoveredItem == value) return;\n                if(hoveredItem != null)\n                {\n                    hoveredItem.ForeColor = Color.FromArgb(90, 90, 90);\n                    //hoveredItem.BackColor = Color.FromArgb(250, 250, 250);\n                    //hoveredItem.Font = new Font(hoveredItem.Font, FontStyle.Regular);\n                }\n                hoveredItem = value;\n                if(hoveredItem != null)\n                {\n                    value.ForeColor = Color.FromArgb(0, 138, 217);\n                    //value.BackColor = Color.FromArgb(200, 230, 250);\n                    //value.Font = new Font(hoveredItem.Font, FontStyle.Bold);\n                    value.Focus();\n                }\n                HoveredItemChanged?.Invoke(this, null);\n            }\n        }\n\n        public event EventHandler HoveredItemChanged;\n\n        public void AddItem(MyListItem item)\n        {\n            this.SuspendLayout();\n            item.Parent = this;\n            item.MouseEnter += (sender, e) => HoveredItem = item;\n            this.MouseWheel += (sender, e) => item.ContextMenuStrip?.Close();\n            void ResizeItem() => item.Width = Owner.Width - item.Margin.Horizontal;\n            Owner.Resize += (sender, e) => ResizeItem();\n            ResizeItem();\n            this.ResumeLayout();\n        }\n\n        public void AddItems(MyListItem[] items)\n        {\n            Array.ForEach(items, item => AddItem(item));\n        }\n\n        public void AddItems(List<MyListItem> items)\n        {\n            items.ForEach(item => AddItem(item));\n        }\n\n        public void SetItemIndex(MyListItem item, int newIndex)\n        {\n            this.Controls.SetChildIndex(item, newIndex);\n        }\n\n        public int GetItemIndex(MyListItem item)\n        {\n            return Controls.GetChildIndex(item);\n        }\n\n        public void InsertItem(MyListItem item, int index)\n        {\n            if(item == null) return;\n            this.AddItem(item);\n            this.SetItemIndex(item, index);\n        }\n\n        public virtual void ClearItems()\n        {\n            if(this.Controls.Count == 0) return;\n            this.SuspendLayout();\n            for(int i = this.Controls.Count - 1; i >= 0; i--)\n            {\n                Control ctr = this.Controls[i];\n                this.Controls.Remove(ctr);\n                ctr.Dispose();\n            }\n            this.ResumeLayout();\n        }\n\n        public void SortItemByText()\n        {\n            List<MyListItem> items = new List<MyListItem>();\n            foreach(MyListItem item in this.Controls) items.Add(item);\n            this.Controls.Clear();\n            items.Sort(new TextComparer());\n            items.ForEach(item => this.AddItem(item));\n        }\n\n        public class TextComparer : IComparer<MyListItem>\n        {\n            public int Compare(MyListItem x, MyListItem y)\n            {\n                if(x.Equals(y)) return 0;\n                string[] strs = { x.Text, y.Text };\n                Array.Sort(strs);\n                if(strs[0] == x.Text) return -1;\n                else return 1;\n            }\n        }\n    }\n\n    public class MyListItem : Panel\n    {\n        public MyListItem()\n        {\n            this.SuspendLayout();\n            this.HasImage = true;\n            this.DoubleBuffered = true;\n            this.Height = 50.DpiZoom();\n            this.Margin = new Padding(0);\n            this.Font = SystemFonts.IconTitleFont;\n            this.ForeColor = Color.FromArgb(80, 80, 80);\n            this.BackColor = Color.FromArgb(250, 250, 250);\n            this.Controls.AddRange(new Control[] { lblSeparator, flpControls, lblText, picImage });\n            this.Resize += (Sender, e) => pnlScrollbar.Height = this.ClientSize.Height;\n            flpControls.MouseClick += (sender, e) => this.OnMouseClick(e);\n            flpControls.MouseEnter += (sender, e) => this.OnMouseEnter(e);\n            flpControls.MouseDown += (sender, e) => this.OnMouseDown(e);\n            lblSeparator.SetEnabled(false);\n            lblText.SetEnabled(false);\n            CenterControl(lblText);\n            CenterControl(picImage);\n            AddCtr(pnlScrollbar, 0);\n            this.ResumeLayout();\n        }\n\n        public Image Image\n        {\n            get => picImage.Image;\n            set => picImage.Image = value;\n        }\n        public new string Text\n        {\n            get => lblText.Text;\n            set => lblText.Text = value;\n        }\n        public new Font Font\n        {\n            get => lblText.Font;\n            set => lblText.Font = value;\n        }\n        public new Color ForeColor\n        {\n            get => lblText.ForeColor;\n            set => lblText.ForeColor = value;\n        }\n\n        private bool hasImage;\n        public bool HasImage\n        {\n            get => hasImage;\n            set\n            {\n                hasImage = value;\n                picImage.Visible = value;\n                lblText.Left = (value ? 60 : 20).DpiZoom();\n            }\n        }\n\n        private readonly Label lblText = new Label\n        {\n            AutoSize = true,\n            Name = \"Text\"\n        };\n        private readonly PictureBox picImage = new PictureBox\n        {\n            SizeMode = PictureBoxSizeMode.AutoSize,\n            Left = 20.DpiZoom(),\n            Enabled = false,\n            Name = \"Image\"\n        };\n        private readonly FlowLayoutPanel flpControls = new FlowLayoutPanel\n        {\n            AutoSizeMode = AutoSizeMode.GrowAndShrink,\n            FlowDirection = FlowDirection.RightToLeft,\n            Anchor = AnchorStyles.Right,\n            AutoSize = true,\n            Name = \"Controls\"\n        };\n        private readonly Label lblSeparator = new Label\n        {\n            BackColor = Color.FromArgb(220, 220, 220),\n            Dock = DockStyle.Bottom,\n            Name = \"Separator\",\n            Height = 1\n        };//分割线\n        private readonly Panel pnlScrollbar = new Panel\n        {\n            Width = SystemInformation.VerticalScrollBarWidth,\n            Enabled = false\n        };//预留滚动条宽度\n\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            base.OnMouseDown(e); OnMouseEnter(null);\n        }\n\n        private void CenterControl(Control ctr)\n        {\n            void reSize()\n            {\n                if(ctr.Parent == null) return;\n                int top = (this.ClientSize.Height - ctr.Height) / 2;\n                ctr.Top = top;\n                if(ctr.Parent == flpControls)\n                {\n                    ctr.Margin = new Padding(0, top, ctr.Margin.Right, top);\n                }\n            }\n            ctr.Parent.Resize += (sender, e) => reSize();\n            ctr.Resize += (sender, e) => reSize();\n            reSize();\n        }\n\n        public void AddCtr(Control ctr)\n        {\n            AddCtr(ctr, 20.DpiZoom());\n        }\n\n        public void AddCtr(Control ctr, int space)\n        {\n            this.SuspendLayout();\n            ctr.Parent = flpControls;\n            ctr.Margin = new Padding(0, 0, space, 0);\n            ctr.MouseEnter += (sender, e) => this.OnMouseEnter(e);\n            ctr.MouseDown += (sender, e) => this.OnMouseEnter(e);\n            CenterControl(ctr);\n            this.ResumeLayout();\n        }\n\n        public void AddCtrs(Control[] ctrs)\n        {\n            Array.ForEach(ctrs, ctr => AddCtr(ctr));\n        }\n\n        public void RemoveCtrAt(int index)\n        {\n            if(flpControls.Controls.Count > index) flpControls.Controls.RemoveAt(index + 1);\n        }\n\n        public int GetCtrIndex(Control ctr)\n        {\n            return flpControls.Controls.GetChildIndex(ctr, true) - 1;\n        }\n\n        public void SetCtrIndex(Control ctr, int newIndex)\n        {\n            flpControls.Controls.SetChildIndex(ctr, newIndex + 1);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyMainForm.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public class MyMainForm : Form\n    {\n        public MyMainForm()\n        {\n            this.SuspendLayout();\n            this.Text = Application.ProductName;\n            this.ForeColor = Color.FromArgb(80, 80, 80);\n            this.BackColor = Color.FromArgb(250, 250, 250);\n            this.StartPosition = FormStartPosition.CenterScreen;\n            this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\n            this.Controls.AddRange(new Control[] { MainBody, SideBar, StatusBar, ToolBar });\n            SideBar.Resize += (sender, e) => this.OnResize(null);\n            this.ClientSize = new Size(850, 610).DpiZoom();\n            this.MinimumSize = this.Size;\n            MainBody.Dock = DockStyle.Left;\n            StatusBar.CanMoveForm();\n            ToolBar.CanMoveForm();\n            this.ResumeLayout();\n        }\n\n        public readonly MyToolBar ToolBar = new MyToolBar();\n        public readonly MySideBar SideBar = new MySideBar();\n        public readonly MyStatusBar StatusBar = new MyStatusBar();\n        public readonly MyListBox MainBody = new MyListBox();\n\n        /// <summary>窗体移动时是否临时挂起MainBody</summary>\n        public bool SuspendMainBodyWhenMove { get; set; } = false;\n        /// <summary>窗体调整大小时是否临时挂起MainBody</summary>\n        public bool SuspendMainBodyWhenResize { get; set; } = true;\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n            MainBody.Width = this.ClientSize.Width - SideBar.Width;\n        }\n\n        protected override void WndProc(ref Message m)\n        {\n            const int WM_NCLBUTTONDBLCLK = 0x00A3;\n            const int WM_SYSCOMMAND = 0x0112;\n            const int SC_MAXIMIZE = 0xF030;\n            const int SC_MINIMIZE = 0xF020;\n            const int SC_RESTORE = 0xF120;\n            const int SC_MOVE = 0xF012;\n            const int SC_SIZE = 0xF000;\n            const int HT_CAPTION = 0x2;\n            bool suspend = false;//临时挂起MainBody\n            switch(m.Msg)\n            {\n                case WM_SYSCOMMAND:\n                    switch(m.WParam.ToInt32())\n                    {\n                        //解决控件过多移动窗体时延迟问题\n                        case SC_MOVE:\n                        //解决控件过多调整窗体大小时延迟问题\n                        case SC_SIZE:\n                            suspend = this.SuspendMainBodyWhenMove; break;\n                        //解决控件过多最大化、最小化、还原重绘卡顿问题\n                        case SC_RESTORE:\n                        case SC_MINIMIZE:\n                        case SC_MAXIMIZE:\n                            suspend = this.SuspendMainBodyWhenResize; break;\n                    }\n                    break;\n                case WM_NCLBUTTONDBLCLK:\n                    switch(m.WParam.ToInt32())\n                    {\n                        //双击标题栏最大化和还原窗口\n                        case HT_CAPTION:\n                            suspend = this.SuspendMainBodyWhenResize; break;\n                    }\n                    break;\n            }\n            if(suspend)\n            {\n                this.SuspendLayout();\n                MainBody.SuspendLayout();\n                this.Controls.Remove(MainBody);\n                base.WndProc(ref m);\n                this.Controls.Add(MainBody);\n                MainBody.BringToFront();\n                MainBody.ResumeLayout();\n                this.ResumeLayout();\n            }\n            else base.WndProc(ref m);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MySideBar.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class MySideBar : Panel\n    {\n        public MySideBar()\n        {\n            this.Dock = DockStyle.Left;\n            this.ItemHeight = 30.DpiZoom();\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n            this.ForeColor = Color.FromArgb(80, 80, 80);\n            this.BackColor = Color.FromArgb(245, 245, 245);\n            this.BackgroundImageLayout = ImageLayout.None;\n            this.Controls.AddRange(new Control[] { LblSeparator, PnlSelected, PnlHovered });\n            PnlHovered.Paint += PaintItem;\n            PnlSelected.Paint += PaintItem;\n            this.SelectedIndex = -1;\n        }\n\n        private string[] itemNames;\n        public string[] ItemNames\n        {\n            get => itemNames;\n            set\n            {\n                itemNames = value;\n                if(value != null && !IsFixedWidth)\n                {\n                    int maxWidth = 0;\n                    Array.ForEach(value, str => maxWidth = Math.Max(maxWidth, GetItemWidth(str)));\n                    this.Width = maxWidth + 2 * HorizontalSpace;\n                }\n                PnlHovered.Width = PnlSelected.Width = this.Width;\n                PaintItems();\n                SelectedIndex = -1;\n            }\n        }\n\n        private int itemHeight;\n        public int ItemHeight\n        {\n            get => itemHeight;\n            set => PnlHovered.Height = PnlSelected.Height = itemHeight = value;\n        }//项上下边缘距离\n        public int TopSpace { get; set; } = 2.DpiZoom();//第一项顶部与上边缘的距离\n        public int HorizontalSpace { get; set; } = 20.DpiZoom();//项文字与项左右边缘距离\n        private float VerticalSpace => (itemHeight - TextHeight) * 0.5F;//项文字与项上下边缘距离\n        private int TextHeight => TextRenderer.MeasureText(\" \", Font).Height;//项文字高度\n        public bool IsFixedWidth { get; set; } = true;//是否固定宽度\n\n        public Color SeparatorColor\n        {\n            get => LblSeparator.BackColor;\n            set => LblSeparator.BackColor = value;\n        }//分隔线颜色\n        public Color SelectedBackColor\n        {\n            get => PnlSelected.BackColor;\n            set => PnlSelected.BackColor = value;\n        }\n        public Color HoveredBackColor\n        {\n            get => PnlHovered.BackColor;\n            set => PnlHovered.BackColor = value;\n        }\n        public Color SelectedForeColor\n        {\n            get => PnlSelected.ForeColor;\n            set => PnlSelected.ForeColor = value;\n        }\n        public Color HoveredForeColor\n        {\n            get => PnlHovered.ForeColor;\n            set => PnlHovered.ForeColor = value;\n        }\n\n        readonly Panel PnlSelected = new Panel\n        {\n            BackColor = Color.FromArgb(40, 140, 210),\n            ForeColor = Color.White,\n            Enabled = false\n        };\n        readonly Panel PnlHovered = new Panel\n        {\n            BackColor = Color.FromArgb(80, 180, 250),\n            ForeColor = Color.White,\n            Enabled = false\n        };\n        readonly Label LblSeparator = new Label\n        {\n            BackColor = Color.FromArgb(220, 220, 220),\n            Dock = DockStyle.Right,\n            Width = 1,\n        };\n\n        /// <summary>获取项目宽度</summary>\n        public int GetItemWidth(string str)\n        {\n            return TextRenderer.MeasureText(str, Font).Width + 2 * HorizontalSpace;\n        }\n\n        /// <summary>绘制所有项目作为底图</summary>\n        private void PaintItems()\n        {\n            this.BackgroundImage = new Bitmap(Width, ItemHeight * ItemNames.Length);\n            using(Graphics g = Graphics.FromImage(BackgroundImage))\n            {\n                g.Clear(BackColor);\n                if(itemNames == null) return;\n                for(int i = 0; i < itemNames.Length; i++)\n                {\n                    if(itemNames[i] != null)\n                    {\n                        g.DrawString(itemNames[i], Font, new SolidBrush(ForeColor),\n                            new PointF(HorizontalSpace, TopSpace + i * ItemHeight + VerticalSpace));\n                    }\n                    else\n                    {\n                        g.DrawLine(new Pen(SeparatorColor),\n                            new PointF(HorizontalSpace, TopSpace + (i + 0.5F) * ItemHeight),\n                            new PointF(Width - HorizontalSpace, TopSpace + (i + 0.5F) * ItemHeight)\n                        );\n                    }\n                }\n            }\n        }\n\n        /// <summary>刷新选中的项目</summary>\n        private void RefreshItem(Panel panel, int index)\n        {\n            panel.CreateGraphics().Clear(panel.BackColor);\n            panel.Top = index < 0 ? -ItemHeight : (TopSpace + index * ItemHeight);\n            panel.Text = index < 0 ? null : ItemNames[index];\n            panel.Refresh();\n        }\n\n        /// <summary>绘制选中的项目</summary>\n        private void PaintItem(object sender, PaintEventArgs e)\n        {\n            Control ctr = (Control)sender;\n            e.Graphics.DrawString(ctr.Text, Font,\n                new SolidBrush(ctr.ForeColor),\n                new PointF(HorizontalSpace, VerticalSpace));\n        }\n\n        /// <summary>显示选中的项目</summary>\n        private void ShowItem(Panel panel, MouseEventArgs e)\n        {\n            if(itemNames == null) return;\n            int index = (e.Y - TopSpace) / ItemHeight;\n            if(index >= itemNames.Length || index < 0 || string.IsNullOrEmpty(itemNames[index]) || index == SelectedIndex)\n            {\n                this.Cursor = Cursors.Default;\n                HoveredIndex = SelectedIndex;\n            }\n            else\n            {\n                this.Cursor = Cursors.Hand;\n                if(panel == PnlSelected) SelectedIndex = index;\n                else HoveredIndex = index;\n            }\n        }\n\n        protected override void OnMouseMove(MouseEventArgs e)\n        {\n            base.OnMouseMove(e);\n            ShowItem(PnlHovered, e);\n        }\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            base.OnMouseDown(e);\n            if(e.Button == MouseButtons.Left) ShowItem(PnlSelected, e);\n        }\n        protected override void OnMouseLeave(EventArgs e)\n        {\n            base.OnMouseLeave(e);\n            HoveredIndex = SelectedIndex;\n        }\n\n        public event EventHandler SelectIndexChanged;\n\n        public event EventHandler HoverIndexChanged;\n\n        private int selectIndex;\n        public int SelectedIndex\n        {\n            get => selectIndex;\n            set\n            {\n                if(selectIndex == value) return;\n                HoveredIndex = value;\n                RefreshItem(PnlSelected, value);\n                selectIndex = value;\n                SelectIndexChanged?.Invoke(this, null);\n            }\n        }\n\n        private int hoverIndex;\n        public int HoveredIndex\n        {\n            get => hoverIndex;\n            set\n            {\n                if(hoverIndex == value) return;\n                RefreshItem(PnlHovered, value);\n                hoverIndex = value;\n                HoverIndexChanged?.Invoke(this, null);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyStatusBar.cs",
    "content": "using BluePointLilac.Methods;\nusing System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class MyStatusBar : Panel\n    {\n        public static readonly string DefaultText = $\"Ver: {Application.ProductVersion}    {Application.CompanyName}\";\n\n        public MyStatusBar()\n        {\n            this.Text = DefaultText;\n            this.Height = 30.DpiZoom();\n            this.Dock = DockStyle.Bottom;\n            this.Font = SystemFonts.StatusFont;\n            this.BackColor = Color.FromArgb(70, 130, 200);\n            this.ForeColor = Color.White;\n        }\n\n        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)]\n        public override string Text { get => base.Text; set => base.Text = value; }\n\n        protected override void OnPaint(PaintEventArgs e)\n        {\n            base.OnPaint(e);\n            string txt = this.Text;\n            int left = this.Height / 3;\n            for(int i = this.Text.Length - 1; i >= 0; i--)\n            {\n                Size size = TextRenderer.MeasureText(txt, this.Font);\n                if(size.Width < ClientSize.Width - 2 * left)\n                {\n                    using(Brush brush = new SolidBrush(this.ForeColor))\n                    {\n                        int top = (this.Height - size.Height) / 2;\n                        e.Graphics.Clear(this.BackColor);\n                        e.Graphics.DrawString(txt, this.Font, brush, left, top);\n                        break;\n                    }\n                }\n                txt = this.Text.Substring(0, i) + \"...\";\n            }\n        }\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e); this.Refresh();\n        }\n        protected override void OnTextChanged(EventArgs e)\n        {\n            base.OnTextChanged(e); this.Refresh();\n        }\n        protected override void OnFontChanged(EventArgs e)\n        {\n            base.OnFontChanged(e); this.Refresh();\n        }\n        protected override void OnForeColorChanged(EventArgs e)\n        {\n            base.OnForeColorChanged(e); this.Refresh();\n        }\n        protected override void OnBackColorChanged(EventArgs e)\n        {\n            base.OnBackColorChanged(e); this.Refresh();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/MyToolBar.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class MyToolBar : FlowLayoutPanel\n    {\n        public MyToolBar()\n        {\n            this.Height = 80.DpiZoom();\n            this.Dock = DockStyle.Top;\n            this.DoubleBuffered = true;\n            this.BackColor = Color.FromArgb(85, 145, 215);\n        }\n\n        private MyToolBarButton selectedButton;\n        public MyToolBarButton SelectedButton\n        {\n            get => selectedButton;\n            set\n            {\n                if(selectedButton == value) return;\n                if(selectedButton != null)\n                {\n                    selectedButton.Opacity = 0;\n                    selectedButton.Cursor = Cursors.Hand;\n                }\n                selectedButton = value;\n                if(selectedButton != null)\n                {\n                    selectedButton.Opacity = 0.4F;\n                    selectedButton.Cursor = Cursors.Default;\n                }\n                SelectedButtonChanged?.Invoke(this, null);\n            }\n        }\n\n        public event EventHandler SelectedButtonChanged;\n\n        public int SelectedIndex\n        {\n            get\n            {\n                if(SelectedButton == null) return -1;\n                else return Controls.GetChildIndex(SelectedButton);\n            }\n            set\n            {\n                if(value < 0 || value >= this.Controls.Count) SelectedButton = null;\n                else SelectedButton = (MyToolBarButton)Controls[value];\n            }\n        }\n\n        public void AddButton(MyToolBarButton button)\n        {\n            this.SuspendLayout();\n            button.Parent = this;\n            button.Margin = new Padding(12, 4, 0, 0).DpiZoom();\n            button.MouseDown += (sender, e) =>\n            {\n                if(e.Button == MouseButtons.Left && button.CanBeSelected) SelectedButton = button;\n            };\n            button.MouseEnter += (sender, e) =>\n            {\n                if(button != SelectedButton) button.Opacity = 0.2F;\n            };\n            button.MouseLeave += (sender, e) =>\n            {\n                if(button != SelectedButton) button.Opacity = 0;\n            };\n            this.ResumeLayout();\n        }\n\n        public void AddButtons(MyToolBarButton[] buttons)\n        {\n            int maxWidth = 72.DpiZoom();\n            Array.ForEach(buttons, button => maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(button.Text, button.Font).Width));\n            Array.ForEach(buttons, button => { button.Width = maxWidth; AddButton(button); });\n        }\n    }\n\n    public sealed class MyToolBarButton : Panel\n    {\n        public MyToolBarButton(Image image, string text)\n        {\n            this.SuspendLayout();\n            this.DoubleBuffered = true;\n            this.Cursor = Cursors.Hand;\n            this.Size = new Size(72, 72).DpiZoom();\n            this.Controls.AddRange(new Control[] { picImage, lblText });\n            lblText.Resize += (sender, e) => this.OnResize(null);\n            picImage.Top = 6.DpiZoom();\n            lblText.Top = 52.DpiZoom();\n            lblText.SetEnabled(false);\n            this.Image = image;\n            this.Text = text;\n            this.ResumeLayout();\n        }\n\n        readonly PictureBox picImage = new PictureBox\n        {\n            SizeMode = PictureBoxSizeMode.StretchImage,\n            Size = new Size(40, 40).DpiZoom(),\n            BackColor = Color.Transparent,\n            Enabled = false\n        };\n\n        readonly Label lblText = new Label\n        {\n            BackColor = Color.Transparent,\n            Font = SystemFonts.MenuFont,\n            ForeColor = Color.White,\n            AutoSize = true,\n        };\n\n        public Image Image\n        {\n            get => picImage.Image;\n            set => picImage.Image = value;\n        }\n        public new string Text\n        {\n            get => lblText.Text;\n            set => lblText.Text = value;\n        }\n        public float Opacity\n        {\n            get => BackColor.A / 255;\n            set => BackColor = Color.FromArgb((int)(value * 255), Color.White);\n        }\n        public bool CanBeSelected { get; set; } = true;\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n            lblText.Left = (this.Width - lblText.Width) / 2;\n            picImage.Left = (this.Width - picImage.Width) / 2;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/PictureButton.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public class PictureButton : PictureBox\n    {\n        public PictureButton(Image image)\n        {\n            this.BaseImage = image;\n            this.SizeMode = PictureBoxSizeMode.AutoSize;\n            this.Cursor = Cursors.Hand;\n        }\n\n        private Image baseImage;\n        public Image BaseImage\n        {\n            get => baseImage;\n            set\n            {\n                baseImage = value;\n                this.Image = ToolStripRenderer.CreateDisabledImage(value);\n            }\n        }\n\n        protected override void OnMouseEnter(EventArgs e)\n        {\n            base.OnMouseEnter(e); this.Image = BaseImage;\n        }\n        protected override void OnMouseLeave(EventArgs e)\n        {\n            base.OnMouseLeave(e);\n            this.Image = ToolStripRenderer.CreateDisabledImage(BaseImage);\n        }\n        protected override void OnMouseDown(MouseEventArgs e)\n        {\n            if(e.Button == MouseButtons.Left) base.OnMouseDown(e);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/ReadOnlyTextBox.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class ReadOnlyTextBox : TextBox\n    {\n        public ReadOnlyTextBox()\n        {\n            this.ReadOnly = true;\n            this.Multiline = true;\n            this.ShortcutsEnabled = false;\n            this.BackColor = Color.White;\n            this.ForeColor = Color.FromArgb(80, 80, 80);\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n        }\n\n        const int WM_SETFOCUS = 0x0007;\n        const int WM_KILLFOCUS = 0x0008;\n        protected override void WndProc(ref Message m)\n        {\n            switch(m.Msg)\n            {\n                case WM_SETFOCUS:\n                    m.Msg = WM_KILLFOCUS; break;\n            }\n            base.WndProc(ref m);\n        }\n\n        private bool firstEnter = true;\n\n        protected override void OnMouseEnter(EventArgs e)\n        {\n            base.OnMouseEnter(e);\n            if(firstEnter) this.Focus();\n            firstEnter = false;\n        }\n    }\n\n    public sealed class ReadOnlyRichTextBox : RichTextBox\n    {\n        public ReadOnlyRichTextBox()\n        {\n            this.ReadOnly = true;\n            this.Dock = DockStyle.Fill;\n            this.BackColor = Color.White;\n            this.BorderStyle = BorderStyle.None;\n            this.ForeColor = Color.FromArgb(80, 80, 80);\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n        }\n\n        const int WM_SETFOCUS = 0x0007;\n        const int WM_KILLFOCUS = 0x0008;\n\n        protected override void WndProc(ref Message m)\n        {\n            switch(m.Msg)\n            {\n                case WM_SETFOCUS:\n                    m.Msg = WM_KILLFOCUS; break;\n            }\n            base.WndProc(ref m);\n        }\n\n        private bool firstEnter = true;\n\n        protected override void OnMouseEnter(EventArgs e)\n        {\n            base.OnMouseEnter(e);\n            if(firstEnter) this.Focus();\n            firstEnter = false;\n        }\n\n        protected override void OnLinkClicked(LinkClickedEventArgs e)\n        {\n            base.OnLinkClicked(e);\n            ExternalProgram.OpenWebUrl(e.LinkText);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/ResizeLimitedForm.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    /// <summary>限制水平、竖直方向调整大小的窗体</summary>\n    public class ResizeLimitedForm : Form\n    {\n        /// <summary>水平方向可调整大小</summary>\n        public bool HorizontalResizable { get; set; } = true;\n\n        /// <summary>竖直方向可调整大小</summary>\n        public bool VerticalResizable { get; set; } = true;\n\n        protected override void WndProc(ref Message m)\n        {\n            base.WndProc(ref m);\n            if(m.Msg == WM_NCHITTEST && this.WindowState == FormWindowState.Normal)\n            {\n                IntPtr hNowhere = new IntPtr((int)HitTest.Nowhere);\n                switch((HitTest)m.Result)\n                {\n                    case HitTest.Top:\n                    case HitTest.Bottom:\n                        if(!VerticalResizable) m.Result = hNowhere;\n                        break;\n                    case HitTest.Left:\n                    case HitTest.Right:\n                        if(!HorizontalResizable) m.Result = hNowhere;\n                        break;\n                    case HitTest.TopLeft:\n                    case HitTest.TopRight:\n                    case HitTest.BottomLeft:\n                    case HitTest.BottomRight:\n                        if(!VerticalResizable || !HorizontalResizable) m.Result = hNowhere;\n                        break;\n                }\n            }\n        }\n\n        const int WM_NCHITTEST = 0x84;//光标移动或鼠标按下、释放时的消息\n        /// <summary>鼠标击中位置</summary>\n        enum HitTest : int\n        {\n            Error = -2,\n            Transparent = -1,\n            Nowhere = 0,\n            Client = 1,\n            TitleBar = 2,\n            SysMenu = 3,\n            Size = 4,\n            GrowBox = 5,\n            Hscroll = 6,\n            Vscroll = 7,\n            MinButton = 8,\n            MaxButton = 9,\n            Left = 10,\n            Right = 11,\n            Top = 12,\n            TopLeft = 13,\n            TopRight = 14,\n            Bottom = 15,\n            BottomLeft = 16,\n            BottomRight = 17,\n            Border = 18,\n            Close = 20,\n            Help = 21\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/SelectDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Controls\n{\n    public class SelectDialog : CommonDialog\n    {\n        public string Title { get; set; }\n        public string Selected { get; set; }\n        public int SelectedIndex { get; set; }\n        public string[] Items { get; set; }\n        public bool CanEdit { get; set; }\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(SelectForm frm = new SelectForm())\n            {\n                frm.Text = this.Title;\n                frm.Items = this.Items;\n                if(this.Selected != null) frm.Selected = this.Selected;\n                else frm.SelectedIndex = this.SelectedIndex;\n                frm.CanEdit = this.CanEdit;\n                Form owner = (Form)Control.FromHandle(hwndOwner);\n                if(owner != null) frm.TopMost = owner.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag)\n                {\n                    this.Selected = frm.Selected;\n                    this.SelectedIndex = frm.SelectedIndex;\n                }\n                return flag;\n            }\n        }\n\n        sealed class SelectForm : Form\n        {\n            public SelectForm()\n            {\n                this.SuspendLayout();\n                this.AcceptButton = btnOK;\n                this.CancelButton = btnCancel;\n                this.Font = SystemFonts.MenuFont;\n                this.ShowIcon = this.ShowInTaskbar = false;\n                this.MaximizeBox = this.MinimizeBox = false;\n                this.FormBorderStyle = FormBorderStyle.FixedSingle;\n                this.StartPosition = FormStartPosition.CenterParent;\n                this.InitializeComponents();\n                this.ResumeLayout();\n            }\n\n            public string Selected\n            {\n                get => cmbItems.Text;\n                set => cmbItems.Text = value;\n            }\n\n            public string[] Items\n            {\n                get\n                {\n                    string[] value = new string[cmbItems.Items.Count];\n                    cmbItems.Items.CopyTo(value, 0);\n                    return value;\n                }\n                set\n                {\n                    cmbItems.Items.Clear();\n                    cmbItems.Items.AddRange(value);\n                }\n            }\n\n            public bool CanEdit\n            {\n                get => cmbItems.DropDownStyle == ComboBoxStyle.DropDown;\n                set => cmbItems.DropDownStyle = value ? ComboBoxStyle.DropDown : ComboBoxStyle.DropDownList;\n            }\n\n            public int SelectedIndex\n            {\n                get => cmbItems.SelectedIndex;\n                set => cmbItems.SelectedIndex = value;\n            }\n\n            readonly Button btnOK = new Button\n            {\n                DialogResult = DialogResult.OK,\n                Text = ResourceString.OK,\n                AutoSize = true\n            };\n            readonly Button btnCancel = new Button\n            {\n                DialogResult = DialogResult.Cancel,\n                Text = ResourceString.Cancel,\n                AutoSize = true\n            };\n            readonly ComboBox cmbItems = new ComboBox\n            {\n                AutoCompleteMode = AutoCompleteMode.SuggestAppend,\n                AutoCompleteSource = AutoCompleteSource.ListItems,\n                DropDownHeight = 294.DpiZoom(),\n                ImeMode = ImeMode.Disable\n            };\n\n            private void InitializeComponents()\n            {\n                this.Controls.AddRange(new Control[] { cmbItems, btnOK, btnCancel });\n                int a = 20.DpiZoom();\n                cmbItems.Left = a;\n                cmbItems.Width = 85.DpiZoom();\n                cmbItems.Top = btnOK.Top = btnCancel.Top = a;\n                btnOK.Left = cmbItems.Right + a;\n                btnCancel.Left = btnOK.Right + a;\n                this.ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);\n                cmbItems.AutosizeDropDownWidth();\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Controls/UAWebClient.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Net;\nusing System.Runtime.Serialization.Json;\nusing System.Text;\nusing System.Xml;\n\nnamespace BluePointLilac.Controls\n{\n    public sealed class UAWebClient : WebClient\n    {\n        public UAWebClient()\n        {\n            //此类主要为了解决访问Github的一些问题\n            //请求被中止: 未能创建 SSL/TLS 安全通道; 基础连接已经关闭: 发送时发生错误，一般添加TLS12即可\n            //TLS12------0xc00，TLS11------0x300，TLS------0xc0，SSL------0x30;\n            ServicePointManager.SecurityProtocol = (SecurityProtocolType)(0xc00 | 0x300 | 0xc0 | 0x30);\n            //网络传输默认文本编码 UTF-8\n            this.Encoding = Encoding.UTF8;\n            //远程服务器返回错误: (403) 已禁止\n            //浏览器 F12 console 输入 console.log(navigator.userAgent); 获取 User Agent\n            this.Headers.Add(\"User-Agent\",\n                \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) \" +\n                \"Chrome/90.0.4430.212 Safari/537.36 Edg/90.0.818.66\");\n        }\n\n        /// <summary>获取网页文本</summary>\n        public string GetWebString(string url)\n        {\n            try\n            {\n                string str = this.DownloadString(url);\n                str = str?.Replace(\"\\n\", Environment.NewLine);//换行符转换\n                return str;\n            }\n            catch { return null; }\n        }\n\n        /// <summary>将网络文本写入本地文件</summary>\n        /// <param name=\"filePath\">本地文件路径</param>\n        /// <param name=\"fileUrl\">网络文件Raw路径</param>\n        public bool WebStringToFile(string filePath, string fileUrl)\n        {\n            string contents = GetWebString(fileUrl);\n            bool flag = contents != null;\n            if(flag) File.WriteAllText(filePath, contents, Encoding.Unicode);\n            return flag;\n        }\n\n        /// <summary>获取网页Json文本并加工为Xml</summary>\n        public XmlDocument GetWebJsonToXml(string url)\n        {\n            try\n            {\n                byte[] bytes = this.DownloadData(url);\n                using(XmlReader xReader = JsonReaderWriterFactory.CreateJsonReader(bytes, XmlDictionaryReaderQuotas.Max))\n                {\n                    XmlDocument doc = new XmlDocument();\n                    doc.Load(xReader);\n                    return doc;\n                }\n            }\n            catch { return null; }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ComboBoxExtension\n    {\n        public static void AutosizeDropDownWidth(this ComboBox box)\n        {\n            box.DropDown += (sender, e) =>\n            {\n                int maxWidth = 0;\n                foreach(var item in box.Items)\n                {\n                    maxWidth = Math.Max(maxWidth, TextRenderer.MeasureText(item.ToString(), box.Font).Width);\n                }\n                maxWidth = Math.Max(maxWidth, box.Width);\n                box.DropDownWidth = maxWidth;\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ControlExtension.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ControlExtension\n    {\n        [DllImport(\"user32.dll\")]\n        private static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);\n\n        [DllImport(\"user32.dll\")]\n        private static extern bool ReleaseCapture();\n\n        /// <summary>使控件能够移动所属窗体</summary>\n        /// <param name=\"ctr\">目标控件</param>\n        public static void CanMoveForm(this Control ctr)\n        {\n            const int WM_NCLBUTTONDOWN = 0xA1;\n            const int HT_CAPTION = 0x2;\n            ctr.MouseMove += (sender, e) =>\n            {\n                if(e.Button != MouseButtons.Left) return;\n                ReleaseCapture();\n                PostMessage(ctr.FindForm().Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);\n            };\n        }\n\n        [DllImport(\"user32.dll\")]\n        private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int wndproc);\n\n        [DllImport(\"user32.dll\")]\n        private static extern int GetWindowLong(IntPtr hWnd, int nIndex);\n\n        /// <summary>通过Win32API禁用/启用目标控件</summary>\n        /// <remarks>控件被禁用时仍可更改字体颜色，不需要同时设置ctr.Enabled=false</remarks>\n        /// <param name=\"ctr\">目标控件</param>\n        /// <param name=\"enabled\">启用为true，禁用为false</param>\n        public static void SetEnabled(this Control ctr, bool enabled)\n        {\n            const int GWL_STYLE = -16;\n            const int WS_DISABLED = 0x8000000;\n            int value = GetWindowLong(ctr.Handle, GWL_STYLE);\n            if(enabled) value &= ~WS_DISABLED;\n            else value |= WS_DISABLED;\n            SetWindowLong(ctr.Handle, GWL_STYLE, value);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/DirectoryEx.cs",
    "content": "﻿using System.IO;\n\nnamespace BluePointLilac.Methods\n{\n    public static class DirectoryEx\n    {\n        public static void CopyTo(string srcDirPath, string dstDirPath)\n        {\n            DirectoryInfo srcDi = new DirectoryInfo(srcDirPath);\n            DirectoryInfo dstDi = new DirectoryInfo(dstDirPath);\n            dstDi.Create();\n            foreach(FileInfo srcFi in srcDi.GetFiles())\n            {\n                string dstFilePath = $@\"{dstDirPath}\\{srcFi.Name}\";\n                srcFi.CopyTo(dstFilePath, true);\n            }\n            foreach(DirectoryInfo srcSubDi in srcDi.GetDirectories())\n            {\n                DirectoryInfo dstSubDi = dstDi.CreateSubdirectory(srcSubDi.Name);\n                CopyTo(srcSubDi.FullName, dstSubDi.FullName);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs",
    "content": "﻿using System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    /// 代码用途：管理员UAC进程窗口拖放文件\n    /// 代码来源1：https://zhuanlan.zhihu.com/p/48735364\n    /// 代码来源2：https://github.com/volschin/sdimager/blob/master/ElevatedDragDropManager.cs\n    /// 代码作者：雨少主（知乎）、volschin（Github）、蓝点lilac（转载、修改）\n    /// 调用方法：var droper = new ElevatedFileDroper(control);\n    /// droper.DragDrop += (sender, e) => MessageBox.Show(droper.DropFilePaths[0]);\n    /// 备注：此类只能生效一个实例，不能将control.AllowDrop设为true，droper.DragDrop与control.DragDrop不共存\n\n    public sealed class ElevatedFileDroper : IMessageFilter\n    {\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint message, ChangeFilterAction action, in ChangeFilterStruct pChangeFilterStruct);\n\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        private static extern bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags);\n\n        [DllImport(\"shell32.dll\", SetLastError = false)]\n        private static extern void DragAcceptFiles(IntPtr hWnd, bool fAccept);\n\n        [DllImport(\"shell32.dll\", SetLastError = false, CharSet = CharSet.Unicode)]\n        private static extern uint DragQueryFile(IntPtr hWnd, uint iFile, StringBuilder lpszFile, int cch);\n\n        [DllImport(\"shell32.dll\", SetLastError = false)]\n        private static extern bool DragQueryPoint(IntPtr hDrop, out Point lppt);\n\n        [DllImport(\"shell32.dll\", SetLastError = false)]\n        private static extern void DragFinish(IntPtr hDrop);\n\n        [StructLayout(LayoutKind.Sequential)]\n        struct ChangeFilterStruct\n        {\n            public uint CbSize;\n            public ChangeFilterStatu ExtStatus;\n        }\n\n        enum ChangeWindowMessageFilterFlags : uint\n        {\n            MSGFLT_ADD = 1,\n            MSGFLT_REMOVE = 2\n        }\n\n        enum ChangeFilterAction : uint\n        {\n            MSGFLT_RESET,\n            MSGFLT_ALLOW,\n            MSGFLT_DISALLOW\n        }\n\n        enum ChangeFilterStatu : uint\n        {\n            MSGFLTINFO_NONE,\n            MSGFLTINFO_ALREADYALLOWED_FORWND,\n            MSGFLTINFO_ALREADYDISALLOWED_FORWND,\n            MSGFLTINFO_ALLOWED_HIGHER\n        }\n\n        const uint WM_COPYGLOBALDATA = 0x0049;\n        const uint WM_COPYDATA = 0x004A;\n        const uint WM_DROPFILES = 0x0233;\n\n        public event EventHandler DragDrop;\n        public string[] DropFilePaths { get; private set; }\n        public Point DropPoint { get; private set; }\n\n        public ElevatedFileDroper(Control ctr)\n        {\n            ctr.AllowDrop = false;\n            DragAcceptFiles(ctr.Handle, true);\n            Application.AddMessageFilter(this);\n            ctr.Disposed += (sender, e) => Application.RemoveMessageFilter(this);\n\n            if(ctr is Form frm)\n            {\n                double opacity = frm.Opacity;\n                frm.Paint += (sender, e) =>\n                {\n                    if(frm.Opacity != opacity)\n                    {\n                        //窗体透明度变化时需要重新注册接受文件拖拽标识符\n                        DragAcceptFiles(ctr.Handle, true);\n                        opacity = frm.Opacity;\n                    }\n                };\n            }\n\n            Version ver = Environment.OSVersion.Version;\n            bool isVistaOrHigher = ver >= new Version(6, 0);\n            bool isWin7OrHigher = ver >= new Version(6, 1);\n            var status = new ChangeFilterStruct { CbSize = 8 };\n            if(isVistaOrHigher)\n            {\n                foreach(uint msg in new[] { WM_DROPFILES, WM_COPYGLOBALDATA, WM_COPYDATA })\n                {\n                    bool error = false;\n                    if(isWin7OrHigher)\n                    {\n                        error = !ChangeWindowMessageFilterEx(ctr.Handle, msg, ChangeFilterAction.MSGFLT_ALLOW, in status);\n                    }\n                    else\n                    {\n                        error = !ChangeWindowMessageFilter(msg, ChangeWindowMessageFilterFlags.MSGFLT_ADD);\n                    }\n                    if(error) throw new Win32Exception(Marshal.GetLastWin32Error());\n                }\n            }\n        }\n\n        public bool PreFilterMessage(ref Message m)\n        {\n            if(m.Msg != WM_DROPFILES) return false;\n            IntPtr handle = m.WParam;\n            uint fileCount = DragQueryFile(handle, uint.MaxValue, null, 0);\n            string[] filePaths = new string[fileCount];\n            for(uint i = 0; i < fileCount; i++)\n            {\n                StringBuilder sb = new StringBuilder(260);\n                uint result = DragQueryFile(handle, i, sb, sb.Capacity);\n                if(result > 0) filePaths[i] = sb.ToString();\n            }\n            DragQueryPoint(handle, out Point point);\n            DragFinish(handle);\n            DropPoint = point;\n            DropFilePaths = filePaths;\n            DragDrop?.Invoke(this, null);\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/EncodingType.cs",
    "content": "﻿using System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{\n    /* 获取文本文件编码类型\n     * 代码参考：https://www.cnblogs.com/guyun/p/4262587.html (Napoléon)*/\n    public static class EncodingType\n    {\n        /// <summary>各种带BOM的编码BOM值</summary>\n        private static readonly Dictionary<byte[], Encoding> EncodingBomBytes = new Dictionary<byte[], Encoding>\n        {\n            { new byte[] { 0xEF, 0xBB, 0xBF }, Encoding.UTF8 },                         //UTF-8         EF BB BF\n            { new byte[] { 0xFF, 0xFE, 0x00, 0x00 }, Encoding.UTF32 },                  //UTF-32LE      FF FE 00 00\n            { new byte[] { 0xFF, 0xFE }, Encoding.Unicode },                            //UTF-16LE      FF FE\n            { new byte[] { 0xFE, 0xFF }, Encoding.BigEndianUnicode },                   //UTF-16BE      FE FF\n            { new byte[] { 0x2B, 0x2F, 0x76 }, Encoding.UTF7 },                         //UTF-7         2B 2F 76\n            { new byte[] { 0x00, 0x00, 0xFE, 0xFF }, new UTF32Encoding(true, true) },   //UTF-32BE      00 00 FE FF\n        };\n\n        /// <summary>获取给定的文件的编码类型</summary> \n        /// <param name=“filePath“>文件路径</param> \n        /// <returns>文件的编码类型</returns> \n        public static Encoding GetType(string filePath)\n        {\n            byte[] fs = File.ReadAllBytes(filePath);\n            foreach(var kv in EncodingBomBytes)\n            {\n                if(fs.Length < kv.Key.Length) continue;\n                int i = -1;\n                bool flag = kv.Key.All(s => { i++; return s == fs[i]; });\n                if(flag) return kv.Value;\n            }\n            if(IsUTF8Bytes(fs)) return Encoding.UTF8; //不带BOM的UTF-8\n            return Encoding.Default;\n        }\n\n        /// <summary>判断是否是不带 BOM 的 UTF8 格式</summary> \n        /// <param name=“bytes“></param> \n        private static bool IsUTF8Bytes(byte[] bytes)\n        {\n            int count = 1; //计算当前正分析的字符应还有的字节数 \n            for(int i = 0; i < bytes.Length; i++)\n            {\n                byte curByte = bytes[i];//当前分析的字节. \n                if(count == 1)\n                {\n                    if(curByte >= 0x80)\n                    {\n                        //判断当前 \n                        while(((curByte <<= 1) & 0x80) != 0) count++;\n                        //标记位首位若为非0 则至少以2个1开始 如:110XXXXX...........1111110X \n                        if(count == 1 || count > 6) return false;\n                    }\n                }\n                else\n                {\n                    //若是UTF-8 此时第一位必须为1 \n                    if((curByte & 0xC0) != 0x80) return false;\n                    else count--;\n                }\n            }\n            //if(count > 1) throw new Exception(\"非预期的byte格式\");\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs",
    "content": "﻿using Microsoft.Win32;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading;\n\nnamespace BluePointLilac.Methods\n{\n    /// <summary>外部程序</summary>\n    public static class ExternalProgram\n    {\n        /// <summary>在Regedit中跳转指定路径并定位指定键名</summary>\n        /// <param name=\"regPath\">注册表项路径</param>\n        /// <param name=\"valueName\">注册表键名</param>\n        /// <param name=\"moreOpen\">窗口是否多开</param>\n        public static void JumpRegEdit(string regPath, string valueName = null, bool moreOpen = false)\n        {\n            //还有一种方法，修改HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\n            //中的LastKey键值（记录上次关闭注册表编辑器时的注册表路径）为要跳转的注册表项路径regPath，\n            //再使用Process.Start(\"regedit.exe\", \"-m\")打开注册表编辑器\n            //优点：代码少、不会有Bug。缺点：不能定位具体键，没有逐步展开效果\n            if(regPath == null) return;\n            Process process;\n            IntPtr hMain = FindWindow(\"RegEdit_RegEdit\", null);\n            if(hMain != IntPtr.Zero && !moreOpen)\n            {\n                GetWindowThreadProcessId(hMain, out int id);\n                process = Process.GetProcessById(id);\n            }\n            else\n            {\n                //注册表编辑器窗口多开\n                process = Process.Start(\"regedit.exe\", \"-m\");\n                process.WaitForInputIdle();\n                hMain = process.MainWindowHandle;\n            }\n\n            ShowWindowAsync(hMain, SW_SHOWNORMAL);\n            SetForegroundWindow(hMain);\n            IntPtr hTree = FindWindowEx(hMain, IntPtr.Zero, \"SysTreeView32\", null);\n            IntPtr hList = FindWindowEx(hMain, IntPtr.Zero, \"SysListView32\", null);\n\n            SetForegroundWindow(hTree);\n            SetFocus(hTree);\n            process.WaitForInputIdle();\n            SendMessage(hTree, WM_KEYDOWN, VK_HOME, null);\n            Thread.Sleep(100);\n            process.WaitForInputIdle();\n            SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);\n            foreach(char chr in Encoding.Default.GetBytes(regPath))\n            {\n                process.WaitForInputIdle();\n                if(chr == '\\\\')\n                {\n                    Thread.Sleep(100);\n                    SendMessage(hTree, WM_KEYDOWN, VK_RIGHT, null);\n                }\n                else\n                {\n                    SendMessage(hTree, WM_CHAR, Convert.ToInt16(chr), null);\n                }\n            }\n\n            if(string.IsNullOrEmpty(valueName)) return;\n            using(RegistryKey key = RegistryEx.GetRegistryKey(regPath))\n            {\n                if(key?.GetValue(valueName) == null) return;\n            }\n            Thread.Sleep(100);\n            SetForegroundWindow(hList);\n            SetFocus(hList);\n            process.WaitForInputIdle();\n            SendMessage(hList, WM_KEYDOWN, VK_HOME, null);\n            foreach(char chr in Encoding.Default.GetBytes(valueName))\n            {\n                process.WaitForInputIdle();\n                SendMessage(hList, WM_CHAR, Convert.ToInt16(chr), null);\n            }\n            process.Dispose();\n        }\n\n        /// <summary>在Explorer中选中指定文件或文件夹</summary>\n        /// <param name=\"filePath\">文件或文件夹路径</param>\n        /// <param name=\"moreOpen\">窗口是否多开</param>\n        public static void JumpExplorer(string filePath, bool moreOpen = false)\n        {\n            if(filePath == null) return;\n            if(!moreOpen)\n            {\n                IntPtr pidlList = ILCreateFromPathW(filePath);\n                if(pidlList == IntPtr.Zero) return;\n                SHOpenFolderAndSelectItems(pidlList, 0, IntPtr.Zero, 0);\n                ILFree(pidlList);\n            }\n            else\n            {\n                using(Process process = new Process())\n                {\n                    process.StartInfo.FileName = \"explorer.exe\";\n                    process.StartInfo.Arguments = $\"/select, {filePath}\";\n                    process.Start();\n                }\n            }\n        }\n\n        /// <summary>在Explorer中打开指定目录</summary>\n        /// <param name=\"dirPath\">目录路径</param>\n        public static void OpenDirectory(string dirPath)\n        {\n            if(!Directory.Exists(dirPath)) return;\n            using(Process process = new Process())\n            {\n                process.StartInfo.FileName = dirPath;\n                process.Start();\n            }\n        }\n\n        /// <summary>打开文件或文件夹的属性对话框</summary>\n        /// <param name=\"filePath\">文件或文件夹路径</param>\n        public static bool ShowPropertiesDialog(string filePath)\n        {\n            SHELLEXECUTEINFO info = new SHELLEXECUTEINFO\n            {\n                lpVerb = \"Properties\",\n                //显示详细信息选项卡, 此处有语言差异\n                //lpParameters = ResourceString.GetDirectString(\"@shell32.dll,-31433\"),//\"详细信息\",\n                lpFile = filePath,\n                nShow = SW_SHOW,\n                fMask = SEE_MASK_INVOKEIDLIST,\n                cbSize = Marshal.SizeOf(typeof(SHELLEXECUTEINFO))\n            };\n            return ShellExecuteEx(ref info);\n        }\n\n        /// <summary>打开指定未关联打开方式的扩展名的打开方式对话框</summary>\n        /// <param name=\"extension\">文件扩展名</param>\n        public static void ShowOpenWithDialog(string extension)\n        {\n            //Win10 调用 SHOpenWithDialog API 或调用 OpenWith.exe -override \"%1\"\n            //或调用 rundll32.exe shell32.dll,OpenAs_RunDLL %1 能显示打开方式对话框，但都不能设置默认应用\n            //以下方法只针对未关联打开方式的扩展名显示系统打开方式对话框，对于已关联打开方式的扩展名会报错\n            string tempPath = $\"{Path.GetTempPath()}{Guid.NewGuid()}{extension}\";\n            File.WriteAllText(tempPath, \"\");\n            using(Process process = new Process())\n            {\n                process.StartInfo = new ProcessStartInfo\n                {\n                    UseShellExecute = true,\n                    FileName = tempPath,\n                    Verb = \"openas\"\n                };\n                process.Start();\n            }\n            File.Delete(tempPath);\n        }\n\n        /// <summary>重启Explorer</summary>\n        public static void RestartExplorer()\n        {\n            using(Process process = new Process())\n            {\n                //有些系统有tskill.exe可以直接调用tskill explorer命令\n                process.StartInfo = new ProcessStartInfo\n                {\n                    FileName = \"taskkill.exe\",\n                    Arguments = \"-f -im explorer.exe\",\n                    WindowStyle = ProcessWindowStyle.Hidden\n                };\n                process.Start();\n                process.WaitForExit();\n                process.StartInfo = new ProcessStartInfo(\"explorer.exe\");\n                process.Start();\n            }\n        }\n\n        /// <summary>调用默认浏览器打开指定网址</summary>\n        /// <param name=\"url\">网址</param>\n        public static void OpenWebUrl(string url)\n        {\n            if(url == null) return;\n            //替换网址转义符\n            url = url.Replace(\"%\", \"%25\").Replace(\"#\", \"%23\").Replace(\"&\", \"%26\").Replace(\"+\", \"%2B\");\n            using(Process process = new Process())\n            {\n                //通过explorer来调用默认浏览器打开链接，避免管理员权限影响\n                process.StartInfo = new ProcessStartInfo($\"\\\"{url}\\\"\");\n                process.Start();\n            }\n        }\n\n        /// <summary>导出指定注册表项的.reg文件</summary>\n        /// <param name=\"regPath\">注册表项路径</param>\n        /// <param name=\"filePath\">.reg文件保存路径</param>\n        public static void ExportRegistry(string regPath, string filePath)\n        {\n            using(Process process = new Process())\n            {\n                process.StartInfo.FileName = \"regedit.exe\";\n                process.StartInfo.Arguments = $\"/e \\\"{filePath}\\\" \\\"{regPath}\\\"\";\n                process.Start();\n                process.WaitForExit();\n            }\n        }\n\n        /// <summary>打开记事本显示指定文本</summary>\n        /// <param name=\"text\">要显示的文本</param>\n        public static void OpenNotepadWithText(string text)\n        {\n            using(Process process = Process.Start(\"notepad.exe\"))\n            {\n                process.WaitForInputIdle();\n                IntPtr handle = FindWindowEx(process.MainWindowHandle, IntPtr.Zero, \"Edit\", null);\n                SendMessage(handle, WM_SETTEXT, 0, text);\n            }\n        }\n\n        private const int SW_SHOWNORMAL = 1;\n        private const int SW_SHOW = 5;\n        private const uint SEE_MASK_INVOKEIDLIST = 12;\n        private const int WM_SETTEXT = 0xC;\n        private const int WM_KEYDOWN = 0x100;\n        private const int WM_CHAR = 0x102;\n        private const int VK_HOME = 0x24;\n        private const int VK_RIGHT = 0x27;\n\n        [DllImport(\"user32.dll\")]\n        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);\n\n        [DllImport(\"user32.dll\")]\n        private static extern bool SetForegroundWindow(IntPtr hWnd);\n\n        [DllImport(\"user32.dll\")]\n        private static extern bool SetFocus(IntPtr hWnd);\n\n        [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]\n        private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);\n\n        [DllImport(\"user32.dll\")]\n        private static extern IntPtr FindWindow(string lpszClass, string lpszWindow);\n\n        [DllImport(\"user32.dll\")]\n        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChild, string lpszClass, string lpszWindow);\n\n        [DllImport(\"user32.dll\")]\n        private static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);\n\n        [DllImport(\"shell32.dll\", ExactSpelling = true)]\n        private static extern void ILFree(IntPtr pidlList);\n\n        [DllImport(\"shell32.dll\", CharSet = CharSet.Unicode, ExactSpelling = true)]\n        private static extern IntPtr ILCreateFromPathW(string pszPath);\n\n        [DllImport(\"shell32.dll\", ExactSpelling = true)]\n        private static extern IntPtr SHOpenFolderAndSelectItems(IntPtr pidlList, uint cild, IntPtr children, uint dwFlags);\n\n        [DllImport(\"shell32.dll\", CharSet = CharSet.Auto)]\n        private static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);\n\n        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\n        private struct SHELLEXECUTEINFO\n        {\n            public int cbSize;\n            public uint fMask;\n            public IntPtr hwnd;\n            [MarshalAs(UnmanagedType.LPTStr)]\n            public string lpVerb;\n            [MarshalAs(UnmanagedType.LPTStr)]\n            public string lpFile;\n            [MarshalAs(UnmanagedType.LPTStr)]\n            public string lpParameters;\n            [MarshalAs(UnmanagedType.LPTStr)]\n            public string lpDirectory;\n            public int nShow;\n            public IntPtr hInstApp;\n            public IntPtr lpIDList;\n            [MarshalAs(UnmanagedType.LPTStr)]\n            public string lpClass;\n            public IntPtr hkeyClass;\n            public uint dwHotKey;\n            public IntPtr hIcon;\n            public IntPtr hProcess;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/FileExtension.cs",
    "content": "﻿using Microsoft.Win32;\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{\n    public static class FileExtension\n    {\n        [Flags]\n        enum AssocF\n        {\n            Init_NoRemapCLSID = 0x1,\n            Init_ByExeName = 0x2,\n            Open_ByExeName = 0x2,\n            Init_DefaultToStar = 0x4,\n            Init_DefaultToFolder = 0x8,\n            NoUserSettings = 0x10,\n            NoTruncate = 0x20,\n            Verify = 0x40,\n            RemapRunDll = 0x80,\n            NoFixUps = 0x100,\n            IgnoreBaseClass = 0x200\n        }\n\n        public enum AssocStr\n        {\n            Command = 1,\n            Executable,\n            FriendlyDocName,\n            FriendlyAppName,\n            NoOpen,\n            ShellNewValue,\n            DDECommand,\n            DDEIfExec,\n            DDEApplication,\n            DDETopic\n        }\n\n        [DllImport(\"shlwapi.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n        private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref uint pcchOut);\n\n        public const string FILEEXTSPATH = @\"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\";\n        private const string HKCRCLASSES = @\"HKEY_CURRENT_USER\\SOFTWARE\\Classes\";\n        private const string HKLMCLASSES = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\";\n\n        public static string GetExtentionInfo(AssocStr assocStr, string extension)\n        {\n            uint pcchOut = 0;\n            AssocQueryString(AssocF.Verify, assocStr, extension, null, null, ref pcchOut);\n            StringBuilder pszOut = new StringBuilder((int)pcchOut);\n            AssocQueryString(AssocF.Verify, assocStr, extension, null, pszOut, ref pcchOut);\n            return pszOut.ToString();\n        }\n\n        public static string GetOpenMode(string extension)\n        {\n            if(string.IsNullOrEmpty(extension)) return null;\n            string mode;\n            bool CheckMode()\n            {\n                if(mode.IsNullOrWhiteSpace()) return false;\n                if(mode.Length > 255) return false;\n                if(mode.ToLower().StartsWith(@\"applications\\\")) return false;\n                using(RegistryKey root = Registry.ClassesRoot)\n                using(RegistryKey key = root.OpenSubKey(mode))\n                {\n                    return key != null;\n                }\n            }\n            mode = Registry.GetValue($@\"{FILEEXTSPATH}\\{extension}\\UserChoice\", \"ProgId\", null)?.ToString();\n            if(CheckMode()) return mode;\n            mode = Registry.GetValue($@\"{HKLMCLASSES}\\{extension}\", \"\", null)?.ToString();\n            if(CheckMode()) return mode;\n            mode = Registry.GetValue($@\"{HKCRCLASSES}\\{extension}\", \"\", null)?.ToString();\n            if(CheckMode()) return mode;\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/FormExtension.cs",
    "content": "﻿using System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class FormExtension\n    {\n        /// <summary>移动窗体时同时移动另一个窗体</summary>\n        /// <param name=\"frm1\">主动移动的窗体</param>\n        /// <param name=\"frm2\">同时被移动的窗体</param>\n        public static void MoveAsMove(this Form frm1, Form frm2)\n        {\n            if(frm2 == null) return;\n            Point pLast = Point.Empty;\n            frm1.Load += (sender, e) => pLast = frm1.Location;\n            frm1.LocationChanged += (sender, e) =>\n            {\n                if(pLast == Point.Empty) return;\n                frm2.Left += frm1.Left - pLast.X;\n                frm2.Top += frm1.Top - pLast.Y;\n                pLast = frm1.Location;\n            };\n        }\n\n        /// <summary>给窗体添加ESC键关闭功能</summary>\n        /// <param name=\"frm\">指定窗口</param>\n        /// <param name=\"dr\">关闭窗口时的对话框返回值</param>\n        /// <remarks>也可以重写Form的ProcessDialogKey事件，\n        /// 这个方法更简单，但遍历窗体控件时切记多了一个不可见的关闭按钮</remarks>\n        public static void AddEscapeButton(this Form frm, DialogResult dr = DialogResult.Cancel)\n        {\n            Button btn = new Button\n            {\n                Parent = frm,\n                Size = Size.Empty,\n                DialogResult = dr\n            };\n            frm.CancelButton = btn;\n            frm.Disposed += (sender, e) => btn.Dispose();\n            frm.FormClosing += (sender, e) => btn.PerformClick();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/GuidEx.cs",
    "content": "﻿using System;\nusing System.Text.RegularExpressions;\n\nnamespace BluePointLilac.Methods\n{\n    //为兼容.Net Framework 3.5，无法引用Microsoft.CSharp.dll（中的Guid.TryParse）写了这个扩展方法\n    public static class GuidEx\n    {\n        public static bool TryParse(string str, out Guid guid)\n        {\n            if(IsGuid(str))\n            {\n                guid = new Guid(str);\n                return true;\n            }\n            else\n            {\n                guid = Guid.Empty;\n                return false;\n            }\n        }\n\n        private static readonly Regex GuidRegex = new Regex(@\"[A-F0-9]{8}(\\-[A-F0-9]{4}){3}\\-[A-F0-9]{12}\", RegexOptions.IgnoreCase);\n\n        public static bool IsGuid(string str)\n        {\n            if(string.IsNullOrEmpty(str)) return false;\n            if(str.Length == 38 && str.StartsWith(\"{\") && str.EndsWith(\"}\") && GuidRegex.IsMatch(str)) return true;\n            if(str.Length == 36 && GuidRegex.IsMatch(str)) return true;\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/HighDpi.cs",
    "content": "﻿using System.Drawing;\nusing System.Windows;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    /// <summary>处理不同DPI缩放比下的像素绘制和字体显示问题</summary>\n    /// <remarks>使用此类需要添加引用 PresentationFramework\n    /// 还应在配置清单App.manifest中启用DPI感知自动缩放\n    /// Font为矢量类型，Point、Size、Rectangle、Padding等为像素类型。\n    /// 在不同DPI缩放下，矢量类型等比缩放，像素类型保持不变，故会出现排版显示问题。\n    /// 解决方案一：项目中所有用到的像素类型实例值都取与缩放比之积，矢量类型不变。\n    /// 解决方案二：项目中所有用到的矢量类型实例都取与缩放比之商，像素类型不变</remarks>\n    public static class HighDpi\n    {\n        /// <summary>DPI缩放比</summary>\n        public static readonly double DpiScale = Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth;\n\n        public static Point DpiZoom(this Point point) => new Point(DpiZoom(point.X), DpiZoom(point.Y));\n\n        public static PointF DpiZoom(this PointF point) => new PointF(DpiZoom(point.X), DpiZoom(point.Y));\n\n        public static Size DpiZoom(this Size size) => new Size(DpiZoom(size.Width), DpiZoom(size.Height));\n\n        public static SizeF DpiZoom(this SizeF size) => new SizeF(DpiZoom(size.Width), DpiZoom(size.Height));\n\n        public static Rectangle DpiZoom(this Rectangle r) => new Rectangle(DpiZoom(r.Location), DpiZoom(r.Size));\n\n        public static RectangleF DpiZoom(this RectangleF r) => new RectangleF(DpiZoom(r.Location), DpiZoom(r.Size));\n\n        public static Padding DpiZoom(this Padding p) => new Padding(DpiZoom(p.Left), DpiZoom(p.Top), DpiZoom(p.Right), DpiZoom(p.Bottom));\n\n        public static Font DpiZoom(this Font font) => new Font(font.FontFamily, font.Size / DpiZoom(1F), font.Style);\n\n        public static int DpiZoom(this int num) => (int)(num * DpiScale);\n\n        public static float DpiZoom(this float num) => (float)(num * DpiScale);\n\n        public static double DpiZoom(this double num) => num * DpiScale;\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ImageExtension.cs",
    "content": "﻿using System.Drawing;\nusing System.Drawing.Drawing2D;\nusing System.Drawing.Imaging;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ImageExtension\n    {\n        public static Image ToTransparent(this Image image, float opacity = 0.5F)\n        {\n            Bitmap bitmap = new Bitmap(image.Width, image.Height);\n            using(Graphics g = Graphics.FromImage(bitmap))\n            using(ImageAttributes attributes = new ImageAttributes())\n            {\n                ColorMatrix matrix = new ColorMatrix { Matrix33 = opacity };\n                attributes.SetColorMatrix(matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);\n                g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height),\n                    0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);\n            }\n            return bitmap;\n        }\n\n        public static Image ResizeImage(this Image image, int width, int height)\n        {\n            //return image.GetThumbnailImage(width, height, null, System.IntPtr.Zero);//质量稍微低一点\n            if(image.Width == width && image.Height == height) return image;\n            Bitmap destImage = new Bitmap(width, height);\n            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);\n            using(Graphics g = Graphics.FromImage(destImage))\n            {\n                g.CompositingMode = CompositingMode.SourceCopy;\n                g.InterpolationMode = InterpolationMode.HighQualityBicubic;\n                g.CompositingQuality = CompositingQuality.HighQuality;\n                g.PixelOffsetMode = PixelOffsetMode.HighQuality;\n                g.SmoothingMode = SmoothingMode.HighQuality;\n\n                using(ImageAttributes attributes = new ImageAttributes())\n                {\n                    attributes.SetWrapMode(WrapMode.TileFlipXY);\n                    g.DrawImage(image, new Rectangle(0, 0, width, height),\n                        0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);\n                }\n            }\n            return destImage;\n        }\n\n        public static Image ResizeImage(this Image image, double scale)\n        {\n            if(scale == 1) return image;\n            int width = (int)(image.Width * scale);\n            int height = (int)(image.Height * scale);\n            return image.ResizeImage(width, height);\n        }\n\n        public static Image ResizeImage(this Image image, Size newSize)\n        {\n            if(newSize == image.Size) return image;\n            return image.ResizeImage(newSize.Width, newSize.Height);\n        }\n\n        public static Image RotateImage(this Image image, RotateFlipType rotateType)\n        {\n            Bitmap bitmap = new Bitmap(image);\n            bitmap.RotateFlip(rotateType);\n            return bitmap;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/IniReader.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{\n    public sealed class IniReader\n    {\n        public IniReader() { }\n\n        public IniReader(StringBuilder sb) => LoadStringBuilder(sb);\n\n        public IniReader(string filePath) => LoadFile(filePath);\n\n        private readonly Dictionary<string, Dictionary<string, string>> RootDic\n            = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);\n\n        public string[] Sections => RootDic.Keys.ToArray();\n\n        public void LoadStringBuilder(StringBuilder sb)\n        {\n            RootDic.Clear();\n            if(sb.ToString().IsNullOrWhiteSpace()) return;\n            List<string> lines = sb.ToString().Split(new[] { \"\\r\\n\", \"\\n\" },\n                StringSplitOptions.RemoveEmptyEntries).ToList();//拆分为行\n            lines.ForEach(line => line.Trim());\n            ReadLines(lines);\n        }\n\n        public void LoadFile(string filePath)\n        {\n            RootDic.Clear();\n            if(!File.Exists(filePath)) return;\n            List<string> lines = new List<string>();\n            using(StreamReader reader = new StreamReader(filePath, EncodingType.GetType(filePath)))\n            {\n                while(!reader.EndOfStream)\n                {\n                    string line = reader.ReadLine().Trim();\n                    if(line != string.Empty) lines.Add(line);\n                }\n            }\n            ReadLines(lines);\n        }\n\n        private void ReadLines(List<string> lines)\n        {\n            lines.RemoveAll(\n                line => line.StartsWith(\";\") || line.StartsWith(\"#\")//移除注释\n                || (!line.StartsWith(\"[\") && !line.Contains(\"=\")));//移除非section行且非key行\n\n            if(lines.Count == 0) return;\n\n            List<int> indexs = new List<int> { 0 };\n            for(int i = 1; i < lines.Count; i++)\n            {\n                if(lines[i].StartsWith(\"[\")) indexs.Add(i);//获取section行号\n            }\n            indexs.Add(lines.Count);\n\n            for(int i = 0; i < indexs.Count - 1; i++)\n            {\n                string section = lines[indexs[i]];\n                int m = section.IndexOf(']') - 1;\n                if(m < 0) continue;\n                section = section.Substring(1, m);\n                if(RootDic.ContainsKey(section)) continue;\n                var keyValues = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n                RootDic.Add(section, keyValues);\n\n                for(int j = indexs[i] + 1; j < indexs[i + 1]; j++)\n                {\n                    int k = lines[j].IndexOf('=');\n                    string key = lines[j].Substring(0, k).TrimEnd();\n                    string value = lines[j].Substring(k + 1).TrimStart();\n                    if(keyValues.ContainsKey(key)) continue;\n                    keyValues.Add(key, value);\n                }\n            }\n        }\n\n        public string GetValue(string section, string key)\n        {\n            if(RootDic.TryGetValue(section, out Dictionary<string, string> sectionDic))\n                if(sectionDic.TryGetValue(key, out string value))\n                    return value;\n            return string.Empty;\n        }\n\n        public bool TryGetValue(string section, string key, out string value)\n        {\n            value = GetValue(section, key);\n            return value != string.Empty;\n        }\n\n        public string[] GetSectionKeys(string section)\n        {\n            if(!RootDic.ContainsKey(section)) return null;\n            else return RootDic[section].Keys.ToArray();\n        }\n\n        public bool RemoveSection(string section)\n        {\n            return RootDic.Remove(section);\n        }\n\n        public bool RemoveKey(string section, string key)\n        {\n            if(RootDic.ContainsKey(section))\n            {\n                return RootDic[section].Remove(key);\n            }\n            return false;\n        }\n\n        public void AddValue(string section, string key, string value)\n        {\n            if(RootDic.ContainsKey(section))\n            {\n                if(RootDic[section].ContainsKey(key))\n                {\n                    RootDic[section][key] = value;\n                }\n                else\n                {\n                    RootDic[section].Add(key, value);\n                }\n            }\n            else\n            {\n                var dic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n                RootDic.Add(section, dic);\n                dic.Add(key, value);\n            }\n        }\n\n        public void SaveFile(string filePath)\n        {\n            List<string> lines = new List<string>();\n            foreach(var item in RootDic)\n            {\n                lines.Add(\"[\" + item.Key + \"]\");\n                foreach(var key in item.Value)\n                {\n                    lines.Add(key.Key + \" = \" + key.Value);\n                }\n                lines.Add(\"\");\n            }\n            Directory.CreateDirectory(Path.GetDirectoryName(filePath));\n            FileAttributes attributes = FileAttributes.Normal;\n            Encoding encoding = Encoding.Unicode;\n            if(File.Exists(filePath))\n            {\n                encoding = EncodingType.GetType(filePath);\n                attributes = File.GetAttributes(filePath);\n                File.SetAttributes(filePath, FileAttributes.Normal);\n            }\n            File.WriteAllLines(filePath, lines.ToArray(), encoding);\n            File.SetAttributes(filePath, attributes);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/IniWriter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{\n    public sealed class IniWriter\n    {\n        public IniWriter() { }\n\n        public IniWriter(string filePath)\n        {\n            this.FilePath = filePath;\n        }\n\n        public string FilePath { get; set; }\n\n        public bool DeleteFileWhenEmpty { get; set; }\n\n        private List<string> GetLines()\n        {\n            List<string> lines = new List<string>();\n            if(!File.Exists(FilePath)) return lines;\n            using(StreamReader reader = new StreamReader(FilePath, EncodingType.GetType(FilePath)))\n            {\n                while(!reader.EndOfStream)\n                {\n                    lines.Add(reader.ReadLine().Trim());\n                }\n            }\n            return lines;\n        }\n\n        /// <param name=\"isGetValue\">是否是获取value值</param>\n        private void SetValue(string section, string key, ref string value, bool isGetValue)\n        {\n            if(section == null) return;\n            List<string> lines = GetLines();\n            string sectionLine = $\"[{section}]\";\n            string keyLine = $\"{key}={value}\";\n            int sectionRow = -1, keyRow = -1;//先假设不存在目标section和目标key\n            int nextSectionRow = -1;//下一个section的行数\n            for(int i = 0; i < lines.Count; i++)\n            {\n                if(lines[i].StartsWith(sectionLine, StringComparison.OrdinalIgnoreCase))\n                {\n                    sectionRow = i; break;//得到目标section所在行\n                }\n            }\n            if(sectionRow >= 0)//如果目标section存在\n            {\n                for(int i = sectionRow + 1; i < lines.Count; i++)\n                {\n                    if(lines[i].StartsWith(\";\") || lines[i].StartsWith(\"#\"))\n                    {\n                        continue;//跳过注释\n                    }\n                    if(lines[i].StartsWith(\"[\"))\n                    {\n                        nextSectionRow = i; break;//读取到下一个section\n                    }\n                    if(key != null && keyRow == -1)\n                    {\n                        int index = lines[i].IndexOf('=');\n                        if(index < 0) continue;\n                        string str = lines[i].Substring(0, index).TrimEnd();\n                        if(str.Equals(key, StringComparison.OrdinalIgnoreCase))\n                        {\n                            if(isGetValue)//如果是获取Value值，直接返回\n                            {\n                                value = lines[i].Substring(index + 1).Trim();\n                                return;\n                            }\n                            keyRow = i; continue;//得到目标key行\n                        }\n                    }\n                }\n            }\n\n            if(isGetValue) return;\n\n            if(sectionRow == -1)\n            {\n                if(key != null && value != null)\n                {\n                    lines.Add(string.Empty);//添加空行\n                    //目标section不存在则添加到最后\n                    lines.Add(sectionLine);\n                    lines.Add(keyLine);\n                }\n            }\n            else\n            {\n                if(keyRow == -1)\n                {\n                    if(key != null)\n                    {\n                        //存在下一个section时插入到其上方\n                        if(nextSectionRow != -1)\n                        {\n                            //目标section存在但目标key不存在\n                            keyRow = nextSectionRow;\n                            lines.Insert(keyRow, keyLine);\n                        }\n                        else\n                        {\n                            //不存在下一个section则添加到最后\n                            lines.Add(keyLine);\n                        }\n                    }\n                    else\n                    {\n                        //key为null则删除整个section\n                        int count;\n                        if(nextSectionRow == -1) count = lines.Count - sectionRow;\n                        else count = nextSectionRow - sectionRow;\n                        lines.RemoveRange(sectionRow, count);\n                    }\n                }\n                else\n                {\n                    if(value != null)\n                    {\n                        //目标section和目标key都存在\n                        lines[keyRow] = keyLine;\n                    }\n                    else\n                    {\n                        //赋值为null则删除key\n                        lines.RemoveAt(keyRow);\n                    }\n                }\n            }\n\n            Directory.CreateDirectory(Path.GetDirectoryName(FilePath));\n            FileAttributes attributes = FileAttributes.Normal;\n            Encoding encoding = Encoding.Unicode;\n            if(File.Exists(FilePath))\n            {\n                encoding = EncodingType.GetType(FilePath);\n                attributes = File.GetAttributes(FilePath);\n                File.SetAttributes(FilePath, FileAttributes.Normal);\n            }\n            File.WriteAllLines(FilePath, lines.ToArray(), encoding);\n            File.SetAttributes(FilePath, attributes);\n\n            if(DeleteFileWhenEmpty && lines.TrueForAll(line => line.IsNullOrWhiteSpace()))\n            {\n                File.Delete(FilePath);\n            }\n        }\n\n        public void SetValue(string section, string key, object value)\n        {\n            SetValue(section, key, value.ToString());\n        }\n\n        public void SetValue(string section, string key, string value)\n        {\n            SetValue(section, key, ref value, false);\n        }\n\n        public void DeleteKey(string section, string key)\n        {\n            SetValue(section, key, null);\n        }\n\n        public void DeleteSection(string section)\n        {\n            SetValue(section, null, null);\n        }\n\n        /// <summary>一次读取只获取一个值，用此方法比IniReader.GetValue要快</summary>\n        public string GetValue(string section, string key)\n        {\n            string value = string.Empty;\n            SetValue(section, key, ref value, true);\n            return value;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/MessageBoxEx.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    /// <summary>在窗体居中显示的MessageBox</summary>\n    public static class MessageBoxEx\n    {\n        /// <summary>弹出一个消息框</summary>\n        /// <param name=\"text\">要在消息框中显示的文本</param>\n        /// <param name=\"caption\">要在消息框的标题栏中显示的文本</param>\n        /// <param name=\"buttons\">指定在消息框中显示哪些按钮</param>\n        /// <param name=\"boxIcon\">指定在消息框中显示哪个图标</param>\n        /// <param name=\"owner\">指定消息框的拥有者</param>\n        /// <param name=\"defaultResult\">指定默认结果，使对应按钮预先获取焦点</param>\n        /// <param name=\"canMoveParent\">能否移动父窗体</param>\n        /// <returns>System.Windows.Forms.DialogResult 值之一</returns>\n        public static DialogResult Show(string text, string caption = null,\n            MessageBoxButtons buttons = MessageBoxButtons.OK, MessageBoxIcon boxIcon = MessageBoxIcon.None,\n            IWin32Window owner = null, DialogResult defaultResult = DialogResult.None, bool canMoveParent = true)\n        {\n            using(MessageBoxForm frm = new MessageBoxForm(text, caption, buttons, boxIcon, defaultResult, canMoveParent))\n            {\n                return frm.ShowDialog(owner);\n            }\n        }\n\n        /// <summary>弹出一个消息框</summary>\n        /// <param name=\"text\">要在消息框中显示的文本</param>\n        /// <param name=\"caption\">要在消息框的标题栏中显示的文本</param>\n        /// <param name=\"buttonTexts\">从右至左添加数组长度的个数的按钮，按钮文本为数组对应成员</param>\n        /// <param name=\"boxImaage\">指定在消息框中显示的图标图像</param>\n        /// <param name=\"owner\">指定消息框的拥有者</param>\n        /// <param name=\"defaultResult\">指定默认结果，使对应按钮预先获取焦点</param>\n        /// <param name=\"canMoveParent\">能否移动父窗体</param>\n        /// <param name=\"closeBox\">消息框关闭按钮是否可用</param>\n        /// <returns>返回用户点击的按钮所显示的文本</returns>\n        public static string Show(string text, string caption,\n            string[] buttonTexts, Image boxImaage,\n            IWin32Window owner = null, string defaultResult = null,\n            bool canMoveParent = true, bool closeBox = true)\n        {\n            using(MessageBoxForm frm = new MessageBoxForm(text, caption, buttonTexts, boxImaage, defaultResult, canMoveParent, closeBox))\n            {\n                frm.ShowDialog(owner);\n                return frm.Tag?.ToString();\n            }\n        }\n\n        sealed class MessageBoxForm : Form\n        {\n            private MessageBoxForm(string text, string caption, bool canMoveParent)\n            {\n                lblText.Text = text;\n                this.Text = caption;\n                this.CanMoveParent = canMoveParent;\n                this.Font = SystemFonts.MessageBoxFont;\n                this.ShowIcon = this.ShowInTaskbar = false;\n                this.MaximizeBox = this.MinimizeBox = false;\n                this.FormBorderStyle = FormBorderStyle.FixedSingle;\n                this.StartPosition = FormStartPosition.CenterParent;\n            }\n\n            public MessageBoxForm(string text, string caption,\n                string[] buttonTexts, Image boxImage,\n                string defaultResult, bool canMoveParent, bool closeBox) : this(text, caption, canMoveParent)\n            {\n                this.CloseBox = closeBox;\n                this.InitializeComponents(buttonTexts, boxImage);\n                foreach(Button button in flpButtons.Controls)\n                {\n                    button.Click += (sender, e) =>\n                    {\n                        this.Tag = button.Text;\n                        this.Close();\n                    };\n                    this.Shown += (sender, e) =>\n                    {\n                        if(button.Text == defaultResult) button.Focus();\n                    };\n                }\n            }\n\n            public MessageBoxForm(string text, string caption,\n                MessageBoxButtons buttons, MessageBoxIcon boxIcon,\n                DialogResult defaultResult, bool canMoveParent) : this(text, caption, canMoveParent)\n            {\n                string[] buttonTexts = null;\n                Image boxImage = null;\n                switch(buttons)\n                {\n                    case MessageBoxButtons.OK:\n                        buttonTexts = new[] { \"OK\" }; break;\n                    case MessageBoxButtons.OKCancel:\n                        buttonTexts = new[] { \"Cancel\", \"OK\" }; break;\n                    case MessageBoxButtons.AbortRetryIgnore:\n                        buttonTexts = new[] { \"&Ignore\", \"&Retry\", \"&Abort\" }; break;\n                    case MessageBoxButtons.YesNoCancel:\n                        buttonTexts = new[] { \"Cancel\", \"&No\", \"&Yes\" }; break;\n                    case MessageBoxButtons.YesNo:\n                        buttonTexts = new[] { \"&No\", \"&Yes\" }; break;\n                    case MessageBoxButtons.RetryCancel:\n                        buttonTexts = new[] { \"Cancel\", \"&Retry\" }; break;\n                }\n                switch(boxIcon)\n                {\n                    case MessageBoxIcon.Question:\n                        boxImage = MessageBoxImage.Question; break;\n                    case MessageBoxIcon.Error:\n                        boxImage = MessageBoxImage.Error; break;\n                    case MessageBoxIcon.Warning:\n                        boxImage = MessageBoxImage.Warning; break;\n                    case MessageBoxIcon.Information:\n                        boxImage = MessageBoxImage.Information; break;\n                }\n                this.InitializeComponents(buttonTexts, boxImage);\n                foreach(Button button in flpButtons.Controls)\n                {\n                    switch(button.Text)\n                    {\n                        case \"OK\":\n                            if(buttons == MessageBoxButtons.OK)\n                            {\n                                this.CancelButton = button;\n                                this.FormClosing += (sender, e) => button.PerformClick();\n                            }\n                            button.DialogResult = DialogResult.OK; break;\n                        case \"Cancel\":\n                            this.CancelButton = button;\n                            button.DialogResult = DialogResult.Cancel; break;\n                        case \"&Yes\":\n                            button.DialogResult = DialogResult.Yes; break;\n                        case \"&No\":\n                            button.DialogResult = DialogResult.No; break;\n                        case \"&Abort\":\n                            button.DialogResult = DialogResult.Abort; break;\n                        case \"&Retry\":\n                            button.DialogResult = DialogResult.Retry; break;\n                        case \"&Ignore\":\n                            button.DialogResult = DialogResult.Ignore; break;\n                    }\n                    this.Shown += (sender, e) =>\n                    {\n                        if(button.DialogResult == defaultResult) button.Focus();\n                    };\n                }\n                this.CloseBox = this.CancelButton != null;\n            }\n\n            private void InitializeComponents(string[] buttonTexts, Image boxImage)\n            {\n                this.SuspendLayout();\n                int w1 = 36.DpiZoom();\n                Size buttonSize = new Size(75, 27).DpiZoom();\n                for(int i = 0; i < buttonTexts.Length; i++)\n                {\n                    Button button = new Button\n                    {\n                        Margin = new Padding(12, 0, 0, 0).DpiZoom(),\n                        Text = buttonTexts[i],\n                        Parent = flpButtons,\n                        AutoSize = true,\n                    };\n                    button.Width = Math.Max(buttonSize.Width, button.Width);\n                    button.Height = Math.Max(buttonSize.Height, button.Height);\n                    buttonSize = button.Size;\n                    w1 += button.Width + button.Margin.Horizontal;\n                }\n                picIcon.Image = boxImage;\n                if(boxImage == null)\n                {\n                    picIcon.Visible = false;\n                    lblText.Left = picIcon.Left;\n                }\n                pnlInfo.Controls.AddRange(new Control[] { picIcon, lblText });\n                this.Controls.AddRange(new Control[] { pnlInfo, flpButtons });\n                pnlInfo.Height = lblText.Height + lblText.Top * 2;\n                if(picIcon.Height > lblText.Height / 2)\n                {\n                    picIcon.Top = (pnlInfo.Height - picIcon.Height) / 2;\n                }\n                int w2 = lblText.Right + picIcon.Left;\n                int w = Math.Max(w1, w2);\n                int h = pnlInfo.Height + flpButtons.Height;\n                this.ClientSize = new Size(w, h);\n                this.ResumeLayout();\n            }\n\n            readonly FlowLayoutPanel flpButtons = new FlowLayoutPanel\n            {\n                FlowDirection = FlowDirection.RightToLeft,\n                Padding = new Padding(12.DpiZoom()),\n                Dock = DockStyle.Bottom,\n                Height = 50.DpiZoom(),\n                WrapContents = false,\n            };\n            readonly Panel pnlInfo = new Panel\n            {\n                BackColor = Color.White,\n                Dock = DockStyle.Top,\n            };\n            readonly PictureBox picIcon = new PictureBox\n            {\n                SizeMode = PictureBoxSizeMode.AutoSize,\n                Location = new Point(32, 32).DpiZoom(),\n            };\n            readonly Label lblText = new Label\n            {\n                Location = new Point(68, 32).DpiZoom(),\n                AutoSize = true,\n            };\n\n            readonly bool CloseBox = true;//关闭按钮可用性\n            readonly bool CanMoveParent = true;//可移动父窗体\n\n            protected override CreateParams CreateParams\n            {\n                get\n                {\n                    const int CP_NOCLOSE_BUTTON = 0x200;\n                    CreateParams cp = base.CreateParams;\n                    if(!CloseBox) cp.ClassStyle |= CP_NOCLOSE_BUTTON; //禁用关闭按钮\n                    return cp;\n                }\n            }\n\n            protected override void OnLoad(EventArgs e)\n            {\n                if(this.Owner == null && Form.ActiveForm != this) this.Owner = Form.ActiveForm;\n                if(this.Owner == null) this.StartPosition = FormStartPosition.CenterScreen;\n                else\n                {\n                    this.TopMost = this.Owner.TopMost;\n                    this.StartPosition = FormStartPosition.CenterParent;\n                    if(this.CanMoveParent) this.MoveAsMove(this.Owner);\n                }\n                base.OnLoad(e);\n            }\n        }\n    }\n\n    public static class MessageBoxImage\n    {\n        // SystemIcons 里面的图标不是扁平的,❌、⚠️、❔、ℹ️\n        public static readonly Image Error = GetImage(-98);\n        public static readonly Image Warning = GetImage(-84);\n        public static readonly Image Question = GetImage(-99);\n        public static readonly Image Information = GetImage(-81);\n\n        private static Image GetImage(int index)\n        {\n            using(Icon icon = ResourceIcon.GetIcon(\"imageres.dll\", index))\n            {\n                return icon?.ToBitmap();\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/RegTrustedInstaller.cs",
    "content": "﻿using Microsoft.Win32;\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Security.AccessControl;\nusing System.Security.Principal;\n\nnamespace BluePointLilac.Methods\n{\n    /// 获取TrustedInstaller权限注册表项的所有权\n    /// 代码作者：JPBlanc（原作者）、蓝点lilac（转载、修改）\n    /// 代码原文：https://gist.github.com/JPBlanc/ca0e4f1830e4ca18a526#file-write_a_registry_own_by_trustedinstaller-cs\n    public class RegTrustedInstaller\n    {\n        static class NativeMethod\n        {\n            public const string TakeOwnership = \"SeTakeOwnershipPrivilege\";\n            public const string Restore = \"SeRestorePrivilege\";\n\n            [StructLayout(LayoutKind.Sequential)]\n            public struct LUID\n            {\n                public int lowPart;\n                public int highPart;\n            }\n\n            [StructLayout(LayoutKind.Sequential)]\n            public struct LUID_AND_ATTRIBUTES\n            {\n                public LUID Luid;\n                public int Attributes;\n            }\n\n            [StructLayout(LayoutKind.Sequential)]\n            public struct TOKEN_PRIVILEGES\n            {\n                public int PrivilegeCount;\n                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]\n                public LUID_AND_ATTRIBUTES[] Privileges;\n            }\n\n            [Flags]\n            public enum PrivilegeAttributes\n            {\n                /// <summary>特权被禁用.</summary>\n                Disabled = 0,\n                /// <summary>默认特权.</summary>\n                EnabledByDefault = 1,\n                /// <summary>特权被激活.</summary>\n                Enabled = 2,\n                /// <summary>特权被废除.</summary>\n                Removed = 4,\n                /// <summary>用于访问对象或服务的特权.</summary>\n                UsedForAccess = -2147483648\n            }\n\n            [Flags]\n            public enum TokenAccessRights\n            {\n                /// <summary>向进程附加主令牌的权限.</summary>\n                AssignPrimary = 0,\n                /// <summary>复制访问令牌的权利.</summary>\n                Duplicate = 1,\n                /// <summary>向进程附加模拟访问令牌的权限.</summary>\n                Impersonate = 4,\n                /// <summary>查询访问令牌的权利.</summary>\n                Query = 8,\n                /// <summary>有权查询访问令牌的来源.</summary>\n                QuerySource = 16,\n                /// <summary>启用或禁用访问令牌中的特权的权限.</summary>\n                AdjustPrivileges = 32,\n                /// <summary>调整访问令牌中的组属性的权限.</summary>\n                AdjustGroups = 64,\n                /// <summary>更改访问令牌的默认所有者、主组或DACL的权限.</summary>\n                AdjustDefault = 128,\n                /// <summary>正确调整访问令牌的会话ID.</summary>\n                AdjustSessionId = 256,\n                /// <summary>为令牌组合所有可能的访问权限.</summary>\n                AllAccess = AccessTypeMasks.StandardRightsRequired | AssignPrimary | Duplicate | Impersonate\n                            | Query | QuerySource | AdjustPrivileges | AdjustGroups | AdjustDefault | AdjustSessionId,\n                /// <summary>结合需要阅读的标准权利</summary>\n                Read = AccessTypeMasks.StandardRightsRead | Query,\n                /// <summary>组合了写入所需的标准权限</summary>\n                Write = AccessTypeMasks.StandardRightsWrite | AdjustPrivileges | AdjustGroups | AdjustDefault,\n                /// <summary>合并执行所需的标准权限</summary>\n                Execute = AccessTypeMasks.StandardRightsExecute | Impersonate\n            }\n\n            [Flags]\n            private enum AccessTypeMasks\n            {\n                Delete = 65536,\n                ReadControl = 131072,\n                WriteDAC = 262144,\n                WriteOwner = 524288,\n                Synchronize = 1048576,\n                StandardRightsRequired = 983040,\n                StandardRightsRead = ReadControl,\n                StandardRightsWrite = ReadControl,\n                StandardRightsExecute = ReadControl,\n                StandardRightsAll = 2031616,\n                SpecificRightsAll = 65535\n            }\n\n            [DllImport(\"advapi32.dll\", SetLastError = true)]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            private static extern bool AdjustTokenPrivileges([In] IntPtr accessTokenHandle, [In] bool disableAllPrivileges,\n                [In] ref TOKEN_PRIVILEGES newState, [In] int bufferLength, [In, Out] ref TOKEN_PRIVILEGES previousState, [In, Out] ref int returnLength);\n\n            [DllImport(\"advapi32.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            private static extern bool LookupPrivilegeValue([In] string systemName, [In] string name, [In, Out] ref LUID luid);\n\n            [DllImport(\"advapi32.dll\", SetLastError = true)]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            private static extern bool OpenProcessToken([In] IntPtr processHandle, [In] TokenAccessRights desiredAccess, [In, Out] ref IntPtr tokenHandle);\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            private static extern int GetLastError();\n\n            [DllImport(\"kernel32.dll\", SetLastError = true)]\n            private static extern IntPtr GetCurrentProcess();\n\n            public static bool TrySetPrivilege(string sPrivilege, bool enablePrivilege)\n            {\n                bool blRc;\n                TOKEN_PRIVILEGES newTP = new TOKEN_PRIVILEGES();\n                TOKEN_PRIVILEGES oldTP = new TOKEN_PRIVILEGES();\n                LUID luid = new LUID();\n                int retrunLength = 0;\n                IntPtr processToken = IntPtr.Zero;\n\n                //本地进程令牌恢复\n                blRc = OpenProcessToken(GetCurrentProcess(), TokenAccessRights.AllAccess, ref processToken);\n                if(blRc == false) return false;\n\n                //恢复特权的唯一标识符空间\n                blRc = LookupPrivilegeValue(null, sPrivilege, ref luid);\n                if(blRc == false) return false;\n\n                //建立或取消特权\n                newTP.PrivilegeCount = 1;\n                newTP.Privileges = new LUID_AND_ATTRIBUTES[64];\n                newTP.Privileges[0].Luid = luid;\n\n                if(enablePrivilege) newTP.Privileges[0].Attributes = (int)PrivilegeAttributes.Enabled;\n                else newTP.Privileges[0].Attributes = (int)PrivilegeAttributes.Disabled;\n\n                oldTP.PrivilegeCount = 64;\n                oldTP.Privileges = new LUID_AND_ATTRIBUTES[64];\n                blRc = AdjustTokenPrivileges(processToken, false, ref newTP, 16, ref oldTP, ref retrunLength);\n\n                if(blRc == false) { GetLastError(); return false; }\n                return true;\n            }\n        }\n\n        /// <summary>获取注册表项权限</summary>\n        /// <remarks>将注册表项所有者改为当前管理员用户</remarks>\n        /// <param name=\"regPath\">要获取权限的注册表完整路径</param>\n        public static void TakeRegKeyOwnerShip(string regPath)\n        {\n            if(regPath.IsNullOrWhiteSpace()) return;\n            RegistryKey key = null;\n            WindowsIdentity id = null;\n            //利用试错判断是否有写入权限\n            try { key = RegistryEx.GetRegistryKey(regPath, true); }\n            catch\n            {\n                try\n                {\n                    //获取当前用户的ID\n                    id = WindowsIdentity.GetCurrent();\n\n                    //添加TakeOwnership特权\n                    bool flag = NativeMethod.TrySetPrivilege(NativeMethod.TakeOwnership, true);\n                    if(!flag) throw new PrivilegeNotHeldException(NativeMethod.TakeOwnership);\n\n                    //添加恢复特权(必须这样做才能更改所有者)\n                    flag = NativeMethod.TrySetPrivilege(NativeMethod.Restore, true);\n                    if(!flag) throw new PrivilegeNotHeldException(NativeMethod.Restore);\n\n                    //打开没有权限的注册表路径\n                    key = RegistryEx.GetRegistryKey(regPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);\n\n                    RegistrySecurity security = key.GetAccessControl(AccessControlSections.All);\n\n                    //得到真正所有者\n                    //IdentityReference oldId = security.GetOwner(typeof(SecurityIdentifier));\n                    //SecurityIdentifier siTrustedInstaller = new SecurityIdentifier(oldId.ToString());\n\n                    //使进程用户成为所有者\n                    security.SetOwner(id.User);\n                    key.SetAccessControl(security);\n\n                    //添加完全控制\n                    RegistryAccessRule fullAccess = new RegistryAccessRule(id.User, RegistryRights.FullControl,\n                        InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow);\n                    security.AddAccessRule(fullAccess);\n                    key.SetAccessControl(security);\n\n                    //注册表操作（写入、删除）\n                    //key.SetValue(\"temp\", \"\");//示例\n\n                    //恢复原有所有者\n                    //security.SetOwner(siTrustedInstaller);\n                    //key.SetAccessControl(security);\n\n                    //收回原有权利\n                    //security.RemoveAccessRule(fullAccess);\n                    //key.SetAccessControl(security);\n\n                    ///得到真正所有者、注册表操作、恢复原有所有者、收回原有权利，这四部分在原文中没有被注释掉\n                    ///但是如果保留这四部分，会在恢复原有所有者这一步抛出异常，提示没有权限，\n                    ///不过我发现经过上面的操作，虽然无法还原所有者权限，但是已经获取了注册表权限\n                    ///即已经将TrustedInstaller权限更改为当前管理员用户权限，我要的目的已经达到了\n                }\n                catch { }\n            }\n            finally { key?.Close(); id?.Dispose(); }\n        }\n\n        /// <summary>获取注册表项及其子项、递归子级子项权限</summary>\n        /// <remarks>将注册表项所有者改为当前管理员用户</remarks>\n        /// <param name=\"regPath\">要获取权限的注册表完整路径</param>\n        public static void TakeRegTreeOwnerShip(string regPath)\n        {\n            if(regPath.IsNullOrWhiteSpace()) return;\n            TakeRegKeyOwnerShip(regPath);\n            try\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey(regPath))\n                {\n                    if(key == null) return;\n                    foreach(string subKeyName in key.GetSubKeyNames())\n                    {\n                        TakeRegTreeOwnerShip($@\"{key.Name}\\{subKeyName}\");\n                    }\n                }\n            }\n            catch { }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/RegistryEx.cs",
    "content": "﻿using Microsoft.Win32;\nusing System;\nusing System.Security.AccessControl;\n\nnamespace BluePointLilac.Methods\n{\n    public static class RegistryEx\n    {\n        public const string CLASSES_ROOT = \"HKEY_CLASSES_ROOT\";\n        public const string CURRENT_USER = \"HKEY_CURRENT_USER\";\n        public const string LOCAL_MACHINE = \"HKEY_LOCAL_MACHINE\";\n        public const string CURRENT_CONFIG = \"HKEY_CURRENT_CONFIG\";\n        public const string USERS = \"HKEY_USERS\";\n\n        public const string HKCR = \"HKCR\";\n        public const string HKCU = \"HKCU\";\n        public const string HKLM = \"HKLM\";\n        public const string HKCC = \"HKCC\";\n        public const string HKU = \"HKU\";\n\n        public static void CopyTo(this RegistryKey srcKey, RegistryKey dstKey)\n        {\n            foreach(string name in srcKey.GetValueNames())\n            {\n                dstKey.SetValue(name, srcKey.GetValue(name), srcKey.GetValueKind(name));\n            }\n            foreach(string name in srcKey.GetSubKeyNames())\n            {\n                using(RegistryKey srcSubKey = srcKey.OpenSubKey(name))\n                using(RegistryKey dstSubKey = dstKey.CreateSubKey(name, true))\n                    srcSubKey.CopyTo(dstSubKey);\n            }\n        }\n\n        public static void CopyTo(string srcPath, string dstPath)\n        {\n            using(RegistryKey srcKey = GetRegistryKey(srcPath))\n            using(RegistryKey dstKey = GetRegistryKey(dstPath, true, true))\n            {\n                CopyTo(srcKey, dstKey);\n            }\n        }\n\n        public static void MoveTo(this RegistryKey srcKey, RegistryKey dstKey)\n        {\n            CopyTo(srcKey, dstKey);\n            DeleteKeyTree(srcKey.Name, true);\n        }\n\n        public static void MoveTo(string srcPath, string dstPath)\n        {\n            CopyTo(srcPath, dstPath);\n            DeleteKeyTree(srcPath, true);\n        }\n\n        public static RegistryKey CreateSubKey(this RegistryKey key, string subKeyName, bool writable)\n        {\n            using(key.CreateSubKey(subKeyName))\n                return key.OpenSubKey(subKeyName, writable);\n        }\n\n        /// <summary>获取指定路径注册表项的上一级路径</summary>\n        public static string GetParentPath(string regPath) => regPath.Substring(0, regPath.LastIndexOf('\\\\'));\n\n        /// <summary>获取指定路径注册表项的项名</summary>\n        public static string GetKeyName(string regPath) => regPath.Substring(regPath.LastIndexOf('\\\\') + 1);\n\n        /// <summary>获取指定路径注册表项的根项项名</summary>\n        public static string GetRootName(string regPath) => regPath.Substring(0, regPath.IndexOf('\\\\'));\n\n        /// <summary>获取不包含根项部分的注册表路径</summary>\n        public static string GetPathWithoutRoot(string regPath) => regPath.Substring(regPath.IndexOf('\\\\') + 1);\n\n        /// <summary>删除指定路径的注册表项的指定名称的键值</summary>\n        /// <param name=\"regPath\">注册表项路径</param>\n        /// <param name=\"valueName\">要删除的键值名称</param>\n        /// <param name=\"throwOnMissingValue\">找不到键值时是否抛出异常</param>\n        public static void DeleteValue(string regPath, string valueName, bool throwOnMissingValue = false)\n        {\n            GetRegistryKey(regPath, true)?.DeleteValue(valueName, throwOnMissingValue);\n        }\n\n        /// <summary>递归删除指定注册表项及所有子项</summary>\n        /// <param name=\"regPath\">注册表路径</param>\n        /// <param name=\"throwOnMissingKey\">找不到注册表项或者没有操作权限时是否抛出异常</param>\n        public static void DeleteKeyTree(string regPath, bool throwOnMissingKey = false)\n        {\n            string dirPath = GetParentPath(regPath);\n            string keyName = GetKeyName(regPath);\n            try\n            {\n                GetRegistryKey(dirPath, true)?.DeleteSubKeyTree(keyName);\n            }\n            catch(Exception)\n            {\n                if(throwOnMissingKey) throw;\n            }\n        }\n\n        /// <summary>获取指定注册表路径的根项RegistryKey和不包含根项部分的注册表路径</summary>\n        /// <param name=\"regPath\">注册表路径</param>\n        /// <param name=\"root\">成功解析返回一个RegistryKey，否则抛出异常</param>\n        /// <param name=\"subRegPath\">不包含根项的注册表路径</param>\n        public static void GetRootAndSubRegPath(string regPath, out RegistryKey root, out string subRegPath)\n        {\n            string rootPath;\n            int index = regPath.IndexOf('\\\\');\n            if(index > 0)\n            {\n                rootPath = regPath.Substring(0, index).ToUpper();\n                subRegPath = regPath.Substring(index + 1);\n            }\n            else\n            {\n                rootPath = regPath;\n                subRegPath = string.Empty;\n            }\n            switch(rootPath)\n            {\n                case HKCR:\n                case CLASSES_ROOT:\n                    root = Registry.ClassesRoot;\n                    break;\n                case HKCU:\n                case CURRENT_USER:\n                    root = Registry.CurrentUser;\n                    break;\n                case HKLM:\n                case LOCAL_MACHINE:\n                    root = Registry.LocalMachine;\n                    break;\n                case HKU:\n                case USERS:\n                    root = Registry.Users;\n                    break;\n                case HKCC:\n                case CURRENT_CONFIG:\n                    root = Registry.CurrentConfig;\n                    break;\n                default:\n                    throw new ArgumentNullException(regPath);\n            }\n        }\n\n        /// <summary>获取指定注册表项路径的RegistryKey</summary>\n        /// <param name=\"regPath\">注册表项路径</param>\n        /// <param name=\"writable\">写入访问权限</param>\n        /// <param name=\"create\">是否创建新项</param>\n        public static RegistryKey GetRegistryKey(string regPath, bool writable = false, bool create = false)\n        {\n            GetRootAndSubRegPath(regPath, out RegistryKey root, out string keyPath);\n            using(root)\n            {\n                if(create) return root.CreateSubKey(keyPath, writable);\n                else\n                {\n                    RegTrustedInstaller.TakeRegTreeOwnerShip(keyPath);\n                    return root.OpenSubKey(keyPath, writable);\n                }\n            }\n        }\n\n        public static RegistryKey GetRegistryKey(string regPath, RegistryKeyPermissionCheck check, RegistryRights rights)\n        {\n            GetRootAndSubRegPath(regPath, out RegistryKey root, out string keyPath);\n            using(root) return root.OpenSubKey(keyPath, check, rights);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ResourceIcon.cs",
    "content": "﻿using Microsoft.Win32;\nusing System;\nusing System.Drawing;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ResourceIcon\n    {\n        [DllImport(\"shell32.dll\", CharSet = CharSet.Auto)]\n        private static extern int ExtractIconEx(string lpFileName, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, uint nIcons);\n\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        private static extern bool DestroyIcon(IntPtr hIcon);\n\n        [DllImport(\"kernel32.dll\", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]\n        private static extern IntPtr LoadLibrary(string lpLibFileName);\n\n        [DllImport(\"kernel32.dll\")]\n        private static extern bool FreeLibrary(IntPtr hLibModule);\n\n        [DllImport(\"user32.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n        private static extern IntPtr LoadImage(IntPtr hInst, string lpFileName, uint uType, int cx, int cy, uint fuLoad);\n\n        [DllImport(\"shell32.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n        private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, FileInfoFlags uFlags);\n\n        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\n        private struct SHFILEINFO\n        {\n            public IntPtr hIcon;\n            public int iIcon;\n            public uint dwAttributes;\n            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]\n            public string szDisplayName;\n            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]\n            public string szTypeName;\n        }\n\n        [Flags]\n        public enum FileInfoFlags : uint\n        {\n            SHGFI_ICON = 0x000000100,               // get icon\n            SHGFI_DISPLAYNAME = 0x000000200,        // get display name\n            SHGFI_TYPENAME = 0x000000400,           // get type name\n            SHGFI_ATTRIBUTES = 0x000000800,         // get attributes\n            SHGFI_ICONLOCATION = 0x000001000,       // get icon location\n            SHGFI_EXETYPE = 0x000002000,            // return exe type\n            SHGFI_SYSICONINDEX = 0x000004000,       // get system icon index\n            SHGFI_LINKOVERLAY = 0x000008000,        // put a link overlay on icon\n            SHGFI_SELECTED = 0x000010000,           // show icon in selected state\n            SHGFI_ATTR_SPECIFIED = 0x000020000,     // get only specified attributes\n            SHGFI_LARGEICON = 0x000000000,          // get large icon\n            SHGFI_SMALLICON = 0x000000001,          // get small icon\n            SHGFI_OPENICON = 0x000000002,           // get open icon\n            SHGFI_SHELLICONSIZE = 0x000000004,      // get shell size icon\n            SHGFI_PIDL = 0x000000008,               // pszPath is a pidl\n            SHGFI_USEFILEATTRIBUTES = 0x000000010,  // use passed dwFileAttribute\n            SHGFI_ADDOVERLAYS = 0x000000020,        // apply the appropriate overlays\n            SHGFI_OVERLAYINDEX = 0x000000040        // get the index of the overlay in the upper 8 bits of the iIcon\n        }\n\n        /// <summary>获取文件类型的关联图标</summary>\n        /// <param name=\"extension\">文件类型的扩展名，如.txt</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetExtensionIcon(string extension)\n        {\n            FileInfoFlags flags = FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_LARGEICON | FileInfoFlags.SHGFI_USEFILEATTRIBUTES;\n            return GetIcon(extension, flags);\n        }\n\n        /// <summary>获取文件夹、磁盘驱动器的图标</summary>\n        /// <param name=\"folderPath\">文件夹或磁盘驱动器路径</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetFolderIcon(string folderPath)\n        {\n            FileInfoFlags flags = FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_LARGEICON;\n            return GetIcon(folderPath, flags);\n        }\n\n        /// <summary>根据文件信息标志提取指定文件路径的图标</summary>\n        /// <param name=\"filePath\">文件路径</param>\n        /// <param name=\"flags\">文件信息标志</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetIcon(string filePath, FileInfoFlags flags)\n        {\n            SHFILEINFO info = new SHFILEINFO();\n            IntPtr hInfo = SHGetFileInfo(filePath, 0, ref info, (uint)Marshal.SizeOf(info), flags);\n            if(hInfo.Equals(IntPtr.Zero)) return null;\n            Icon icon = (Icon)Icon.FromHandle(info.hIcon).Clone();\n            DestroyIcon(info.hIcon); //释放资源\n            return icon;\n        }\n\n        /// <summary>获取指定位置的图标</summary>\n        /// <param name=\"iconLocation\">图标位置</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetIcon(string iconLocation)\n        {\n            return GetIcon(iconLocation, out _, out _);\n        }\n\n        /// <summary>获取指定位置的图标</summary>\n        /// <param name=\"iconLocation\">图标位置</param>\n        /// <param name=\"iconPath\">返回图标文件路径</param>\n        /// <param name=\"iconIndex\">返回图标索引</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetIcon(string iconLocation, out string iconPath, out int iconIndex)\n        {\n            iconIndex = 0; iconPath = null;\n            if(iconLocation.IsNullOrWhiteSpace()) return null;\n            iconLocation = Environment.ExpandEnvironmentVariables(iconLocation).Replace(\"\\\"\", \"\");\n            int index = iconLocation.LastIndexOf(',');\n            if(index == -1) iconPath = iconLocation;\n            else\n            {\n                if(File.Exists(iconLocation)) iconPath = iconLocation;\n                else\n                {\n                    bool flag = int.TryParse(iconLocation.Substring(index + 1), out iconIndex);\n                    iconPath = flag ? iconLocation.Substring(0, index) : null;\n                }\n            }\n            return GetIcon(iconPath, iconIndex);\n        }\n\n        /// <summary>获取指定文件中指定索引的图标</summary>\n        /// <param name=\"iconPath\">图标文件路径</param>\n        /// <param name=\"iconIndex\">图标索引</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetIcon(string iconPath, int iconIndex)\n        {\n            Icon icon = null;\n            if(iconPath.IsNullOrWhiteSpace()) return icon;\n            iconPath = Environment.ExpandEnvironmentVariables(iconPath).Replace(\"\\\"\", \"\");\n\n            if(Path.GetFileName(iconPath).ToLower() == \"shell32.dll\")\n            {\n                iconPath = \"shell32.dll\";//系统强制文件重定向\n                icon = GetReplacedShellIcon(iconIndex);//注册表图标重定向\n                if(icon != null) return icon;\n            }\n\n            IntPtr hInst = IntPtr.Zero;\n            IntPtr[] hIcons = new[] { IntPtr.Zero };\n            //iconIndex为负数就是指定资源标识符, 为正数就是该图标在资源文件中的顺序序号, 为-1时不能使用ExtractIconEx提取图标\n            if(iconIndex == -1)\n            {\n                hInst = LoadLibrary(iconPath);\n                hIcons[0] = LoadImage(hInst, \"#1\", 1, SystemInformation.IconSize.Width, SystemInformation.IconSize.Height, 0);\n            }\n            else ExtractIconEx(iconPath, iconIndex, hIcons, null, 1);\n\n            try { icon = (Icon)Icon.FromHandle(hIcons[0]).Clone(); }\n            catch { icon = null; }\n            finally { DestroyIcon(hIcons[0]); FreeLibrary(hInst); }//释放资源\n            return icon;\n        }\n\n        private const string ShellIconPath = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Icons\";\n        /// <summary>获取shell32.dll中的图标被替换后的图标</summary>\n        /// <param name=\"iconIndex\">图标索引</param>\n        /// <returns>获取到的图标</returns>\n        public static Icon GetReplacedShellIcon(int iconIndex)\n        {\n            string iconLocation = Registry.GetValue(ShellIconPath, iconIndex.ToString(), null)?.ToString();\n            if(iconLocation != null) return GetIcon(iconLocation) ?? GetIcon(\"imageres.dll\", 2);\n            else return null;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ResourceString.cs",
    "content": "﻿using System;\nusing System.Runtime.InteropServices;\nusing System.Text;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ResourceString\n    {\n        //MSDN文档: https://docs.microsoft.com/windows/win32/api/shlwapi/nf-shlwapi-shloadindirectstring\n        //提取.pri文件资源: https://docs.microsoft.com/windows/uwp/app-resources/makepri-exe-command-options\n        //.pri转储.xml资源列表: MakePri.exe dump /if [priPath] /of [xmlPath]\n\n        [DllImport(\"shlwapi.dll\", BestFitMapping = false, CharSet = CharSet.Unicode,\n            ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]\n        private static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, IntPtr ppvReserved);\n\n        /// <summary>获取格式为\"@[filename],-[strID]\"或\"@{[packageName]?ms-resource://[resPath]}\"的直接字符串</summary>\n        /// <param name=\"resStr\">要转换的字符串</param>\n        /// <returns>resStr为Null时返回值为string.Empty; resStr首字符为@但解析失败时返回string.Empty</returns>\n        /// <remarks>[fileName]:文件路径; [strID]:字符串资源索引; [packageName]:UWP带版本号包名; [resPath]:pri资源路径</remarks>\n        public static string GetDirectString(string resStr)\n        {\n            StringBuilder outBuff = new StringBuilder(1024);\n            SHLoadIndirectString(resStr, outBuff, 1024, IntPtr.Zero);\n            return outBuff.ToString();\n        }\n\n        public static readonly string OK = GetDirectString(\"@shell32.dll,-9752\");\n        public static readonly string Cancel = GetDirectString(\"@shell32.dll,-9751\");\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/RichTextBoxExtension.cs",
    "content": "﻿using System;\nusing System.Drawing;\nusing System.Windows.Forms;\nusing System.Xml.Linq;\n\nnamespace BluePointLilac.Methods\n{\n    public static class RichTextBoxExtension\n    {\n        /// <summary>RichTextBox中ini语法高亮</summary>\n        /// <param name=\"iniStr\">要显示的ini文本</param>\n        public static void LoadIni(this RichTextBox box, string iniStr)\n        {\n            string[] lines = iniStr.Split(new[] { \"\\r\\n\", \"\\n\" }, StringSplitOptions.None);\n            for(int i = 0; i < lines.Length; i++)\n            {\n                string str = lines[i].Trim();\n                if(str.StartsWith(\";\") || str.StartsWith(\"#\"))\n                {\n                    box.AppendText(str, Color.SkyBlue);//注释\n                }\n                else if(str.StartsWith(\"[\"))\n                {\n                    if(str.Contains(\"]\"))\n                    {\n                        int index = str.IndexOf(']');\n                        box.AppendText(str.Substring(0, index + 1), Color.DarkCyan, null, true);//section\n                        box.AppendText(str.Substring(index + 1), Color.SkyBlue);//section标签之后的内容视作注释\n                    }\n                    else box.AppendText(str, Color.SkyBlue);//section标签未关闭视作注释\n                }\n                else if(str.Contains(\"=\"))\n                {\n                    int index = str.IndexOf('=');\n                    box.AppendText(str.Substring(0, index), Color.DodgerBlue);//key\n                    box.AppendText(str.Substring(index), Color.DimGray);//value\n                }\n                else box.AppendText(str, Color.SkyBlue);//非section行和非key行视作注释\n                if(i != lines.Length - 1) box.AppendText(\"\\r\\n\");\n            }\n        }\n\n        /// 代码原文：https://archive.codeplex.com/?p=xmlrichtextbox\n        /// 本人（蓝点lilac）仅作简单修改，将原继承类改写为扩展方法\n        /// <summary>RichTextBox中xml语法高亮</summary>\n        /// <param name=\"xmlStr\">要显示的xml文本</param>\n        /// <remarks>可直接用WebBrowser的Url加载本地xml文件，但无法自定义颜色</remarks>\n        public static void LoadXml(this RichTextBox box, string xmlStr)\n        {\n            XmlStateMachine machine = new XmlStateMachine();\n            if(xmlStr.StartsWith(\"<?\"))\n            {\n                string declaration = machine.GetXmlDeclaration(xmlStr);\n                try\n                {\n                    xmlStr = XDocument.Parse(xmlStr, LoadOptions.PreserveWhitespace).ToString().Trim();\n                    if(string.IsNullOrEmpty(xmlStr) && declaration == string.Empty) return;\n                }\n                catch { throw; }\n                xmlStr = declaration + \"\\r\\n\" + xmlStr;\n            }\n\n            int location = 0;\n            int failCount = 0;\n            int tokenTryCount = 0;\n            while(location < xmlStr.Length)\n            {\n                string token = machine.GetNextToken(xmlStr.Substring(location), out XmlTokenType ttype);\n                Color color = machine.GetTokenColor(ttype);\n                bool isBold = ttype == XmlTokenType.DocTypeName || ttype == XmlTokenType.NodeName;\n                box.AppendText(token, color, null, isBold);\n                location += token.Length;\n                tokenTryCount++;\n\n                // Check for ongoing failure\n                if(token.Length == 0) failCount++;\n                if(failCount > 10 || tokenTryCount > xmlStr.Length)\n                {\n                    string theRestOfIt = xmlStr.Substring(location, xmlStr.Length - location);\n                    //box.AppendText(Environment.NewLine + Environment.NewLine + theRestOfIt); // DEBUG\n                    box.AppendText(theRestOfIt);\n                    break;\n                }\n            }\n        }\n\n        public static void AppendText(this RichTextBox box, string text, Color color = default, Font font = null, bool isBold = false)\n        {\n            FontStyle fontStyle = isBold ? FontStyle.Bold : FontStyle.Regular;\n            box.SelectionFont = new Font(font ?? box.Font, fontStyle);\n            box.SelectionColor = color != default ? color : box.ForeColor;\n            box.SelectionStart = box.TextLength;\n            box.SelectionLength = 0;\n            box.AppendText(text);\n            box.SelectionColor = box.ForeColor;\n        }\n\n        sealed class XmlStateMachine\n        {\n            public XmlTokenType CurrentState = XmlTokenType.Unknown;\n            private string subString = string.Empty;\n            private string token = string.Empty;\n\n            public string GetNextToken(string s, out XmlTokenType ttype)\n            {\n                ttype = XmlTokenType.Unknown;\n                // skip past any whitespace (token added to it at the end of method)\n                string whitespace = GetWhitespace(s);\n                subString = s.TrimStart();\n                token = string.Empty;\n                if(CurrentState == XmlTokenType.CDataStart)\n                {\n                    // check for empty CDATA\n                    if(subString.StartsWith(\"]]>\"))\n                    {\n                        CurrentState = XmlTokenType.CDataEnd;\n                        token = \"]]>\";\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.CDataValue;\n                        int n = subString.IndexOf(\"]]>\");\n                        token = subString.Substring(0, n);\n                    }\n                }\n                else if(CurrentState == XmlTokenType.DocTypeStart)\n                {\n                    CurrentState = XmlTokenType.DocTypeName;\n                    token = \"DOCTYPE\";\n                }\n                else if(CurrentState == XmlTokenType.DocTypeName)\n                {\n                    CurrentState = XmlTokenType.DocTypeDeclaration;\n                    int n = subString.IndexOf(\"[\");\n                    token = subString.Substring(0, n);\n                }\n                else if(CurrentState == XmlTokenType.DocTypeDeclaration)\n                {\n                    CurrentState = XmlTokenType.DocTypeDefStart;\n                    token = \"[\";\n                }\n                else if(CurrentState == XmlTokenType.DocTypeDefStart)\n                {\n                    if(subString.StartsWith(\"]>\"))\n                    {\n                        CurrentState = XmlTokenType.DocTypeDefEnd;\n                        token = \"]>\";\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.DocTypeDefValue;\n                        int n = subString.IndexOf(\"]>\");\n                        token = subString.Substring(0, n);\n                    }\n                }\n                else if(CurrentState == XmlTokenType.DocTypeDefValue)\n                {\n                    CurrentState = XmlTokenType.DocTypeDefEnd;\n                    token = \"]>\";\n                }\n                else if(CurrentState == XmlTokenType.DoubleQuotationMarkStart)\n                {\n                    // check for empty attribute value\n                    if(subString[0] == '\\\"')\n                    {\n                        CurrentState = XmlTokenType.DoubleQuotationMarkEnd;\n                        token = \"\\\"\";\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.AttributeValue;\n                        int n = subString.IndexOf(\"\\\"\");\n                        token = subString.Substring(0, n);\n                    }\n                }\n                else if(CurrentState == XmlTokenType.SingleQuotationMarkStart)\n                {\n                    // check for empty attribute value\n                    if(subString[0] == '\\'')\n                    {\n                        CurrentState = XmlTokenType.SingleQuotationMarkEnd;\n                        token = \"\\'\";\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.AttributeValue;\n                        int n = subString.IndexOf(\"'\");\n                        token = subString.Substring(0, n);\n                    }\n                }\n                else if(CurrentState == XmlTokenType.CommentStart)\n                {\n                    // check for empty comment\n                    if(subString.StartsWith(\"-->\"))\n                    {\n                        CurrentState = XmlTokenType.CommentEnd;\n                        token = \"-->\";\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.CommentValue;\n                        token = ReadCommentValue(subString);\n                    }\n                }\n                else if(CurrentState == XmlTokenType.NodeStart)\n                {\n                    CurrentState = XmlTokenType.NodeName;\n                    token = ReadNodeName(subString);\n                }\n                else if(CurrentState == XmlTokenType.XmlDeclarationStart)\n                {\n                    CurrentState = XmlTokenType.NodeName;\n                    token = ReadNodeName(subString);\n                }\n                else if(CurrentState == XmlTokenType.NodeName)\n                {\n                    if(subString[0] != '/' &&\n                        subString[0] != '>')\n                    {\n                        CurrentState = XmlTokenType.AttributeName;\n                        token = ReadAttributeName(subString);\n                    }\n                    else\n                    {\n                        HandleReservedXmlToken();\n                    }\n                }\n                else if(CurrentState == XmlTokenType.NodeEndValueStart)\n                {\n                    if(subString[0] == '<')\n                    {\n                        HandleReservedXmlToken();\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.NodeValue;\n                        token = ReadNodeValue(subString);\n                    }\n                }\n                else if(CurrentState == XmlTokenType.DoubleQuotationMarkEnd)\n                {\n                    HandleAttributeEnd();\n                }\n                else if(CurrentState == XmlTokenType.SingleQuotationMarkEnd)\n                {\n                    HandleAttributeEnd();\n                }\n                else\n                {\n                    HandleReservedXmlToken();\n                }\n                if(token != string.Empty)\n                {\n                    ttype = CurrentState;\n                    return whitespace + token;\n                }\n                return string.Empty;\n            }\n\n            public Color GetTokenColor(XmlTokenType ttype)\n            {\n                switch(ttype)\n                {\n                    case XmlTokenType.NodeValue:\n                    case XmlTokenType.EqualSignStart:\n                    case XmlTokenType.EqualSignEnd:\n                    case XmlTokenType.DoubleQuotationMarkStart:\n                    case XmlTokenType.DoubleQuotationMarkEnd:\n                    case XmlTokenType.SingleQuotationMarkStart:\n                    case XmlTokenType.SingleQuotationMarkEnd:\n                        return Color.DimGray;\n                    case XmlTokenType.XmlDeclarationStart:\n                    case XmlTokenType.XmlDeclarationEnd:\n                    case XmlTokenType.NodeStart:\n                    case XmlTokenType.NodeEnd:\n                    case XmlTokenType.NodeEndValueStart:\n                    case XmlTokenType.CDataStart:\n                    case XmlTokenType.CDataEnd:\n                    case XmlTokenType.CommentStart:\n                    case XmlTokenType.CommentEnd:\n                    case XmlTokenType.AttributeValue:\n                    case XmlTokenType.DocTypeStart:\n                    case XmlTokenType.DocTypeEnd:\n                    case XmlTokenType.DocTypeDefStart:\n                    case XmlTokenType.DocTypeDefEnd:\n                        return Color.DimGray;\n                    case XmlTokenType.CDataValue:\n                    case XmlTokenType.DocTypeDefValue:\n                        return Color.SkyBlue;\n                    case XmlTokenType.CommentValue:\n                        return Color.SkyBlue;\n                    case XmlTokenType.DocTypeName:\n                    case XmlTokenType.NodeName:\n                        return Color.DarkCyan;\n                    case XmlTokenType.AttributeName:\n                    case XmlTokenType.DocTypeDeclaration:\n                        return Color.DodgerBlue;\n                    default:\n                        return Color.DimGray;\n                }\n            }\n\n            public string GetXmlDeclaration(string s)\n            {\n                int start = s.IndexOf(\"<?\");\n                int end = s.IndexOf(\"?>\");\n                if(start > -1 && end > start)\n                {\n                    return s.Substring(start, end - start + 2);\n                }\n                return string.Empty;\n            }\n\n            private void HandleAttributeEnd()\n            {\n                if(subString.StartsWith(\">\"))\n                {\n                    HandleReservedXmlToken();\n                }\n                else if(subString.StartsWith(\"/>\"))\n                {\n                    HandleReservedXmlToken();\n                }\n                else if(subString.StartsWith(\"?>\"))\n                {\n                    HandleReservedXmlToken();\n                }\n                else\n                {\n                    CurrentState = XmlTokenType.AttributeName;\n                    token = ReadAttributeName(subString);\n                }\n            }\n\n            private void HandleReservedXmlToken()\n            {\n                // check if state changer\n                // <, >, =, </, />, <![CDATA[, <!--, -->\n                if(subString.StartsWith(\"<![CDATA[\"))\n                {\n                    CurrentState = XmlTokenType.CDataStart;\n                    token = \"<![CDATA[\";\n                }\n                else if(subString.StartsWith(\"<!DOCTYPE\"))\n                {\n                    CurrentState = XmlTokenType.DocTypeStart;\n                    token = \"<!\";\n                }\n                else if(subString.StartsWith(\"</\"))\n                {\n                    CurrentState = XmlTokenType.NodeStart;\n                    token = \"</\";\n                }\n                else if(subString.StartsWith(\"<!--\"))\n                {\n                    CurrentState = XmlTokenType.CommentStart;\n                    token = \"<!--\";\n                }\n                else if(subString.StartsWith(\"<?\"))\n                {\n                    CurrentState = XmlTokenType.XmlDeclarationStart;\n                    token = \"<?\";\n                }\n                else if(subString.StartsWith(\"<\"))\n                {\n                    CurrentState = XmlTokenType.NodeStart;\n                    token = \"<\";\n                }\n                else if(subString.StartsWith(\"=\"))\n                {\n                    CurrentState = XmlTokenType.EqualSignStart;\n                    token = \"=\";\n                }\n                else if(subString.StartsWith(\"?>\"))\n                {\n                    CurrentState = XmlTokenType.XmlDeclarationEnd;\n                    token = \"?>\";\n                }\n                else if(subString.StartsWith(\">\"))\n                {\n                    CurrentState = XmlTokenType.NodeEndValueStart;\n                    token = \">\";\n                }\n                else if(subString.StartsWith(\"-->\"))\n                {\n                    CurrentState = XmlTokenType.CommentEnd;\n                    token = \"-->\";\n                }\n                else if(subString.StartsWith(\"]>\"))\n                {\n                    CurrentState = XmlTokenType.DocTypeEnd;\n                    token = \"]>\";\n                }\n                else if(subString.StartsWith(\"]]>\"))\n                {\n                    CurrentState = XmlTokenType.CDataEnd;\n                    token = \"]]>\";\n                }\n                else if(subString.StartsWith(\"/>\"))\n                {\n                    CurrentState = XmlTokenType.NodeEnd;\n                    token = \"/>\";\n                }\n                else if(subString.StartsWith(\"\\\"\"))\n                {\n                    if(CurrentState == XmlTokenType.AttributeValue)\n                    {\n                        CurrentState = XmlTokenType.DoubleQuotationMarkEnd;\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.DoubleQuotationMarkStart;\n                    }\n                    token = \"\\\"\";\n                }\n                else if(subString.StartsWith(\"'\"))\n                {\n                    if(CurrentState == XmlTokenType.AttributeValue)\n                    {\n                        CurrentState = XmlTokenType.SingleQuotationMarkEnd;\n                    }\n                    else\n                    {\n                        CurrentState = XmlTokenType.SingleQuotationMarkStart;\n                    }\n                    token = \"'\";\n                }\n            }\n\n            private string ReadNodeName(string s)\n            {\n                string nodeName = \"\";\n                for(int i = 0; i < s.Length; i++)\n                {\n                    if(s[i] == '/' || s[i] == ' ' || s[i] == '>') return nodeName;\n                    else nodeName += s[i].ToString();\n                }\n                return nodeName;\n            }\n\n            private string ReadAttributeName(string s)\n            {\n                string attName = \"\";\n                int n = s.IndexOf('=');\n                if(n != -1) attName = s.Substring(0, n);\n                return attName;\n            }\n\n            private string ReadNodeValue(string s)\n            {\n                string nodeValue = \"\";\n                int n = s.IndexOf('<');\n                if(n != -1) nodeValue = s.Substring(0, n);\n                return nodeValue;\n            }\n\n            private string ReadCommentValue(string s)\n            {\n                string commentValue = \"\";\n                int n = s.IndexOf(\"-->\");\n                if(n != -1) commentValue = s.Substring(0, n);\n                return commentValue;\n            }\n\n            private string GetWhitespace(string s)\n            {\n                string whitespace = \"\";\n                for(int i = 0; i < s.Length; i++)\n                {\n                    char c = s[i];\n                    if(char.IsWhiteSpace(c)) whitespace += c;\n                    else break;\n                }\n                return whitespace;\n            }\n        }\n\n        enum XmlTokenType\n        {\n            Whitespace, XmlDeclarationStart, XmlDeclarationEnd, NodeStart, NodeEnd, NodeEndValueStart, NodeName,\n            NodeValue, AttributeName, AttributeValue, EqualSignStart, EqualSignEnd, CommentStart, CommentValue,\n            CommentEnd, CDataStart, CDataValue, CDataEnd, DoubleQuotationMarkStart, DoubleQuotationMarkEnd,\n            SingleQuotationMarkStart, SingleQuotationMarkEnd, DocTypeStart, DocTypeName, DocTypeDeclaration,\n            DocTypeDefStart, DocTypeDefValue, DocTypeDefEnd, DocTypeEnd, DocumentEnd, Unknown\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ShellLink.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Runtime.InteropServices.ComTypes;\nusing System.Text;\nusing System.Windows.Forms;\nusing ComTypes = System.Runtime.InteropServices.ComTypes;\n\nnamespace BluePointLilac.Methods\n{\n    public class ShellLink : IDisposable\n    {\n        [ComImport]\n        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n        [Guid(\"000214F9-0000-0000-C000-000000000046\")]\n        interface IShellLinkW\n        {\n            void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, ref WIN32_FIND_DATAW pfd, uint fFlags);\n            void GetIDList(out IntPtr ppidl);\n            void SetIDList(IntPtr pidl);\n            void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);\n            void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);\n            void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);\n            void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);\n            void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);\n            void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);\n            void GetHotKey(out ushort pwHotkey);\n            void SetHotKey(ushort wHotKey);\n            void GetShowCmd(out int piShowCmd);\n            void SetShowCmd(int iShowCmd);\n            void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, int cchIconPath, out int piIcon);\n            void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);\n            void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, uint dwReserved);\n            void Resolve(IntPtr hwnd, uint fFlags);\n            void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);\n        }\n\n        [ComImport]\n        [ClassInterface(ClassInterfaceType.None)]\n        [Guid(\"00021401-0000-0000-C000-000000000046\")]\n        private class CShellLink { }\n\n        [ComImport]\n        [Guid(\"45e2b4ae-b1c3-11d0-b92f-00a0c90312e1\")]\n        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n        interface IShellLinkDataList\n        {\n            void AddDataBlock(IntPtr pDataBlock);\n            void CopyDataBlock(uint dwSig, out IntPtr ppDataBlock);\n            void RemoveDataBlock(uint dwSig);\n            void GetFlags(out ShellLinkDataFlags pdwFlags);\n            void SetFlags(ShellLinkDataFlags dwFlags);\n        }\n\n        [Flags]\n        enum ShellLinkDataFlags : uint\n        {\n            Default = 0x00000000,\n            HasIdList = 0x00000001,\n            HasLinkInfo = 0x00000002,\n            HasName = 0x00000004,\n            HasRelpath = 0x00000008,\n            HasWorkingdir = 0x00000010,\n            HasArgs = 0x00000020,\n            HasIconLocation = 0x00000040,\n            Unicode = 0x00000080,\n            ForceNoLinkInfo = 0x00000100,\n            HasExpSz = 0x00000200,\n            RunInSeparate = 0x00000400,\n            HasLogo3Id = 0x00000800,\n            HasDarwinId = 0x00001000,\n            RunasUser = 0x00002000,\n            HasExpIconSz = 0x00004000,\n            NoPidlAlias = 0x00008000,\n            ForceUncname = 0x00010000,\n            RunWithShimlayer = 0x00020000,\n            ForceNoLinktrack = 0x00040000,\n            EnableTargetMetadata = 0x00080000,\n            DisableLinkPathTracking = 0x00100000,\n            DisableKnownfolderRelativeTracking = 0x00200000,\n            NoKFAlias = 0x00400000,\n            AllowLinkToLink = 0x00800000,\n            UnaliasOnSave = 0x01000000,\n            PreferEnvironmentPath = 0x02000000,\n            KeepLocalIdListForUncTarget = 0x04000000,\n            Valid = 0x07fff7ff,\n            Reserved = 0x80000000\n        }\n\n        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Unicode)]\n        struct WIN32_FIND_DATAW\n        {\n            public uint dwFileAttributes;\n            public ComTypes.FILETIME ftCreationTime;\n            public ComTypes.FILETIME ftLastAccessTime;\n            public ComTypes.FILETIME ftLastWriteTime;\n            public uint nFileSizeHigh;\n            public uint nFileSizeLow;\n            public uint dwReserved0;\n            public uint dwReserved1;\n            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]\n            public string cFileName;\n            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]\n            public string cAlternateFileName;\n        }\n\n        public struct ICONLOCATION\n        {\n            public string IconPath;\n            public int IconIndex;\n        }\n\n        private const int MAX_PATH = 260;\n        private const int INFOTIPSIZE = 1024;\n\n        private const uint SLGP_UNCPRIORITY = 2;\n        private const int STGM_READWRITE = 2;\n\n        private const int SW_SHOWMAXIMIZED = 3;\n        private const int SW_SHOWMINIMIZED = 2;\n        private const int SW_SHOWMINNOACTIVE = 7;\n        private const int SW_SHOWNORMAL = 1;\n\n        private IShellLinkW shellLinkW = null;\n        private IPersistFile PersistFile => (IPersistFile)shellLinkW;\n        private IShellLinkDataList LinkDataList => (IShellLinkDataList)shellLinkW;\n\n        public string ShortcutPath { get; private set; }\n\n        public string TargetPath\n        {\n            get\n            {\n                StringBuilder targetPath = new StringBuilder(MAX_PATH);\n                WIN32_FIND_DATAW data = new WIN32_FIND_DATAW();\n                shellLinkW.GetPath(targetPath, targetPath.Capacity, ref data, SLGP_UNCPRIORITY);\n                return targetPath.ToString();\n            }\n            set\n            {\n                shellLinkW.SetPath(value);\n            }\n        }\n\n        public string Arguments\n        {\n            get\n            {\n                StringBuilder arguments = new StringBuilder(INFOTIPSIZE);\n                shellLinkW.GetArguments(arguments, arguments.Capacity);\n                return arguments.ToString();\n            }\n            set\n            {\n                shellLinkW.SetArguments(value);\n            }\n        }\n\n        public string WorkingDirectory\n        {\n            get\n            {\n                StringBuilder dirPath = new StringBuilder(MAX_PATH);\n                shellLinkW.GetWorkingDirectory(dirPath, dirPath.Capacity);\n                return dirPath.ToString();\n            }\n            set\n            {\n                shellLinkW.SetWorkingDirectory(value);\n            }\n        }\n\n        public ICONLOCATION IconLocation\n        {\n            get\n            {\n                StringBuilder iconPath = new StringBuilder(MAX_PATH);\n                shellLinkW.GetIconLocation(iconPath, iconPath.Capacity, out int iconIndex);\n                return new ICONLOCATION { IconPath = iconPath.ToString(), IconIndex = iconIndex };\n            }\n            set\n            {\n                shellLinkW.SetIconLocation(value.IconPath, value.IconIndex);\n            }\n        }\n\n        public string IconPath => IconLocation.IconPath;\n\n        public int IconIndex => IconLocation.IconIndex;\n\n        public string Description\n        {\n            get\n            {\n                StringBuilder description = new StringBuilder(INFOTIPSIZE);\n                shellLinkW.GetDescription(description, description.Capacity);\n                return description.ToString();\n            }\n            set\n            {\n                shellLinkW.SetDescription(value);\n            }\n        }\n\n        public Keys HotKey\n        {\n            get\n            {\n                shellLinkW.GetHotKey(out ushort key);\n                int hotKey = ((key & 0xFF00) << 8) | (key & 0xFF);\n                return (Keys)hotKey;\n            }\n            set\n            {\n                if((value & Keys.Modifiers) == 0) throw new ArgumentException(\"Hotkey must include a modifier key.\");\n                ushort key = unchecked((ushort)(((int)(value & Keys.Modifiers) >> 8) | (int)(value & Keys.KeyCode)));\n                shellLinkW.SetHotKey(key);\n            }\n        }\n\n        public FormWindowState WindowStyle\n        {\n            get\n            {\n                shellLinkW.GetShowCmd(out int style);\n                switch(style)\n                {\n                    case SW_SHOWMINIMIZED:\n                    case SW_SHOWMINNOACTIVE:\n                        return FormWindowState.Minimized;\n                    case SW_SHOWMAXIMIZED:\n                        return FormWindowState.Maximized;\n                    case SW_SHOWNORMAL:\n                    default:\n                        return FormWindowState.Normal;\n                }\n            }\n            set\n            {\n                int style;\n                switch(value)\n                {\n                    case FormWindowState.Minimized:\n                        style = SW_SHOWMINIMIZED; break;\n                    case FormWindowState.Maximized:\n                        style = SW_SHOWMAXIMIZED; break;\n                    case FormWindowState.Normal:\n                    default:\n                        style = SW_SHOWNORMAL; break;\n                }\n                shellLinkW.SetShowCmd(style);\n            }\n        }\n\n        public bool RunAsAdministrator\n        {\n            get\n            {\n                LinkDataList.GetFlags(out ShellLinkDataFlags flags);\n                return (flags & ShellLinkDataFlags.RunasUser) == ShellLinkDataFlags.RunasUser;\n            }\n            set\n            {\n                LinkDataList.GetFlags(out ShellLinkDataFlags flags);\n                if(value) flags |= ShellLinkDataFlags.RunasUser;\n                else flags &= ~ShellLinkDataFlags.RunasUser;\n                LinkDataList.SetFlags(flags);\n            }\n        }\n\n        public ShellLink(string lnkPath = null)\n        {\n            try { shellLinkW = (IShellLinkW)new CShellLink(); }\n            catch { throw new COMException(\"Failed to create ShellLink object.\"); }\n            Load(lnkPath);\n        }\n\n        ~ShellLink() { Dispose(false); }\n\n        public void Dispose()\n        {\n            Dispose(true);\n            GC.SuppressFinalize(this);\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if(shellLinkW == null) return;\n            Marshal.FinalReleaseComObject(shellLinkW);\n            shellLinkW = null;\n        }\n\n        public void Save() { Save(this.ShortcutPath); }\n\n        public void Save(string lnkPath)\n        {\n            PersistFile.Save(lnkPath, true);\n        }\n\n        public void Load() { Load(this.ShortcutPath); }\n\n        public void Load(string lnkPath)\n        {\n            this.ShortcutPath = lnkPath;\n            if(File.Exists(lnkPath)) PersistFile.Load(lnkPath, STGM_READWRITE);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class SingleInstance\n    {\n        [DllImport(\"user32.dll\")]\n        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);\n\n        [DllImport(\"user32.dll\")]\n        private static extern bool SetForegroundWindow(IntPtr hWnd);\n\n        /// <summary>判断单实例程序是否正在运行</summary>\n        /// <remarks>若正在运行激活窗口</remarks>\n        public static bool IsRunning()\n        {\n            using(Process current = Process.GetCurrentProcess())\n            {\n                foreach(Process process in Process.GetProcessesByName(current.ProcessName))\n                {\n                    using(process)\n                    {\n                        if(process.Id == current.Id) continue;\n                        if(process.MainModule.FileName == current.MainModule.FileName)\n                        {\n                            const int SW_RESTORE = 9;\n                            ShowWindowAsync(process.MainWindowHandle, SW_RESTORE);\n                            SetForegroundWindow(process.MainWindowHandle);\n                            return true;\n                        }\n                    }\n                }\n                return false;\n            }\n        }\n\n        /// <summary>重启单实例程序</summary>\n        /// <param name=\"args\">重启程序时传入参数</param>\n        /// <param name=\"updatePath\">用于更新程序的新版本文件路径，为null则为普通重启</param>\n        public static void Restart(string[] args = null, string updatePath = null)\n        {\n            string appPath = Application.ExecutablePath;\n            string command = appPath;\n            if(args != null && args.Length > 0) command += \",\" + string.Join(\" \", args);\n            List<string> contents = new List<string>();\n            //vbs命令逐行执行不等待，故加些代码确定上一条命令执行是否完成\n            contents.AddRange(new[]\n            {\n                \"On Error Resume Next\",\n                \"WScript.Sleep 1000\",//等待程序结束\n                \"Dim wsh, fso\",\n                \"Set wsh = CreateObject(\\\"WScript.Shell\\\")\",\n                \"Set fso = CreateObject(\\\"Scripting.FileSystemObject\\\")\",\n            });\n\n            if(File.Exists(updatePath))\n            {\n                contents.AddRange(new[]\n                {\n                    $\"fso.DeleteFile \\\"{appPath}\\\"\",\n                    $\"Do While fso.FileExists(\\\"{appPath}\\\")\",\n                        \"WScript.Sleep 100\",\n                    \"Loop\",//确定文件删除完成\n                    $\"fso.MoveFile \\\"{updatePath}\\\",\\\"{appPath}\\\"\",//更新文件\n                    $\"Do While fso.FileExists(\\\"{updatePath}\\\")\",//确定文件已被移动\n                        \"WScript.Sleep 100\",\n                    $\"Loop\",\n                });\n            }\n            contents.AddRange(new[]\n            {\n                $\"wsh.Run \\\"{command}\\\"\",\n                \"fso.DeleteFile(WScript.ScriptFullName)\",//vbs自删命令\n                \"Set wsh = Nothing\",\n                \"Set fso = Nothing\",\n            });\n\n            string vbsPath = Path.GetTempPath() + Guid.NewGuid() + \".vbs\";\n            File.WriteAllLines(vbsPath, contents.ToArray(), Encoding.Unicode);\n            Application.Exit();\n            using(Process process = new Process())\n            {\n                process.StartInfo.FileName = \"wscript.exe\";\n                process.StartInfo.Arguments = vbsPath;\n                process.Start();\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/StringExtension.cs",
    "content": "﻿namespace BluePointLilac.Methods\n{\n    //为兼容.Net Framework 3.5，无法引用Microsoft.CSharp.dll（中的string.IsNullOrWhiteSpace）写了这个扩展方法\n    public static class StringExtension\n    {\n        public static bool IsNullOrWhiteSpace(this string str)\n        {\n            if(string.IsNullOrEmpty(str)) return true;\n            return str.Trim().Length == 0;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/TextBoxExtension.cs",
    "content": "﻿using System.Drawing;\nusing System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class TextBoxExtension\n    {\n        /// <summary>TextBox仿RichTextBox按住Ctrl加鼠标滚轮放缩字体</summary>\n        public static void CanResizeFont(this TextBox box)\n        {\n            box.MouseWheel += (sender, e) =>\n            {\n                if(Control.ModifierKeys != Keys.Control) return;\n                float size = box.Font.Size;\n                if(size < 8F && e.Delta < 0) return;\n                if(size > 40F && e.Delta > 0) return;\n                box.Font = new Font(box.Font.FontFamily, size + (e.Delta > 0 ? 1F : -1F));\n            };\n        }\n\n        /// <summary>TextBox在文字未超出边界时隐藏滚动条，超出时显示</summary>\n        public static void SetAutoShowScroll(this TextBox box, ScrollBars scrollBars)\n        {\n\n            void SetScrollVisible()\n            {\n                Size szBox = box.ClientSize;\n                Size szText = TextRenderer.MeasureText(box.Text, box.Font);\n                if((scrollBars | ScrollBars.Vertical) == ScrollBars.Vertical)\n                {\n                    if(szText.Height > szBox.Height)\n                    {\n                        box.ScrollBars = scrollBars | ScrollBars.Vertical;\n                    }\n                    else\n                    {\n                        box.ScrollBars = scrollBars & ~ScrollBars.Vertical;\n                    }\n                }\n                if((scrollBars | ScrollBars.Horizontal) == ScrollBars.Horizontal)\n                {\n                    if(szText.Width > szBox.Width)\n                    {\n                        box.ScrollBars = scrollBars | ScrollBars.Horizontal;\n                    }\n                    else\n                    {\n                        box.ScrollBars = scrollBars & ~ScrollBars.Horizontal;\n                    }\n                }\n            };\n            box.TextChanged += (sender, e) => SetScrollVisible();\n            box.FontChanged += (sender, e) => SetScrollVisible();\n            box.ClientSizeChanged += (sender, e) => SetScrollVisible();\n        }\n\n        /// <summary>TextBox只读时可以使用Ctrl+A全选快捷键</summary>\n        public static void CanSelectAllWhenReadOnly(this TextBox box)\n        {\n            box.KeyDown += (sender, e) =>\n            {\n                if(box.ReadOnly && e.Control && e.KeyCode == Keys.A) box.SelectAll();\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/ToolTipBox.cs",
    "content": "﻿using System.Windows.Forms;\n\nnamespace BluePointLilac.Methods\n{\n    public static class ToolTipBox\n    {\n        public static void SetToolTip(Control ctr, string tip)\n        {\n            if(tip.IsNullOrWhiteSpace()) return;\n            ToolTip toolTip = new ToolTip { InitialDelay = 1 };\n            toolTip.SetToolTip(ctr, tip);\n            ctr.Disposed += (sender, e) => toolTip.Dispose();\n        }\n\n        public static void SetToolTip(ToolStripItem item, string tip)\n        {\n            //必须先设置item的Owner\n            item.Owner.ShowItemToolTips = true;\n            item.ToolTipText = tip;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/BluePointLilac.Methods/WinOsVersion.cs",
    "content": "﻿using System;\n\nnamespace BluePointLilac.Methods\n{\n    // 判断Windows系统版本\n    // https://docs.microsoft.com/windows/release-health/release-information\n    public static class WinOsVersion\n    {\n        public static readonly Version Current = Environment.OSVersion.Version;\n        public static readonly Version Win10 = new Version(10, 0);\n        public static readonly Version Win8_1 = new Version(6, 3);\n        public static readonly Version Win8 = new Version(6, 2);\n        public static readonly Version Win7 = new Version(6, 1);\n        public static readonly Version Vista = new Version(6, 0);\n        public static readonly Version XP = new Version(5, 1);\n\n        public static readonly Version Win10_1507 = new Version(10, 0, 10240);\n        public static readonly Version Win10_1511 = new Version(10, 0, 10586);\n        public static readonly Version Win10_1607 = new Version(10, 0, 14393);\n        public static readonly Version Win10_1703 = new Version(10, 0, 15063);\n        public static readonly Version Win10_1709 = new Version(10, 0, 16299);\n        public static readonly Version Win10_1803 = new Version(10, 0, 17134);\n        public static readonly Version Win10_1809 = new Version(10, 0, 17763);\n        public static readonly Version Win10_1903 = new Version(10, 0, 18362);\n        public static readonly Version Win10_1909 = new Version(10, 0, 18363);\n        public static readonly Version Win10_2004 = new Version(10, 0, 19041);\n        public static readonly Version Win10_20H2 = new Version(10, 0, 19042);\n    }\n}"
  },
  {
    "path": "ContextMenuManager/ContextMenuManager.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}</ProjectGuid>\n    <OutputType>WinExe</OutputType>\n    <RootNamespace>ContextMenuManager</RootNamespace>\n    <AssemblyName>ContextMenuManager</AssemblyName>\n    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n    <Deterministic>true</Deterministic>\n    <IsWebBootstrapper>false</IsWebBootstrapper>\n    <TargetFrameworkProfile />\n    <PublishUrl>C:\\Users\\Lilac\\Desktop\\</PublishUrl>\n    <Install>true</Install>\n    <InstallFrom>Disk</InstallFrom>\n    <UpdateEnabled>false</UpdateEnabled>\n    <UpdateMode>Foreground</UpdateMode>\n    <UpdateInterval>7</UpdateInterval>\n    <UpdateIntervalUnits>Days</UpdateIntervalUnits>\n    <UpdatePeriodically>false</UpdatePeriodically>\n    <UpdateRequired>false</UpdateRequired>\n    <MapFileExtensions>true</MapFileExtensions>\n    <ApplicationRevision>0</ApplicationRevision>\n    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>\n    <UseApplicationTrust>false</UseApplicationTrust>\n    <PublishWizardCompleted>true</PublishWizardCompleted>\n    <BootstrapperEnabled>true</BootstrapperEnabled>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>send</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n    <AllowUnsafeBlocks>false</AllowUnsafeBlocks>\n    <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>\n    <DocumentationFile>\n    </DocumentationFile>\n    <FileAlignment>4096</FileAlignment>\n    <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>\n    <TreatWarningsAsErrors>false</TreatWarningsAsErrors>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>none</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n    <Prefer32Bit>false</Prefer32Bit>\n    <FileAlignment>4096</FileAlignment>\n    <DebugSymbols>false</DebugSymbols>\n    <GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ApplicationIcon>Properties\\AppIcon.ico</ApplicationIcon>\n  </PropertyGroup>\n  <PropertyGroup>\n    <TargetZone>Custom</TargetZone>\n  </PropertyGroup>\n  <PropertyGroup>\n    <GenerateManifests>false</GenerateManifests>\n  </PropertyGroup>\n  <PropertyGroup />\n  <PropertyGroup>\n    <SignManifests>false</SignManifests>\n  </PropertyGroup>\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup>\n    <Win32Resource>\n    </Win32Resource>\n  </PropertyGroup>\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup>\n    <StartupObject>ContextMenuManager.Program</StartupObject>\n  </PropertyGroup>\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup>\n    <ManifestCertificateThumbprint>BEFE3AE42DB8F7604D715C01388001CABFF0FABF</ManifestCertificateThumbprint>\n  </PropertyGroup>\n  <PropertyGroup>\n    <ManifestKeyFile>ContextMenuManager_TemporaryKey.pfx</ManifestKeyFile>\n  </PropertyGroup>\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup />\n  <PropertyGroup>\n    <ApplicationManifest>Properties\\App.manifest</ApplicationManifest>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"PresentationFramework\" />\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"System.Deployment\" />\n    <Reference Include=\"System.Drawing\" />\n    <Reference Include=\"System.Management\" />\n    <Reference Include=\"System.Runtime.Serialization\" />\n    <Reference Include=\"System.ServiceModel.Web\" />\n    <Reference Include=\"System.Web\" />\n    <Reference Include=\"System.Windows.Forms\" />\n    <Reference Include=\"System.Xml\" />\n    <Reference Include=\"System.Xml.Linq\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"Controls\\DetailedEditDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\DictionariesBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\DonateBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\EnhanceMenusDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\IBtnDeleteItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\LanguagesBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\SubItemsForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\SwitchDicList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Methods\\AppConfig.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\FormExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\MessageBoxEx.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ToolTipBox.cs\" />\n    <Compile Include=\"BluePointLilac.Controls\\ReadOnlyTextBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\ResizeLimitedForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\MyToolBar.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Methods\\ComboBoxExtension.cs\" />\n    <Compile Include=\"Methods\\DesktopIni.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\DirectoryEx.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ElevatedFileDroper.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\FileExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\GuidEx.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\IniReader.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\IniWriter.cs\" />\n    <Compile Include=\"Methods\\AppMessageBox.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ExternalProgram.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\RichTextBoxExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\SingleInstance.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\StringExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\TextBoxExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Controls\\UAWebClient.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Methods\\UwpHelper.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\WinOsVersion.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ShellLink.cs\" />\n    <Compile Include=\"Methods\\WinXHasher.cs\" />\n    <Compile Include=\"BluePointLilac.Controls\\DownloadDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\FileExtensionDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\EnhanceMenusItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\EnhanceMenusList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\IEItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\IEList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\IBtnMoveUpDownItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\IProtectOpenItem.cs\" />\n    <Compile Include=\"Controls\\Interfaces\\ITsiAdministratorItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiGuidItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiShortcutCommandItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiRegExportItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\NewIEDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\NewLnkFileDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\SelectDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellExecuteDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellStoreDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\FoldSubItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiDeleteItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiCommandItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiFilePathItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiIconItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiTextItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiRegPathItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\IBtnShowMenuItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\IChkVisibleItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\Interfaces\\ITsiWebSearchItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\NewItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\NewItemForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\AppSettingBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\GuidBlockedItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\GuidBlockedList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\NewOpenWithDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\NewShellDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\OpenWithList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\RuleItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\OpenWithItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ExplorerRestarter.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\SendToItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\SendToList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellNewItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellNewList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\DetailedEditList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\UwpModeItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\WinXGroupItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\WinXItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\WinXList.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"MainForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\IconDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\InputDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\MyCheckBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\MyListBox.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\MyMainForm.cs\">\n      <SubType>Form</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\MySideBar.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\MyStatusBar.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellSubMenuDialog.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Controls\\PictureButton.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellExItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"Controls\\ShellItem.cs\">\n      <SubType>Component</SubType>\n    </Compile>\n    <Compile Include=\"BluePointLilac.Methods\\ControlExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\HighDpi.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\RegistryEx.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\RegTrustedInstaller.cs\" />\n    <Compile Include=\"Methods\\AppString.cs\" />\n    <Compile Include=\"Methods\\AppImage.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\EncodingType.cs\" />\n    <Compile Include=\"Methods\\GuidInfo.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ImageExtension.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ResourceIcon.cs\" />\n    <Compile Include=\"BluePointLilac.Methods\\ResourceString.cs\" />\n    <Compile Include=\"Methods\\ObjectPath.cs\" />\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\Resources.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DesignTime>True</DesignTime>\n      <DependentUpon>Resources.resx</DependentUpon>\n    </Compile>\n    <Compile Include=\"Methods\\Updater.cs\" />\n    <Compile Include=\"Methods\\XmlDicHelper.cs\" />\n    <None Include=\"App.config\" />\n    <None Include=\"Properties\\App.manifest\" />\n    <None Include=\"Properties\\Resources\\ShellNew\\0.rar\" />\n    <None Include=\"Properties\\Resources\\ShellNew\\0.reg\" />\n    <None Include=\"Properties\\Resources\\ShellNew\\0.rtf\" />\n    <None Include=\"Properties\\Resources\\ShellNew\\0.xlsx\" />\n    <None Include=\"Properties\\Resources\\ShellNew\\0.zip\" />\n    <None Include=\"Properties\\Resources\\Texts\\AppLanguageDic.ini\" />\n    <None Include=\"Properties\\Resources\\Texts\\GuidInfosDic.ini\" />\n    <Content Include=\"Properties\\Resources\\Images\\CheckUpdate.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\DownLoad.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Enhance.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Jump.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Translate.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\User.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Web.png\" />\n    <Content Include=\"Properties\\Resources\\ShellNew\\0.c\" />\n    <Content Include=\"Properties\\Resources\\ShellNew\\0.html\" />\n    <Content Include=\"Properties\\Resources\\ShellNew\\0.xml\" />\n    <Content Include=\"Properties\\Resources\\Texts\\UwpModeItemsDic.xml\" />\n    <None Include=\"Properties\\Settings.settings\">\n      <Generator>SettingsSingleFileGenerator</Generator>\n      <LastGenOutput>Settings.Designer.cs</LastGenOutput>\n    </None>\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"Properties\\Settings.Designer.cs\">\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Settings.settings</DependentUpon>\n      <DesignTimeSharedInput>True</DesignTimeSharedInput>\n    </Compile>\n  </ItemGroup>\n  <ItemGroup>\n    <BootstrapperPackage Include=\".NETFramework,Version=v4.6\">\n      <Visible>False</Visible>\n      <ProductName>Microsoft .NET Framework 4.6 %28x86 和 x64%29</ProductName>\n      <Install>true</Install>\n    </BootstrapperPackage>\n    <BootstrapperPackage Include=\"Microsoft.Net.Framework.3.5.SP1\">\n      <Visible>False</Visible>\n      <ProductName>.NET Framework 3.5 SP1</ProductName>\n      <Install>false</Install>\n    </BootstrapperPackage>\n  </ItemGroup>\n  <ItemGroup>\n    <Content Include=\"Properties\\AppIcon.ico\" />\n    <Content Include=\"Properties\\Resources\\Images\\Custom.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\NewFolder.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Refresh.png\" />\n    <Content Include=\"Properties\\Resources\\Texts\\EnhanceMenusDic.xml\" />\n    <Content Include=\"Properties\\Resources\\Images\\About.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Add.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\AddExisting.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\AddSeparator.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Delete.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Home.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\MicrosoftStore.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\NewItem.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Open.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Setting.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Star.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\SubItems.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Type.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Up.png\" />\n    <Content Include=\"Properties\\Resources\\Images\\Donate.png\" />\n    <Content Include=\"Properties\\Resources\\Texts\\DetailedEditDic.xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <EmbeddedResource Include=\"Properties\\Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n  </ItemGroup>\n  <ItemGroup />\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <PropertyGroup>\n    <PreBuildEvent>\n    </PreBuildEvent>\n  </PropertyGroup>\n  <PropertyGroup>\n    <PostBuildEvent>mkdir $(TargetDir)\\Config\\Languages\nmkdir $(TargetDir)\\Config\\Dictionaries\\Web\nxcopy $(ProjectDir)\\Properties\\Resources\\Texts\\AppLanguageDic.ini $(SolutionDir)\\Languages\\zh-CN.ini /y\nxcopy $(SolutionDir)\\Languages $(TargetDir)\\config\\Languages /y\nxcopy $(ProjectDir)\\Properties\\Resources\\Texts $(TargetDir)\\Config\\Dictionaries\\Web /y\ndel $(TargetDir)\\Config\\Dictionaries\\Web\\AppLanguageDic.ini</PostBuildEvent>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "ContextMenuManager/Controls/AppSettingBox.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nusing System.IO;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class AppSettingBox : MyList\n    {\n        public AppSettingBox()\n        {\n            this.SuspendLayout();\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n            mliConfigDir.AddCtrs(new Control[] { cmbConfigDir, btnConfigDir });\n            mliBackup.AddCtrs(new Control[] { chkBackup, btnBackupDir });\n            mliUpdate.AddCtrs(new Control[] { cmbUpdate, btnUpdate });\n            mliRepo.AddCtr(cmbRepo);\n            mliTopMost.AddCtr(chkTopMost);\n            mliProtect.AddCtr(chkProtect);\n            mliEngine.AddCtr(cmbEngine);\n            mliWinXSortable.AddCtr(chkWinXSortable);\n            mliShowFilePath.AddCtr(chkShowFilePath);\n            mliOpenMoreRegedit.AddCtr(chkOpenMoreRegedit);\n            mliOpenMoreExplorer.AddCtr(chkOpenMoreExplorer);\n            mliHideDisabledItems.AddCtr(chkHideDisabledItems);\n            mliHideSysStoreItems.AddCtr(chkHideSysStoreItems);\n\n            ToolTipBox.SetToolTip(btnUpdate, AppString.Tip.ImmediatelyCheck);\n            ToolTipBox.SetToolTip(cmbConfigDir, AppString.Tip.ConfigPath);\n            ToolTipBox.SetToolTip(btnConfigDir, AppString.Menu.FileLocation);\n            ToolTipBox.SetToolTip(btnBackupDir, AppString.Menu.FileLocation);\n\n            cmbRepo.Items.AddRange(new[] { \"Github\", \"Gitee\" });\n            cmbConfigDir.Items.AddRange(new[] { AppString.Other.AppDataDir, AppString.Other.AppDir });\n            cmbEngine.Items.AddRange(AppConfig.EngineUrlsDic.Keys.ToArray());\n            cmbEngine.Items.Add(AppString.Other.CustomEngine);\n            cmbUpdate.Items.AddRange(new[] { AppString.Other.OnceAWeek, AppString.Other.OnceAMonth,\n                AppString.Other.OnceASeason, AppString.Other.NeverCheck });\n\n            cmbConfigDir.Width = cmbEngine.Width = cmbUpdate.Width = cmbRepo.Width = 120.DpiZoom();\n            cmbConfigDir.DropDownStyle = cmbEngine.DropDownStyle = cmbUpdate.DropDownStyle\n                = cmbRepo.DropDownStyle = ComboBoxStyle.DropDownList;\n            cmbConfigDir.AutosizeDropDownWidth();\n            cmbEngine.AutosizeDropDownWidth();\n            cmbUpdate.AutosizeDropDownWidth();\n            cmbRepo.AutosizeDropDownWidth();\n\n            btnUpdate.MouseDown += (sender, e) =>\n            {\n                this.Cursor = Cursors.WaitCursor;\n                Updater.Update(true);\n                this.Cursor = Cursors.Default;\n            };\n            btnConfigDir.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(AppConfig.ConfigDir);\n            btnBackupDir.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(AppConfig.BackupDir);\n            chkBackup.CheckChanged += () => AppConfig.AutoBackup = chkBackup.Checked;\n            chkProtect.CheckChanged += () => AppConfig.ProtectOpenItem = chkProtect.Checked;\n            chkWinXSortable.CheckChanged += () => AppConfig.WinXSortable = chkWinXSortable.Checked;\n            chkOpenMoreRegedit.CheckChanged += () => AppConfig.OpenMoreRegedit = chkOpenMoreRegedit.Checked;\n            chkTopMost.CheckChanged += () => AppConfig.TopMost = this.FindForm().TopMost = chkTopMost.Checked;\n            chkOpenMoreExplorer.CheckChanged += () => AppConfig.OpenMoreExplorer = chkOpenMoreExplorer.Checked;\n            chkHideDisabledItems.CheckChanged += () => AppConfig.HideDisabledItems = chkHideDisabledItems.Checked;\n            chkHideSysStoreItems.CheckChanged += () => AppConfig.HideSysStoreItems = chkHideSysStoreItems.Checked;\n            cmbRepo.SelectionChangeCommitted += (sender, e) => AppConfig.RequestUseGithub = cmbRepo.SelectedIndex == 0;\n            chkShowFilePath.CheckChanged += () => AppConfig.ShowFilePath = chkShowFilePath.Checked;\n            cmbUpdate.SelectionChangeCommitted += (sender, e) => ChangeUpdateFrequency();\n            cmbConfigDir.SelectionChangeCommitted += (sender, e) => ChangeConfigDir();\n            cmbEngine.SelectionChangeCommitted += (sender, e) => ChangeEngineUrl();\n            this.ResumeLayout();\n        }\n\n        readonly MyListItem mliConfigDir = new MyListItem\n        {\n            Text = AppString.Other.ConfigPath\n        };\n        readonly ComboBox cmbConfigDir = new ComboBox();\n        readonly PictureButton btnConfigDir = new PictureButton(AppImage.Open);\n\n        readonly MyListItem mliRepo = new MyListItem\n        {\n            Text = AppString.Other.SetRequestRepo\n        };\n        readonly ComboBox cmbRepo = new ComboBox();\n\n        readonly MyListItem mliBackup = new MyListItem\n        {\n            Text = AppString.Other.AutoBackup\n        };\n        readonly MyCheckBox chkBackup = new MyCheckBox();\n        readonly PictureButton btnBackupDir = new PictureButton(AppImage.Open);\n\n        readonly MyListItem mliUpdate = new MyListItem\n        {\n            Text = AppString.Other.SetUpdateFrequency\n        };\n        readonly ComboBox cmbUpdate = new ComboBox();\n        readonly PictureButton btnUpdate = new PictureButton(AppImage.CheckUpdate);\n\n        readonly MyListItem mliTopMost = new MyListItem\n        {\n            Text = AppString.Other.TopMost\n        };\n        readonly MyCheckBox chkTopMost = new MyCheckBox();\n\n        readonly MyListItem mliProtect = new MyListItem\n        {\n            Text = AppString.Other.ProtectOpenItem\n        };\n        readonly MyCheckBox chkProtect = new MyCheckBox();\n\n        readonly MyListItem mliEngine = new MyListItem\n        {\n            Text = AppString.Other.WebSearchEngine\n        };\n        readonly ComboBox cmbEngine = new ComboBox();\n\n        readonly MyListItem mliShowFilePath = new MyListItem\n        {\n            Text = AppString.Other.ShowFilePath\n        };\n        readonly MyCheckBox chkShowFilePath = new MyCheckBox();\n\n        readonly MyListItem mliOpenMoreRegedit = new MyListItem\n        {\n            Text = AppString.Other.OpenMoreRegedit\n        };\n        readonly MyCheckBox chkOpenMoreRegedit = new MyCheckBox();\n\n        readonly MyListItem mliOpenMoreExplorer = new MyListItem\n        {\n            Text = AppString.Other.OpenMoreExplorer\n        };\n        readonly MyCheckBox chkOpenMoreExplorer = new MyCheckBox();\n\n        readonly MyListItem mliHideDisabledItems = new MyListItem\n        {\n            Text = AppString.Other.HideDisabledItems\n        };\n        readonly MyCheckBox chkHideDisabledItems = new MyCheckBox();\n\n        readonly MyListItem mliWinXSortable = new MyListItem\n        {\n            Text = AppString.Other.WinXSortable,\n            Visible = WinOsVersion.Current >= WinOsVersion.Win8\n        };\n        readonly MyCheckBox chkWinXSortable = new MyCheckBox();\n\n        readonly MyListItem mliHideSysStoreItems = new MyListItem\n        {\n            Text = AppString.Other.HideSysStoreItems,\n            Visible = WinOsVersion.Current >= WinOsVersion.Win7\n        };\n        readonly MyCheckBox chkHideSysStoreItems = new MyCheckBox();\n\n        public override void ClearItems()\n        {\n            this.Controls.Clear();\n        }\n\n        public void LoadItems()\n        {\n            this.AddItems(new[] { mliConfigDir, mliUpdate, mliRepo, mliEngine, mliBackup, mliTopMost, mliProtect, mliShowFilePath,\n                mliHideDisabledItems, mliHideSysStoreItems, mliOpenMoreRegedit, mliOpenMoreExplorer, mliWinXSortable });\n            foreach(MyListItem item in this.Controls) item.HasImage = false;\n            cmbConfigDir.SelectedIndex = AppConfig.SaveToAppDir ? 1 : 0;\n            cmbRepo.SelectedIndex = AppConfig.RequestUseGithub ? 0 : 1;\n            cmbUpdate.SelectedIndex = GetUpdateSelectIndex();\n            cmbEngine.SelectedIndex = GetEngineSelectIndex();\n            chkBackup.Checked = AppConfig.AutoBackup;\n            chkTopMost.Checked = this.FindForm().TopMost;\n            chkProtect.Checked = AppConfig.ProtectOpenItem;\n            chkWinXSortable.Checked = AppConfig.WinXSortable;\n            chkShowFilePath.Checked = AppConfig.ShowFilePath;\n            chkOpenMoreRegedit.Checked = AppConfig.OpenMoreRegedit;\n            chkOpenMoreExplorer.Checked = AppConfig.OpenMoreExplorer;\n            chkHideDisabledItems.Checked = AppConfig.HideDisabledItems;\n            chkHideSysStoreItems.Checked = AppConfig.HideSysStoreItems;\n        }\n\n        private void ChangeConfigDir()\n        {\n            string newPath = (cmbConfigDir.SelectedIndex == 0) ? AppConfig.AppDataConfigDir : AppConfig.AppConfigDir;\n            if(newPath == AppConfig.ConfigDir) return;\n            if(AppMessageBox.Show(AppString.Message.RestartApp, MessageBoxButtons.OKCancel) != DialogResult.OK)\n            {\n                cmbConfigDir.SelectedIndex = AppConfig.SaveToAppDir ? 1 : 0;\n            }\n            else\n            {\n                DirectoryEx.CopyTo(AppConfig.ConfigDir, newPath);\n                Directory.Delete(AppConfig.ConfigDir, true);\n                SingleInstance.Restart();\n            }\n        }\n\n        private void ChangeEngineUrl()\n        {\n            if(cmbEngine.SelectedIndex < cmbEngine.Items.Count - 1)\n            {\n                AppConfig.EngineUrl = AppConfig.EngineUrlsDic[cmbEngine.Text];\n            }\n            else\n            {\n                using(InputDialog dlg = new InputDialog())\n                {\n                    dlg.Text = AppConfig.EngineUrl;\n                    dlg.Title = AppString.Other.SetCustomEngine;\n                    if(dlg.ShowDialog() == DialogResult.OK) AppConfig.EngineUrl = dlg.Text;\n                    cmbEngine.SelectedIndex = GetEngineSelectIndex();\n                }\n            }\n        }\n\n        private void ChangeUpdateFrequency()\n        {\n            int day = 30;\n            switch(cmbUpdate.SelectedIndex)\n            {\n                case 0:\n                    day = 7; break;\n                case 2:\n                    day = 90; break;\n                case 3:\n                    day = -1; break;\n            }\n            AppConfig.UpdateFrequency = day;\n        }\n\n        private int GetUpdateSelectIndex()\n        {\n            int index = 1;\n            switch(AppConfig.UpdateFrequency)\n            {\n                case 7:\n                    index = 0; break;\n                case 90:\n                    index = 2; break;\n                case -1:\n                    index = 3; break;\n            }\n            return index;\n        }\n\n        private int GetEngineSelectIndex()\n        {\n            string[] urls = AppConfig.EngineUrlsDic.Values.ToArray();\n            for(int i = 0; i < urls.Length; i++)\n            {\n                if(AppConfig.EngineUrl.Equals(urls[i])) return i;\n            }\n            return cmbEngine.Items.Count - 1;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/DetailedEditDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class DetailedEditDialog : CommonDialog\n    {\n        public Guid GroupGuid { get; set; }\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(SubItemsForm frm = new SubItemsForm())\n            using(DetailedEditList list = new DetailedEditList())\n            {\n                var location = GuidInfo.GetIconLocation(this.GroupGuid);\n                frm.Icon = ResourceIcon.GetIcon(location.IconPath, location.IconIndex);\n                frm.Text = AppString.Dialog.DetailedEdit.Replace(\"%s\", GuidInfo.GetText(this.GroupGuid));\n                frm.TopMost = AppConfig.TopMost;\n                frm.AddList(list);\n                list.GroupGuid = this.GroupGuid;\n                list.UseUserDic = XmlDicHelper.DetailedEditGuidDic[this.GroupGuid];\n                list.LoadItems();\n                frm.ShowDialog();\n            }\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/DetailedEditList.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\nusing System.Xml;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class DetailedEditList : SwitchDicList\n    {\n        public Guid GroupGuid { get; set; }\n\n        public override void LoadItems()\n        {\n            base.LoadItems();\n            int index = this.UseUserDic ? 1 : 0;\n            XmlDocument doc = XmlDicHelper.DetailedEditDic[index];\n            if(doc?.DocumentElement == null) return;\n            foreach(XmlNode groupXN in doc.DocumentElement.ChildNodes)\n            {\n                try\n                {\n                    List<Guid> guids = new List<Guid>();\n                    XmlNodeList guidList = groupXN.SelectNodes(\"Guid\");\n                    foreach(XmlNode guidXN in guidList)\n                    {\n                        if(!GuidEx.TryParse(guidXN.InnerText, out Guid guid)) continue;\n                        if(!File.Exists(GuidInfo.GetFilePath(guid))) continue;\n                        if(this.GroupGuid != Guid.Empty && this.GroupGuid != guid) continue;\n                        guids.Add(guid);\n                    }\n                    if(guidList.Count > 0 && guids.Count == 0) continue;\n\n                    FoldGroupItem groupItem;\n                    bool isIniGroup = groupXN.SelectSingleNode(\"IsIniGroup\") != null;\n                    string attribute = isIniGroup ? \"FilePath\" : \"RegPath\";\n                    ObjectPath.PathType pathType = isIniGroup ? ObjectPath.PathType.File : ObjectPath.PathType.Registry;\n                    groupItem = new FoldGroupItem(groupXN.SelectSingleNode(attribute)?.InnerText, pathType);\n                    foreach(XmlElement textXE in groupXN.SelectNodes(\"Text\"))\n                    {\n                        if(XmlDicHelper.JudgeCulture(textXE)) groupItem.Text = ResourceString.GetDirectString(textXE.GetAttribute(\"Value\"));\n                    }\n                    if(guids.Count > 0)\n                    {\n                        groupItem.Tag = guids;\n                        if(groupItem.Text.IsNullOrWhiteSpace()) groupItem.Text = GuidInfo.GetText(guids[0]);\n                        groupItem.Image = GuidInfo.GetImage(guids[0]);\n                        string filePath = GuidInfo.GetFilePath(guids[0]);\n                        string clsidPath = GuidInfo.GetClsidPath(guids[0]);\n                        if(filePath != null || clsidPath != null) groupItem.ContextMenuStrip.Items.Add(new ToolStripSeparator());\n                        if(filePath != null)\n                        {\n                            ToolStripMenuItem tsi = new ToolStripMenuItem(AppString.Menu.FileLocation);\n                            tsi.Click += (sender, e) => ExternalProgram.JumpExplorer(filePath, AppConfig.OpenMoreExplorer);\n                            groupItem.ContextMenuStrip.Items.Add(tsi);\n                        }\n                        if(clsidPath != null)\n                        {\n                            ToolStripMenuItem tsi = new ToolStripMenuItem(AppString.Menu.ClsidLocation);\n                            tsi.Click += (sender, e) => ExternalProgram.JumpRegEdit(clsidPath, null, AppConfig.OpenMoreRegedit);\n                            groupItem.ContextMenuStrip.Items.Add(tsi);\n                        }\n                    }\n                    XmlNode iconXN = groupXN.SelectSingleNode(\"Icon\");\n                    using(Icon icon = ResourceIcon.GetIcon(iconXN?.InnerText))\n                    {\n                        if(icon != null) groupItem.Image = icon.ToBitmap();\n                    }\n                    this.AddItem(groupItem);\n\n                    string GetRuleFullRegPath(string regPath)\n                    {\n                        if(string.IsNullOrEmpty(regPath)) regPath = groupItem.GroupPath;\n                        else if(regPath.StartsWith(\"\\\\\")) regPath = groupItem.GroupPath + regPath;\n                        return regPath;\n                    };\n\n                    foreach(XmlElement itemXE in groupXN.SelectNodes(\"Item\"))\n                    {\n                        try\n                        {\n                            if(!XmlDicHelper.JudgeOSVersion(itemXE)) continue;\n                            RuleItem ruleItem;\n                            ItemInfo info = new ItemInfo();\n                            foreach(XmlElement textXE in itemXE.SelectNodes(\"Text\"))\n                            {\n                                if(XmlDicHelper.JudgeCulture(textXE)) info.Text = ResourceString.GetDirectString(textXE.GetAttribute(\"Value\"));\n                            }\n                            foreach(XmlElement tipXE in itemXE.SelectNodes(\"Tip\"))\n                            {\n                                if(XmlDicHelper.JudgeCulture(tipXE)) info.Tip = ResourceString.GetDirectString(tipXE.GetAttribute(\"Value\"));\n                            }\n                            info.RestartExplorer = itemXE.SelectSingleNode(\"RestartExplorer\") != null;\n\n                            int defaultValue = 0, maxValue = 0, minValue = 0;\n                            if(itemXE.SelectSingleNode(\"IsNumberItem\") != null)\n                            {\n                                XmlElement ruleXE = (XmlElement)itemXE.SelectSingleNode(\"Rule\");\n                                defaultValue = ruleXE.HasAttribute(\"Default\") ? Convert.ToInt32(ruleXE.GetAttribute(\"Default\")) : 0;\n                                maxValue = ruleXE.HasAttribute(\"Max\") ? Convert.ToInt32(ruleXE.GetAttribute(\"Max\")) : int.MaxValue;\n                                minValue = ruleXE.HasAttribute(\"Min\") ? Convert.ToInt32(ruleXE.GetAttribute(\"Min\")) : int.MinValue;\n                            }\n\n                            if(isIniGroup)\n                            {\n                                XmlElement ruleXE = (XmlElement)itemXE.SelectSingleNode(\"Rule\");\n                                string iniPath = ruleXE.GetAttribute(\"FilePath\");\n                                if(iniPath.IsNullOrWhiteSpace()) iniPath = groupItem.GroupPath;\n                                string section = ruleXE.GetAttribute(\"Section\");\n                                string keyName = ruleXE.GetAttribute(\"KeyName\");\n                                if(itemXE.SelectSingleNode(\"IsNumberItem\") != null)\n                                {\n                                    var rule = new NumberIniRuleItem.IniRule\n                                    {\n                                        IniPath = iniPath,\n                                        Section = section,\n                                        KeyName = keyName,\n                                        DefaultValue = defaultValue,\n                                        MaxValue = maxValue,\n                                        MinValue = maxValue\n                                    };\n                                    ruleItem = new NumberIniRuleItem(rule, info);\n                                }\n                                else if(itemXE.SelectSingleNode(\"IsStringItem\") != null)\n                                {\n                                    var rule = new StringIniRuleItem.IniRule\n                                    {\n                                        IniPath = iniPath,\n                                        Secation = section,\n                                        KeyName = keyName\n                                    };\n                                    ruleItem = new StringIniRuleItem(rule, info);\n                                }\n                                else\n                                {\n                                    var rule = new VisbleIniRuleItem.IniRule\n                                    {\n                                        IniPath = iniPath,\n                                        Section = section,\n                                        KeyName = keyName,\n                                        TurnOnValue = ruleXE.HasAttribute(\"On\") ? ruleXE.GetAttribute(\"On\") : null,\n                                        TurnOffValue = ruleXE.HasAttribute(\"Off\") ? ruleXE.GetAttribute(\"Off\") : null,\n                                    };\n                                    ruleItem = new VisbleIniRuleItem(rule, info);\n                                }\n                            }\n                            else\n                            {\n                                if(itemXE.SelectSingleNode(\"IsNumberItem\") != null)\n                                {\n                                    XmlElement ruleXE = (XmlElement)itemXE.SelectSingleNode(\"Rule\");\n                                    var rule = new NumberRegRuleItem.RegRule\n                                    {\n                                        RegPath = GetRuleFullRegPath(ruleXE.GetAttribute(\"RegPath\")),\n                                        ValueName = ruleXE.GetAttribute(\"ValueName\"),\n                                        ValueKind = XmlDicHelper.GetValueKind(ruleXE.GetAttribute(\"ValueKind\"), RegistryValueKind.DWord),\n                                        DefaultValue = defaultValue,\n                                        MaxValue = maxValue,\n                                        MinValue = minValue\n                                    };\n                                    ruleItem = new NumberRegRuleItem(rule, info);\n                                }\n                                else if(itemXE.SelectSingleNode(\"IsStringItem\") != null)\n                                {\n                                    XmlElement ruleXE = (XmlElement)itemXE.SelectSingleNode(\"Rule\");\n                                    var rule = new StringRegRuleItem.RegRule\n                                    {\n                                        RegPath = GetRuleFullRegPath(ruleXE.GetAttribute(\"RegPath\")),\n                                        ValueName = ruleXE.GetAttribute(\"ValueName\"),\n                                    };\n                                    ruleItem = new StringRegRuleItem(rule, info);\n                                }\n                                else\n                                {\n                                    XmlNodeList ruleXNList = itemXE.SelectNodes(\"Rule\");\n                                    var rules = new VisibleRegRuleItem.RegRule[ruleXNList.Count];\n                                    for(int i = 0; i < ruleXNList.Count; i++)\n                                    {\n                                        XmlElement ruleXE = (XmlElement)ruleXNList[i];\n                                        rules[i] = new VisibleRegRuleItem.RegRule\n                                        {\n                                            RegPath = GetRuleFullRegPath(ruleXE.GetAttribute(\"RegPath\")),\n                                            ValueName = ruleXE.GetAttribute(\"ValueName\"),\n                                            ValueKind = XmlDicHelper.GetValueKind(ruleXE.GetAttribute(\"ValueKind\"), RegistryValueKind.DWord)\n                                        };\n                                        string turnOn = ruleXE.HasAttribute(\"On\") ? ruleXE.GetAttribute(\"On\") : null;\n                                        string turnOff = ruleXE.HasAttribute(\"Off\") ? ruleXE.GetAttribute(\"Off\") : null;\n                                        switch(rules[i].ValueKind)\n                                        {\n                                            case RegistryValueKind.Binary:\n                                                rules[i].TurnOnValue = turnOn != null ? XmlDicHelper.ConvertToBinary(turnOn) : null;\n                                                rules[i].TurnOffValue = turnOff != null ? XmlDicHelper.ConvertToBinary(turnOff) : null;\n                                                break;\n                                            case RegistryValueKind.DWord:\n                                                if(turnOn == null) rules[i].TurnOnValue = null;\n                                                else rules[i].TurnOnValue = Convert.ToInt32(turnOn);\n                                                if(turnOff == null) rules[i].TurnOffValue = null;\n                                                else rules[i].TurnOffValue = Convert.ToInt32(turnOff);\n                                                break;\n                                            default:\n                                                rules[i].TurnOnValue = turnOn;\n                                                rules[i].TurnOffValue = turnOff;\n                                                break;\n                                        }\n                                    }\n                                    ruleItem = new VisibleRegRuleItem(rules, info);\n                                }\n                            }\n                            this.AddItem(ruleItem);\n                            ruleItem.FoldGroupItem = groupItem;\n                            ruleItem.HasImage = ruleItem.Image != null;\n                            ruleItem.Indent();\n                        }\n                        catch { continue; }\n                    }\n                    groupItem.SetVisibleWithSubItemCount();\n                }\n                catch { continue; }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/DictionariesBox.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.IO;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class DictionariesBox : TabControl\n    {\n        public DictionariesBox()\n        {\n            this.SuspendLayout();\n            this.Dock = DockStyle.Fill;\n            this.Controls.AddRange(pages);\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n            cms.Items.AddRange(items);\n            for(int i = 0; i < 6; i++)\n            {\n                boxs[i] = new ReadOnlyRichTextBox { Parent = pages[i] };\n                if(i > 0) boxs[i].ContextMenuStrip = cms;\n            }\n            items[0].Click += (sender, e) => ExternalProgram.OpenNotepadWithText(GetInitialText());\n            items[2].Click += (sender, e) => SaveFile();\n            boxs[0].Controls.Add(btnOpenDir);\n            btnOpenDir.Top = boxs[0].Height - btnOpenDir.Height;\n            ToolTipBox.SetToolTip(btnOpenDir, AppString.Menu.FileLocation);\n            btnOpenDir.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(AppConfig.DicsDir);\n            this.SelectedIndexChanged += (sender, e) => LoadText();\n            this.VisibleChanged += (sender, e) => this.SetEnabled(this.Visible);\n            this.ResumeLayout();\n        }\n\n        readonly TabPage[] pages =\n        {\n            new TabPage(AppString.Other.DictionaryDescription),\n            new TabPage(AppString.SideBar.AppLanguage),\n            new TabPage(AppString.Other.GuidInfosDictionary),\n            new TabPage(AppString.SideBar.DetailedEdit),\n            new TabPage(AppString.SideBar.EnhanceMenu),\n            new TabPage(AppString.Other.UwpMode)\n        };\n        readonly ReadOnlyRichTextBox[] boxs = new ReadOnlyRichTextBox[6];\n        readonly PictureButton btnOpenDir = new PictureButton(AppImage.Open)\n        {\n            Anchor = AnchorStyles.Left | AnchorStyles.Bottom,\n            Left = 0\n        };\n        readonly ContextMenuStrip cms = new ContextMenuStrip();\n        readonly ToolStripItem[] items =\n        {\n            new ToolStripMenuItem(AppString.Menu.Edit),\n            new ToolStripSeparator(),\n            new ToolStripMenuItem(AppString.Menu.Save)\n        };\n\n        private void SaveFile()\n        {\n            using(SaveFileDialog dlg = new SaveFileDialog())\n            {\n                string dirPath = AppConfig.UserDicsDir;\n                switch(SelectedIndex)\n                {\n                    case 1:\n                        dirPath = AppConfig.LangsDir;\n                        dlg.FileName = AppConfig.ZH_CNINI;\n                        break;\n                    case 2:\n                        dlg.FileName = AppConfig.GUIDINFOSDICINI;\n                        break;\n                    case 3:\n                        dlg.FileName = AppConfig.DETAILEDEDITDICXML;\n                        break;\n                    case 4:\n                        dlg.FileName = AppConfig.ENHANCEMENUSICXML;\n                        break;\n                    case 5:\n                        dlg.FileName = AppConfig.UWPMODEITEMSDICXML;\n                        break;\n                }\n                dlg.Filter = $\"{dlg.FileName}|*{Path.GetExtension(dlg.FileName)}\";\n                Directory.CreateDirectory(dirPath);\n                dlg.InitialDirectory = dirPath;\n                if(dlg.ShowDialog() == DialogResult.OK)\n                {\n                    File.WriteAllText(dlg.FileName, GetInitialText(), Encoding.Unicode);\n                }\n            }\n        }\n\n        private string GetInitialText()\n        {\n            switch(this.SelectedIndex)\n            {\n                case 0:\n                    return AppString.Other.Dictionaries;\n                case 1:\n                    return Properties.Resources.AppLanguageDic;\n                case 2:\n                    return Properties.Resources.GuidInfosDic;\n                case 3:\n                    return Properties.Resources.DetailedEditDic;\n                case 4:\n                    return Properties.Resources.EnhanceMenusDic;\n                case 5:\n                    return Properties.Resources.UwpModeItemsDic;\n                default:\n                    return string.Empty;\n            }\n        }\n\n        public void LoadText()\n        {\n            int index = this.SelectedIndex;\n            if(boxs[index].Text.Length > 0) return;\n            Action<string> action = null;\n            switch(index)\n            {\n                case 0:\n                case 1:\n                case 2:\n                    action = boxs[index].LoadIni; break;\n                case 3:\n                case 4:\n                case 5:\n                    action = boxs[index].LoadXml; break;\n            }\n            this.BeginInvoke(action, new[] { GetInitialText() });\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/DonateBox.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class DonateBox : Panel\n    {\n        public DonateBox()\n        {\n            this.SuspendLayout();\n            this.AutoScroll = true;\n            this.Dock = DockStyle.Fill;\n            this.BackColor = Color.White;\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n            this.Controls.AddRange(new Control[] { lblInfo, picQR, lblList });\n            this.VisibleChanged += (sender, e) => this.SetEnabled(this.Visible);\n            lblList.Click += (sender, e) => this.ShowDonateDialog();\n            picQR.Resize += (sender, e) => this.OnResize(null);\n            picQR.MouseDown += SwitchQR;\n            this.ResumeLayout();\n        }\n\n        readonly Label lblInfo = new Label\n        {\n            Text = AppString.Other.Donate,\n            AutoSize = true\n        };\n\n        readonly Label lblList = new Label\n        {\n            ForeColor = Color.FromArgb(85, 145, 215),\n            Text = AppString.Other.DonationList,\n            Cursor = Cursors.Hand,\n            AutoSize = true\n        };\n\n        readonly PictureBox picQR = new PictureBox\n        {\n            SizeMode = PictureBoxSizeMode.AutoSize,\n            Cursor = Cursors.Hand,\n            Image = AllQR,\n        };\n\n        static readonly Image AllQR = Properties.Resources.Donate;\n        static readonly Image WechatQR = GetSingleQR(0);\n        static readonly Image AlipayQR = GetSingleQR(1);\n        static readonly Image QQQR = GetSingleQR(2);\n        private static Image GetSingleQR(int index)\n        {\n            Bitmap bitmap = new Bitmap(200, 200);\n            using(Graphics g = Graphics.FromImage(bitmap))\n            {\n                Rectangle destRect = new Rectangle(0, 0, 200, 200);\n                Rectangle srcRect = new Rectangle(index * 200, 0, 200, 200);\n                g.DrawImage(AllQR, destRect, srcRect, GraphicsUnit.Pixel);\n            }\n            return bitmap;\n        }\n\n        protected override void OnResize(EventArgs e)\n        {\n            int a = 60.DpiZoom();\n            base.OnResize(e);\n            picQR.Left = (this.Width - picQR.Width) / 2;\n            lblInfo.Left = (this.Width - lblInfo.Width) / 2;\n            lblList.Left = (this.Width - lblList.Width) / 2;\n            lblInfo.Top = a;\n            picQR.Top = lblInfo.Bottom + a;\n            lblList.Top = picQR.Bottom + a;\n        }\n\n        private void SwitchQR(object sender, MouseEventArgs e)\n        {\n            if(picQR.Image == AllQR)\n            {\n                if(e.X < 200) picQR.Image = WechatQR;\n                else if(e.X < 400) picQR.Image = AlipayQR;\n                else picQR.Image = QQQR;\n            }\n            else\n            {\n                picQR.Image = AllQR;\n            }\n        }\n\n        private void ShowDonateDialog()\n        {\n            this.Cursor = Cursors.WaitCursor;\n            using(UAWebClient client = new UAWebClient())\n            {\n                string url = AppConfig.RequestUseGithub ? AppConfig.GithubDonateRaw : AppConfig.GiteeDonateRaw;\n                string contents = client.GetWebString(url);\n                //contents = System.IO.File.ReadAllText(@\"..\\..\\..\\Donate.md\");//用于求和更新Donate.md文件\n                if(contents == null)\n                {\n                    if(AppMessageBox.Show(AppString.Message.WebDataReadFailed + \"\\r\\n\"\n                        + AppString.Message.OpenWebUrl, MessageBoxButtons.OKCancel) == DialogResult.OK)\n                    {\n                        url = AppConfig.RequestUseGithub ? AppConfig.GithubDonate : AppConfig.GiteeDonate;\n                        ExternalProgram.OpenWebUrl(url);\n                    }\n                }\n                else\n                {\n                    using(DonateListDialog dlg = new DonateListDialog())\n                    {\n                        dlg.DanateData = contents;\n                        dlg.ShowDialog();\n                    }\n                }\n            }\n            this.Cursor = Cursors.Default;\n        }\n\n        sealed class DonateListDialog : CommonDialog\n        {\n            public string DanateData { get; set; }\n\n            public override void Reset() { }\n\n            protected override bool RunDialog(IntPtr hwndOwner)\n            {\n                using(DonateListForm frm = new DonateListForm())\n                {\n                    frm.ShowDonateList(DanateData);\n                    MainForm mainForm = (MainForm)FromHandle(hwndOwner);\n                    frm.Left = mainForm.Left + (mainForm.Width + mainForm.SideBar.Width - frm.Width) / 2;\n                    frm.Top = mainForm.Top + 150.DpiZoom();\n                    frm.TopMost = AppConfig.TopMost;\n                    frm.ShowDialog();\n                }\n                return true;\n            }\n\n            sealed class DonateListForm : Form\n            {\n                public DonateListForm()\n                {\n                    this.Font = SystemFonts.DialogFont;\n                    this.Text = AppString.Other.DonationList;\n                    this.SizeGripStyle = SizeGripStyle.Hide;\n                    this.StartPosition = FormStartPosition.Manual;\n                    this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\n                    this.MinimizeBox = this.MaximizeBox = this.ShowInTaskbar = false;\n                    this.ClientSize = new Size(520, 350).DpiZoom();\n                    this.MinimumSize = this.Size;\n                    dgvDonate.ColumnHeadersDefaultCellStyle.Alignment\n                        = dgvDonate.RowsDefaultCellStyle.Alignment\n                        = DataGridViewContentAlignment.BottomCenter;\n                    this.Controls.AddRange(new Control[] { lblThank, lblDonate, dgvDonate });\n                    lblThank.MouseEnter += (sender, e) => lblThank.ForeColor = Color.FromArgb(0, 162, 255);\n                    lblThank.MouseLeave += (sender, e) => lblThank.ForeColor = Color.DimGray;\n                    lblDonate.Resize += (sender, e) => this.OnResize(null);\n                    this.AddEscapeButton();\n                }\n\n                readonly DataGridView dgvDonate = new DataGridView\n                {\n                    ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize,\n                    AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells,\n                    SelectionMode = DataGridViewSelectionMode.FullRowSelect,\n                    BackgroundColor = SystemColors.Control,\n                    BorderStyle = BorderStyle.None,\n                    AllowUserToResizeRows = false,\n                    AllowUserToAddRows = false,\n                    RowHeadersVisible = false,\n                    MultiSelect = false,\n                    ReadOnly = true\n                };\n\n                readonly Label lblDonate = new Label { AutoSize = true };\n                readonly Label lblThank = new Label\n                {\n                    Font = new Font(\"Lucida Handwriting\", 15F),\n                    ForeColor = Color.DimGray,\n                    Text = \"Thank you!\",\n                    AutoSize = true,\n                };\n\n                protected override void OnResize(EventArgs e)\n                {\n                    base.OnResize(e);\n                    int a = 20.DpiZoom();\n                    lblDonate.Location = new Point(a, a);\n                    dgvDonate.Location = new Point(a, lblDonate.Bottom + a);\n                    dgvDonate.Width = this.ClientSize.Width - 2 * a;\n                    dgvDonate.Height = this.ClientSize.Height - 3 * a - lblDonate.Height;\n                    lblThank.Location = new Point(dgvDonate.Right - lblThank.Width, lblDonate.Bottom - lblThank.Height);\n                }\n\n                public void ShowDonateList(string contents)\n                {\n                    string[] lines = contents.Split(new[] { \"\\r\\n\", \"\\n\" }, StringSplitOptions.RemoveEmptyEntries);\n                    int index = Array.FindIndex(lines, line => line == \"|:--:|:--:|:--:|:--:|:--:\");\n                    if(index == -1) return;\n                    string[] heads = lines[index - 1].Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);\n                    dgvDonate.ColumnCount = heads.Length;\n                    dgvDonate.Columns[4].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;\n                    for(int m = 0; m < heads.Length; m++)\n                    {\n                        dgvDonate.Columns[m].HeaderText = heads[m];\n                    }\n                    for(int n = index + 1; n < lines.Length; n++)\n                    {\n                        string[] strs = lines[n].Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);\n                        object[] values = new object[strs.Length];\n                        for(int k = 0; k < strs.Length; k++)\n                        {\n                            switch(k)\n                            {\n                                case 3:\n                                    values[k] = Convert.ToSingle(strs[k]);\n                                    break;\n                                default:\n                                    values[k] = strs[k];\n                                    break;\n                            }\n                        }\n                        dgvDonate.Rows.Add(values);\n                    }\n                    dgvDonate.Sort(dgvDonate.Columns[0], ListSortDirection.Descending);\n                    DateTime date = Convert.ToDateTime(dgvDonate.Rows[0].Cells[0].Value);\n                    float money = dgvDonate.Rows.Cast<DataGridViewRow>().Sum(row => (float)row.Cells[3].Value);\n                    lblDonate.Text = AppString.Dialog.DonateInfo.Replace(\"%date\", date.ToLongDateString())\n                        .Replace(\"%money\", money.ToString()).Replace(\"%count\", dgvDonate.RowCount.ToString());\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/EnhanceMenusDialog.cs",
    "content": "﻿using ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class EnhanceMenusDialog : CommonDialog\n    {\n        public string ScenePath { get; set; }\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(SubItemsForm frm = new SubItemsForm())\n            using(EnhanceMenusList list = new EnhanceMenusList())\n            {\n                frm.Text = AppString.SideBar.EnhanceMenu;\n                frm.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\n                frm.TopMost = AppConfig.TopMost;\n                frm.AddList(list);\n                list.ScenePath = this.ScenePath;\n                list.UseUserDic = XmlDicHelper.EnhanceMenuPathDic[this.ScenePath];\n                list.LoadItems();\n                frm.ShowDialog();\n            }\n            return false;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/EnhanceMenusItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Xml;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class EnhanceShellItem : FoldSubItem, IChkVisibleItem\n    {\n        public string RegPath { get; set; }\n        public XmlElement ItemXE { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n\n        public bool ItemVisible\n        {\n            get\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey(RegPath))\n                    return key != null;\n            }\n            set\n            {\n                if(value) WriteSubKeysValue(ItemXE, RegPath);\n                else RegistryEx.DeleteKeyTree(RegPath);\n            }\n        }\n\n        public EnhanceShellItem()\n        {\n            ChkVisible = new VisibleCheckBox(this);\n            this.Indent();\n        }\n\n        private static void WriteAttributesValue(XmlNode valueXN, string regPath)\n        {\n            if(valueXN == null) return;\n            if(!XmlDicHelper.FileExists(valueXN)) return;\n            if(!XmlDicHelper.JudgeCulture(valueXN)) return;\n            if(!XmlDicHelper.JudgeOSVersion(valueXN)) return;\n            using(RegistryKey key = RegistryEx.GetRegistryKey(regPath, true, true))\n            {\n                foreach(XmlNode xn in valueXN.ChildNodes)\n                {\n                    if(xn is XmlComment) continue;\n                    if(!XmlDicHelper.FileExists(xn)) continue;\n                    if(!XmlDicHelper.JudgeCulture(xn)) continue;\n                    if(!XmlDicHelper.JudgeOSVersion(xn)) continue;\n                    foreach(XmlAttribute xa in xn.Attributes)\n                    {\n                        switch(xn.Name)\n                        {\n                            case \"REG_SZ\":\n                                key.SetValue(xa.Name, Environment.ExpandEnvironmentVariables(xa.Value), RegistryValueKind.String);\n                                break;\n                            case \"REG_EXPAND_SZ\":\n                                key.SetValue(xa.Name, xa.Value, RegistryValueKind.ExpandString);\n                                break;\n                            case \"REG_BINARY\":\n                                key.SetValue(xa.Name, XmlDicHelper.ConvertToBinary(xa.Value), RegistryValueKind.Binary);\n                                break;\n                            case \"REG_DWORD\":\n                                int num = xa.Value.ToLower().StartsWith(\"0x\") ? 16 : 10;\n                                key.SetValue(xa.Name, Convert.ToInt32(xa.Value, num), RegistryValueKind.DWord);\n                                break;\n                        }\n                    }\n                }\n            }\n        }\n\n        private static void WriteSubKeysValue(XmlNode keyXN, string regPath)\n        {\n            if(keyXN == null) return;\n            if(!XmlDicHelper.FileExists(keyXN)) return;\n            if(!XmlDicHelper.JudgeCulture(keyXN)) return;\n            if(!XmlDicHelper.JudgeOSVersion(keyXN)) return;\n            string defaultValue = ((XmlElement)keyXN).GetAttribute(\"Default\");\n            if(!defaultValue.IsNullOrWhiteSpace())\n            {\n                defaultValue = Environment.ExpandEnvironmentVariables(defaultValue);\n                Registry.SetValue(regPath, \"\", defaultValue);\n            }\n            else if(keyXN.Name == \"Command\")\n            {\n                //按照规则Command节点无默认值则创建文件\n                WriteCommandValue(keyXN, regPath);\n            }\n            WriteAttributesValue(keyXN.SelectSingleNode(\"Value\"), regPath);\n\n            XmlNode subKeyXN = keyXN.SelectSingleNode(\"SubKey\");\n            if(subKeyXN != null)\n            {\n                foreach(XmlNode xn in subKeyXN.ChildNodes)\n                {\n                    if(xn is XmlComment) continue;\n                    WriteSubKeysValue(xn, $@\"{regPath}\\{xn.Name}\");\n                }\n            }\n        }\n\n        private static void WriteCommandValue(XmlNode cmdXE, string regPath)\n        {\n            XmlElement fnXE = (XmlElement)cmdXE.SelectSingleNode(\"FileName\");\n            XmlElement argXE = (XmlElement)cmdXE.SelectSingleNode(\"Arguments\");\n            XmlElement seXE = (XmlElement)cmdXE.SelectSingleNode(\"ShellExecute\");\n\n            string command;\n            string fileName = fnXE?.InnerText.Trim();\n            string arguments = argXE?.InnerText.Trim();\n            if(string.IsNullOrEmpty(fileName)) fileName = CreateCommandFile(fnXE);\n            if(string.IsNullOrEmpty(arguments)) arguments = CreateCommandFile(argXE);\n            fileName = Environment.ExpandEnvironmentVariables(fileName);\n            arguments = Environment.ExpandEnvironmentVariables(arguments);\n            string prefix = argXE?.GetAttribute(\"Prefix\");//参数前缀\n            string suffix = argXE?.GetAttribute(\"Suffix\");//参数后缀\n            arguments = prefix + arguments + suffix;\n            if(seXE != null)\n            {\n                string verb = seXE.HasAttribute(\"Verb\") ? seXE.GetAttribute(\"Verb\") : \"open\";\n                int windowStyle = seXE.HasAttribute(\"WindowStyle\") ? Convert.ToInt32(seXE.GetAttribute(\"WindowStyle\")) : 1;\n                string directory = Environment.ExpandEnvironmentVariables(seXE.GetAttribute(\"Directory\"));\n                command = ShellExecuteDialog.GetCommand(fileName, arguments, verb, windowStyle, directory);\n            }\n            else\n            {\n                command = fileName;\n                if(arguments != string.Empty) command += $\" {arguments}\";\n            }\n            Registry.SetValue(regPath, \"\", command);\n        }\n\n        private static string CreateCommandFile(XmlNode xe)\n        {\n            string path = string.Empty;\n            if(xe == null) return path;\n            foreach(XmlElement cfXE in xe.SelectNodes(\"CreateFile\"))\n            {\n                if(!XmlDicHelper.FileExists(cfXE)) continue;\n                if(!XmlDicHelper.JudgeCulture(cfXE)) continue;\n                if(!XmlDicHelper.JudgeOSVersion(cfXE)) continue;\n                string fileName = cfXE.GetAttribute(\"FileName\");\n                string content = cfXE.GetAttribute(\"Content\");\n                string extension = Path.GetExtension(fileName).ToLower();\n                string filePath = $@\"{AppConfig.ProgramsDir}\\{fileName}\";\n                if(path == string.Empty) path = filePath;\n                Encoding encoding;\n                switch(extension)\n                {\n                    case \".bat\":\n                    case \".cmd\":\n                        encoding = Encoding.Default;\n                        break;\n                    default:\n                        encoding = Encoding.Unicode;\n                        break;\n                }\n                File.Delete(filePath);\n                File.WriteAllText(filePath, content, encoding);\n\n            }\n            return path;\n        }\n    }\n\n    sealed class EnhanceShellExItem : FoldSubItem, IChkVisibleItem\n    {\n        public string RegPath => $@\"{ShellExPath}\\ContextMenuHandlers\\{DefaultKeyName}\";\n        public string ShellExPath { get; set; }\n        public string DefaultKeyName { get; set; }\n        public Guid Guid { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n\n        public bool ItemVisible\n        {\n            get => ShellExItem.GetPathAndGuids(ShellExPath).Values.Contains(Guid);\n            set\n            {\n                if(value)\n                {\n                    string regPath = ObjectPath.GetNewPathWithIndex(this.RegPath, ObjectPath.PathType.Registry);\n                    Registry.SetValue(regPath, \"\", this.Guid.ToString(\"B\"));\n                }\n                else\n                {\n                    Dictionary<string, Guid> dic = ShellExItem.GetPathAndGuids(ShellExPath);\n                    foreach(string regPath in dic.Keys)\n                    {\n                        if(dic[regPath].Equals(this.Guid))\n                            RegistryEx.DeleteKeyTree(regPath);\n                    }\n                }\n            }\n        }\n\n        public EnhanceShellExItem()\n        {\n            ChkVisible = new VisibleCheckBox(this);\n            this.Indent();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/EnhanceMenusList.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Xml;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class EnhanceMenusList : SwitchDicList\n    {\n        public string ScenePath { get; set; }\n\n        public override void LoadItems()\n        {\n            base.LoadItems();\n            int index = this.UseUserDic ? 1 : 0;\n            XmlDocument doc = XmlDicHelper.EnhanceMenusDic[index];\n            if(doc?.DocumentElement == null) return;\n            foreach(XmlNode xn in doc.DocumentElement.ChildNodes)\n            {\n                try\n                {\n                    Image image = null;\n                    string text = null;\n                    string path = xn.SelectSingleNode(\"RegPath\")?.InnerText;\n                    foreach(XmlElement textXE in xn.SelectNodes(\"Text\"))\n                    {\n                        if(XmlDicHelper.JudgeCulture(textXE))\n                        {\n                            text = ResourceString.GetDirectString(textXE.GetAttribute(\"Value\"));\n                        }\n                    }\n                    if(string.IsNullOrEmpty(path) || string.IsNullOrEmpty(text)) continue;\n                    if(!string.IsNullOrEmpty(this.ScenePath) && !path.Equals(this.ScenePath, StringComparison.OrdinalIgnoreCase)) continue;\n\n                    string iconLocation = xn.SelectSingleNode(\"Icon\")?.InnerText;\n                    using(Icon icon = ResourceIcon.GetIcon(iconLocation))\n                    {\n                        image = icon?.ToBitmap();\n                        image = image ?? AppImage.NotFound;\n                    }\n                    FoldGroupItem groupItem = new FoldGroupItem(path, ObjectPath.PathType.Registry)\n                    {\n                        Image = image,\n                        Text = text\n                    };\n                    this.AddItem(groupItem);\n                    XmlNode shellXN = xn.SelectSingleNode(\"Shell\");\n                    XmlNode shellExXN = xn.SelectSingleNode(\"ShellEx\");\n                    if(shellXN != null) LoadShellItems(shellXN, groupItem);\n                    if(shellExXN != null) LoadShellExItems(shellExXN, groupItem);\n                    groupItem.SetVisibleWithSubItemCount();\n                }\n                catch { continue; }\n            }\n        }\n\n        private void LoadShellItems(XmlNode shellXN, FoldGroupItem groupItem)\n        {\n            foreach(XmlElement itemXE in shellXN.SelectNodes(\"Item\"))\n            {\n                if(!XmlDicHelper.FileExists(itemXE)) continue;\n                if(!XmlDicHelper.JudgeCulture(itemXE)) continue;\n                if(!XmlDicHelper.JudgeOSVersion(itemXE)) continue;\n                string keyName = itemXE.GetAttribute(\"KeyName\");\n                if(keyName.IsNullOrWhiteSpace()) continue;\n                EnhanceShellItem item = new EnhanceShellItem()\n                {\n                    RegPath = $@\"{groupItem.GroupPath}\\shell\\{keyName}\",\n                    FoldGroupItem = groupItem,\n                    ItemXE = itemXE\n                };\n                foreach(XmlElement szXE in itemXE.SelectNodes(\"Value/REG_SZ\"))\n                {\n                    if(!XmlDicHelper.JudgeCulture(szXE)) continue;\n                    if(szXE.HasAttribute(\"MUIVerb\")) item.Text = ResourceString.GetDirectString(szXE.GetAttribute(\"MUIVerb\"));\n                    if(szXE.HasAttribute(\"Icon\")) item.Image = ResourceIcon.GetIcon(szXE.GetAttribute(\"Icon\"))?.ToBitmap();\n                    else if(szXE.HasAttribute(\"HasLUAShield\")) item.Image = AppImage.Shield;\n                }\n                if(item.Image == null)\n                {\n                    XmlElement cmdXE = (XmlElement)itemXE.SelectSingleNode(\"SubKey/Command\");\n                    if(cmdXE != null)\n                    {\n                        Icon icon = null;\n                        if(cmdXE.HasAttribute(\"Default\"))\n                        {\n                            string filePath = ObjectPath.ExtractFilePath(cmdXE.GetAttribute(\"Default\"));\n                            icon = ResourceIcon.GetIcon(filePath);\n                        }\n                        else\n                        {\n                            XmlNode fileXE = cmdXE.SelectSingleNode(\"FileName\");\n                            if(fileXE != null)\n                            {\n                                string filePath = ObjectPath.ExtractFilePath(fileXE.InnerText);\n                                icon = ResourceIcon.GetIcon(filePath);\n                            }\n                        }\n                        item.Image = icon?.ToBitmap();\n                        icon?.Dispose();\n                    }\n                }\n                if(item.Image == null) item.Image = AppImage.NotFound;\n                if(item.Text.IsNullOrWhiteSpace()) item.Text = keyName;\n                string tip = \"\";\n                foreach(XmlElement tipXE in itemXE.SelectNodes(\"Tip\"))\n                {\n                    if(XmlDicHelper.JudgeCulture(tipXE)) tip = tipXE.GetAttribute(\"Value\");\n                }\n                if(itemXE.GetElementsByTagName(\"CreateFile\").Count > 0)\n                {\n                    if(!tip.IsNullOrWhiteSpace()) tip += \"\\n\";\n                    tip += AppString.Tip.CommandFiles;\n                }\n                ToolTipBox.SetToolTip(item.ChkVisible, tip);\n                this.AddItem(item);\n            }\n        }\n\n        private void LoadShellExItems(XmlNode shellExXN, FoldGroupItem groupItem)\n        {\n            foreach(XmlNode itemXN in shellExXN.SelectNodes(\"Item\"))\n            {\n                if(!XmlDicHelper.FileExists(itemXN)) continue;\n                if(!XmlDicHelper.JudgeCulture(itemXN)) continue;\n                if(!XmlDicHelper.JudgeOSVersion(itemXN)) continue;\n                if(!GuidEx.TryParse(itemXN.SelectSingleNode(\"Guid\")?.InnerText, out Guid guid)) continue;\n                EnhanceShellExItem item = new EnhanceShellExItem\n                {\n                    FoldGroupItem = groupItem,\n                    ShellExPath = $@\"{groupItem.GroupPath}\\ShellEx\",\n                    Image = ResourceIcon.GetIcon(itemXN.SelectSingleNode(\"Icon\")?.InnerText)?.ToBitmap() ?? AppImage.SystemFile,\n                    DefaultKeyName = itemXN.SelectSingleNode(\"KeyName\")?.InnerText,\n                    Guid = guid\n                };\n                foreach(XmlNode textXE in itemXN.SelectNodes(\"Text\"))\n                {\n                    if(XmlDicHelper.JudgeCulture(textXE))\n                    {\n                        item.Text = ResourceString.GetDirectString(textXE.InnerText);\n                    }\n                }\n                if(item.Text.IsNullOrWhiteSpace()) item.Text = GuidInfo.GetText(guid);\n                if(item.DefaultKeyName.IsNullOrWhiteSpace()) item.DefaultKeyName = guid.ToString(\"B\");\n                string tip = \"\";\n                foreach(XmlElement tipXE in itemXN.SelectNodes(\"Tip\"))\n                {\n                    if(XmlDicHelper.JudgeCulture(tipXE)) tip = tipXE.GetAttribute(\"Text\");\n                }\n                ToolTipBox.SetToolTip(item.ChkVisible, tip);\n                this.AddItem(item);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ExplorerRestarter.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ExplorerRestarter : MyListItem\n    {\n        public ExplorerRestarter()\n        {\n            this.Visible = false;\n            this.DoubleBuffered = false;\n            this.Dock = DockStyle.Bottom;\n            this.Image = AppImage.Explorer;\n            this.Text = AppString.Other.RestartExplorer;\n            ToolTipBox.SetToolTip(BtnRestart, AppString.Tip.RestartExplorer);\n            this.AddCtr(BtnRestart);\n            this.CanMoveForm();\n            ShowHandler += () => this.Visible = true;\n            HideHandler += () => this.Visible = false;\n            BtnRestart.MouseDown += (sender, e) =>\n            {\n                ExternalProgram.RestartExplorer();\n                this.Visible = false;\n            };\n        }\n\n        public new bool Visible\n        {\n            get => base.Visible;\n            set\n            {\n                bool flag = base.Visible != value && this.Parent != null;\n                base.Visible = value;\n                if(flag) this.Parent.Height += value ? Height : -Height;\n            }\n        }\n\n        private readonly PictureButton BtnRestart = new PictureButton(AppImage.RestartExplorer);\n\n        private static Action ShowHandler;\n        private static Action HideHandler;\n\n        public static new void Show() => ShowHandler?.Invoke();\n        public static new void Hide() => HideHandler?.Invoke();\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/FileExtensionDialog.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Collections.Generic;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class FileExtensionDialog : SelectDialog\n    {\n        public string Extension\n        {\n            get => Selected.Trim();\n            set => Selected = value?.Trim();\n        }\n\n        public FileExtensionDialog()\n        {\n            this.CanEdit = true;\n            this.Title = AppString.Dialog.SelectExtension;\n            List<string> items = new List<string>();\n            using(var key = RegistryEx.GetRegistryKey(FileExtension.FILEEXTSPATH))\n            {\n                if(key != null)\n                {\n                    foreach(string keyName in key.GetSubKeyNames())\n                    {\n                        if(keyName.StartsWith(\".\")) items.Add(keyName.Substring(1));\n                    }\n                }\n            }\n            this.Items = items.ToArray();\n        }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            bool flag = base.RunDialog(hwndOwner);\n            if(flag)\n            {\n                string extension = ObjectPath.RemoveIllegalChars(this.Extension);\n                int index = extension.LastIndexOf('.');\n                if(index >= 0) this.Extension = extension.Substring(index);\n                else this.Extension = $\".{extension}\";\n            }\n            return flag;\n        }\n    }\n}\n"
  },
  {
    "path": "ContextMenuManager/Controls/FoldSubItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\nusing static ContextMenuManager.Methods.ObjectPath;\n\nnamespace ContextMenuManager.Controls\n{\n    class FoldSubItem : MyListItem\n    {\n        public FoldGroupItem FoldGroupItem { get; set; }\n\n        public void Indent()\n        {\n            int w = 40.DpiZoom();\n            this.Controls[\"Image\"].Left += w;\n            this.Controls[\"Text\"].Left += w;\n        }\n    }\n\n    class FoldGroupItem : MyListItem, IBtnShowMenuItem\n    {\n        private bool isFold;\n        public bool IsFold\n        {\n            get => isFold;\n            set\n            {\n                if(isFold == value) return;\n                isFold = value;\n                FoldMe(value);\n            }\n        }\n\n        public string GroupPath { get; set; }\n        public PathType PathType { get; set; }\n\n        public MenuButton BtnShowMenu { get; set; }\n        readonly PictureButton btnFold;\n        readonly PictureButton btnOpenPath;\n        readonly ToolStripMenuItem tsiFoldAll = new ToolStripMenuItem(AppString.Menu.FoldAll);\n        readonly ToolStripMenuItem tsiUnfoldAll = new ToolStripMenuItem(AppString.Menu.UnfoldAll);\n\n        public FoldGroupItem(string groupPath, PathType pathType)\n        {\n            btnFold = new PictureButton(AppImage.Up);\n            BtnShowMenu = new MenuButton(this);\n            btnOpenPath = new PictureButton(AppImage.Open);\n\n            if(pathType == PathType.File || pathType == PathType.Directory)\n            {\n                groupPath = Environment.ExpandEnvironmentVariables(groupPath);\n            }\n            string tip = null;\n            Action openPath = null;\n            switch(pathType)\n            {\n                case PathType.File:\n                    tip = AppString.Menu.FileLocation;\n                    this.Text = Path.GetFileNameWithoutExtension(groupPath);\n                    this.Image = ResourceIcon.GetExtensionIcon(groupPath).ToBitmap();\n                    openPath = () => ExternalProgram.JumpExplorer(groupPath, AppConfig.OpenMoreExplorer);\n                    break;\n                case PathType.Directory:\n                    tip = AppString.Menu.FileLocation;\n                    this.Text = Path.GetFileNameWithoutExtension(groupPath);\n                    this.Image = ResourceIcon.GetFolderIcon(groupPath).ToBitmap();\n                    openPath = () => ExternalProgram.OpenDirectory(groupPath);\n                    break;\n                case PathType.Registry:\n                    tip = AppString.Menu.RegistryLocation;\n                    openPath = () => ExternalProgram.JumpRegEdit(groupPath, null, AppConfig.OpenMoreRegedit);\n                    break;\n            }\n            this.PathType = pathType;\n            this.GroupPath = groupPath;\n            this.Font = new Font(this.Font, FontStyle.Bold);\n            this.AddCtrs(new[] { btnFold, btnOpenPath });\n            this.ContextMenuStrip.Items.AddRange(new[] { tsiFoldAll, tsiUnfoldAll });\n            this.MouseDown += (sender, e) =>\n            {\n                if(e.Button == MouseButtons.Left) Fold();\n            };\n            btnFold.MouseDown += (sender, e) =>\n            {\n                Fold();\n                btnFold.Image = btnFold.BaseImage;\n            };\n            tsiFoldAll.Click += (sender, e) => FoldAll(true);\n            tsiUnfoldAll.Click += (sender, e) => FoldAll(false);\n            btnOpenPath.MouseDown += (sender, e) => openPath.Invoke();\n            ToolTipBox.SetToolTip(btnOpenPath, tip);\n        }\n\n        public void SetVisibleWithSubItemCount()\n        {\n            foreach(Control ctr in this.Parent.Controls)\n            {\n                if(ctr is FoldSubItem item && item.FoldGroupItem == this)\n                {\n                    this.Visible = true;\n                    return;\n                }\n            }\n            this.Visible = false;\n        }\n\n        private void Fold()\n        {\n            this.Parent.SuspendLayout();\n            this.IsFold = !this.IsFold;\n            this.Parent.ResumeLayout();\n        }\n\n        private void FoldMe(bool isFold)\n        {\n            btnFold.BaseImage = isFold ? AppImage.Down : AppImage.Up;\n            foreach(Control ctr in this.Parent?.Controls)\n            {\n                if(ctr is FoldSubItem item && item.FoldGroupItem == this) ctr.Visible = !isFold;\n            }\n        }\n\n        private void FoldAll(bool isFold)\n        {\n            this.Parent.SuspendLayout();\n            foreach(Control ctr in this.Parent.Controls)\n            {\n                if(ctr is FoldGroupItem groupItem) groupItem.IsFold = isFold;\n            }\n            this.Parent.ResumeLayout();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/GuidBlockedItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    class GuidBlockedItem : MyListItem, IBtnShowMenuItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiGuidItem, ITsiRegPathItem\n    {\n        public GuidBlockedItem(string value)\n        {\n            InitializeComponents();\n            this.Value = value;\n            if(GuidEx.TryParse(value, out Guid guid))\n            {\n                this.Guid = guid;\n                this.Image = GuidInfo.GetImage(guid);\n                this.ItemFilePath = GuidInfo.GetFilePath(Guid);\n            }\n            else\n            {\n                this.Guid = Guid.Empty;\n                this.Image = AppImage.SystemFile;\n            }\n            this.Text = this.ItemText;\n        }\n\n        public string Value { get; set; }\n        public Guid Guid { get; set; }\n        public string SearchText => Value;\n        public string ValueName => Value;\n        public string RegPath\n        {\n            get\n            {\n                foreach(string path in GuidBlockedList.BlockedPaths)\n                {\n                    using(var key = RegistryEx.GetRegistryKey(path))\n                    {\n                        if(key == null) continue;\n                        if(key.GetValueNames().Contains(Value, StringComparer.OrdinalIgnoreCase)) return path;\n                    }\n                }\n                return null;\n            }\n        }\n\n        public string ItemText\n        {\n            get\n            {\n                string text;\n                if(GuidEx.TryParse(Value, out Guid guid)) text = GuidInfo.GetText(guid);\n                else text = AppString.Message.MalformedGuid;\n                text += \"\\n\" + Value;\n                return text;\n            }\n        }\n\n        public string ItemFilePath { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n        public DetailedEditButton BtnDetailedEdit { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public HandleGuidMenuItem TsiHandleGuid { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n        readonly ToolStripMenuItem TsiDelete = new ToolStripMenuItem(AppString.Menu.Delete);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            BtnDetailedEdit = new DetailedEditButton(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiHandleGuid = new HandleGuidMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] {TsiHandleGuid,\n                new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDelete });\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch,\n                new ToolStripSeparator(), TsiFileProperties, TsiFileLocation, TsiRegLocation});\n\n            TsiDelete.Click += (sender, e) => DeleteMe();\n        }\n\n        public void DeleteMe()\n        {\n            if(AppMessageBox.Show(AppString.Message.ConfirmDelete, MessageBoxButtons.YesNo) != DialogResult.Yes) return;\n            Array.ForEach(GuidBlockedList.BlockedPaths, path => RegistryEx.DeleteValue(path, this.Value));\n            if(!this.Guid.Equals(Guid.Empty)) ExplorerRestarter.Show();\n            int index = this.Parent.Controls.GetChildIndex(this);\n            index -= (index < this.Parent.Controls.Count - 1) ? 0 : 1;\n            this.Parent.Controls[index].Focus();\n            this.Dispose();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/GuidBlockedList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class GuidBlockedList : MyList\n    {\n        public const string HKLMBLOCKED = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Blocked\";\n        public const string HKCUBLOCKED = @\"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Blocked\";\n        public static readonly string[] BlockedPaths = { HKLMBLOCKED, HKCUBLOCKED };\n\n        public void LoadItems()\n        {\n            this.AddNewItem();\n            this.LoadBlockedItems();\n        }\n\n        private void LoadBlockedItems()\n        {\n            List<string> values = new List<string>();\n            foreach(string path in BlockedPaths)\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey(path))\n                {\n                    if(key == null) continue;\n                    foreach(string value in key.GetValueNames())\n                    {\n                        if(values.Contains(value, StringComparer.OrdinalIgnoreCase)) continue;\n                        this.AddItem(new GuidBlockedItem(value));\n                        values.Add(value);\n                    }\n                }\n            }\n        }\n\n        private void AddNewItem()\n        {\n            NewItem newItem = new NewItem(AppString.Other.AddGuidBlockedItem);\n            this.AddItem(newItem);\n            newItem.AddNewItem += () =>\n            {\n                using(InputDialog dlg = new InputDialog { Title = AppString.Dialog.InputGuid })\n                {\n                    if(GuidEx.TryParse(Clipboard.GetText(), out Guid guid)) dlg.Text = guid.ToString();\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    if(GuidEx.TryParse(dlg.Text, out guid))\n                    {\n                        string value = guid.ToString(\"B\");\n                        Array.ForEach(BlockedPaths, path => Registry.SetValue(path, value, \"\"));\n                        for(int i = 1; i < Controls.Count; i++)\n                        {\n                            if(((GuidBlockedItem)Controls[i]).Guid.Equals(guid))\n                            {\n                                AppMessageBox.Show(AppString.Message.HasBeenAdded);\n                                return;\n                            }\n                        }\n                        this.InsertItem(new GuidBlockedItem(value), 1);\n                        ExplorerRestarter.Show();\n                    }\n                    else AppMessageBox.Show(AppString.Message.MalformedGuid);\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/IEItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class IEItem : MyListItem, ITsiRegPathItem, ITsiFilePathItem, ITsiRegDeleteItem, ITsiCommandItem,\n        ITsiWebSearchItem, ITsiTextItem, ITsiRegExportItem, IBtnShowMenuItem, IChkVisibleItem\n    {\n        public static readonly string[] MeParts = { \"MenuExt\", \"-MenuExt\" };\n\n        public IEItem(string regPath)\n        {\n            InitializeComponents();\n            this.RegPath = regPath;\n        }\n\n        private string regPath;\n        public string RegPath\n        {\n            get => regPath;\n            set\n            {\n                regPath = value;\n                this.Text = this.ItemText;\n                this.Image = this.ItemImage;\n            }\n        }\n        public string ValueName => null;\n        private string KeyName => RegistryEx.GetKeyName(RegPath);\n        private string BackupPath => $@\"{IEList.IEPath}\\{(ItemVisible ? MeParts[1] : MeParts[0])}\\{KeyName}\";\n        private string MeKeyName => RegistryEx.GetKeyName(RegistryEx.GetParentPath(RegPath));\n\n        public string ItemText\n        {\n            get => RegistryEx.GetKeyName(RegPath);\n            set\n            {\n                string newPath = $@\"{RegistryEx.GetParentPath(RegPath)}\\{value.Replace(\"\\\\\", \"\")}\";\n                string defaultValue = Registry.GetValue(newPath, \"\", null)?.ToString();\n                if(!defaultValue.IsNullOrWhiteSpace())\n                {\n                    AppMessageBox.Show(AppString.Message.HasBeenAdded);\n                }\n                else\n                {\n                    RegistryEx.MoveTo(RegPath, newPath);\n                    RegPath = newPath;\n                }\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get => MeKeyName.Equals(MeParts[0], StringComparison.OrdinalIgnoreCase);\n            set\n            {\n                RegistryEx.MoveTo(RegPath, BackupPath);\n                RegPath = BackupPath;\n            }\n        }\n\n        public string ItemCommand\n        {\n            get => Registry.GetValue(RegPath, \"\", null)?.ToString();\n            set\n            {\n                Registry.SetValue(RegPath, \"\", value);\n                this.Image = this.ItemImage;\n            }\n        }\n\n        public string SearchText => $@\"{AppString.SideBar.IEMenu} {Text}\";\n        public string ItemFilePath => ObjectPath.ExtractFilePath(ItemCommand);\n        private Icon ItemIcon => ResourceIcon.GetIcon(ItemFilePath) ?? ResourceIcon.GetExtensionIcon(ItemFilePath);\n        private Image ItemImage => ItemIcon?.ToBitmap() ?? AppImage.NotFound;\n\n        public MenuButton BtnShowMenu { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        public ChangeCommandMenuItem TsiChangeCommand { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n        public RegExportMenuItem TsiRegExport { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            TsiChangeCommand = new ChangeCommandMenuItem(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiRegExport = new RegExportMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText,\n                new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),\n                TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport});\n        }\n\n        public void DeleteMe()\n        {\n            RegistryEx.DeleteKeyTree(this.RegPath);\n            RegistryEx.DeleteKeyTree(this.BackupPath);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/IEList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class IEList : MyList\n    {\n        public const string IEPath = @\"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Internet Explorer\";\n\n        public void LoadItems()\n        {\n            AddNewItem();\n            LoadIEItems();\n        }\n\n        private void LoadIEItems()\n        {\n            List<string> names = new List<string>();\n            using(RegistryKey ieKey = RegistryEx.GetRegistryKey(IEPath))\n            {\n                if(ieKey == null) return;\n                foreach(string part in IEItem.MeParts)\n                {\n                    using(RegistryKey meKey = ieKey.OpenSubKey(part))\n                    {\n                        if(meKey == null) continue;\n                        foreach(string keyName in meKey.GetSubKeyNames())\n                        {\n                            if(names.Contains(keyName, StringComparer.OrdinalIgnoreCase)) continue;\n                            using(RegistryKey key = meKey.OpenSubKey(keyName))\n                            {\n                                if(!string.IsNullOrEmpty(key.GetValue(\"\")?.ToString()))\n                                {\n                                    this.AddItem(new IEItem(key.Name));\n                                    names.Add(keyName);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private void AddNewItem()\n        {\n            NewItem newItem = new NewItem();\n            this.AddItem(newItem);\n            newItem.AddNewItem += () =>\n            {\n                using(NewIEDialog dlg = new NewIEDialog())\n                {\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    this.InsertItem(new IEItem(dlg.RegPath), 1);\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IBtnDeleteItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface IBtnDeleteItem\n    {\n        DeleteButton BtnDelete { get; set; }\n        void DeleteMe();\n    }\n\n    sealed class DeleteButton : PictureButton\n    {\n        public DeleteButton(IBtnDeleteItem item) : base(AppImage.Delete)\n        {\n            MyListItem listItem = (MyListItem)item;\n            listItem.AddCtr(this);\n            this.MouseDown += (sender, e) =>\n            {\n                if(AppMessageBox.Show(AppString.Message.ConfirmDelete, MessageBoxButtons.YesNo) == DialogResult.Yes) item.DeleteMe();\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IBtnMoveUpDownItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface IBtnMoveUpDownItem\n    {\n        MoveButton BtnMoveUp { get; set; }\n        MoveButton BtnMoveDown { get; set; }\n    }\n\n    sealed class MoveButton : PictureButton\n    {\n        public MoveButton(IBtnMoveUpDownItem item, bool isUp) : base(isUp ? AppImage.Up : AppImage.Down)\n        {\n            ((MyListItem)item).AddCtr(this);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IBtnShowMenuItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface IBtnShowMenuItem\n    {\n        ContextMenuStrip ContextMenuStrip { get; set; }\n        MenuButton BtnShowMenu { get; set; }\n    }\n\n    sealed class MenuButton : PictureButton\n    {\n        public MenuButton(IBtnShowMenuItem item) : base(AppImage.Setting)\n        {\n            item.ContextMenuStrip = new ContextMenuStrip();\n            ((MyListItem)item).AddCtr(this);\n            bool isShow = false;\n            this.MouseDown += (sender, e) =>\n            {\n                if(!isShow) item.ContextMenuStrip.Show(this, 0, Height);\n                else item.ContextMenuStrip.Close();\n                isShow = !isShow;\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IChkVisibleItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing ContextMenuManager.Methods;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface IChkVisibleItem\n    {\n        bool ItemVisible { get; set; }\n        VisibleCheckBox ChkVisible { get; set; }\n    }\n\n    sealed class VisibleCheckBox : MyCheckBox\n    {\n        public VisibleCheckBox(IChkVisibleItem item)\n        {\n            MyListItem listItem = (MyListItem)item;\n            listItem.AddCtr(this);\n            this.CheckChanged += () => item.ItemVisible = this.Checked;\n            listItem.ParentChanged += (sender, e) =>\n            {\n                if(listItem.IsDisposed) return;\n                if(listItem.Parent == null) return;\n                this.Checked = item.ItemVisible;\n                if(listItem is FoldSubItem subItem && subItem.FoldGroupItem != null) return;\n                if(listItem.FindForm() is ShellStoreDialog.ShellStoreForm) return;\n                if(AppConfig.HideDisabledItems) listItem.Visible = this.Checked;\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/IProtectOpenItem.cs",
    "content": "﻿namespace ContextMenuManager.Controls.Interfaces\n{\n    interface IProtectOpenItem\n    {\n        bool ItemVisible { get; set; }\n        bool TryProtectOpenItem();\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiAdministratorItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiAdministratorItem\n    {\n        ContextMenuStrip ContextMenuStrip { get; set; }\n        RunAsAdministratorItem TsiAdministrator { get; set; }\n        ShellLink ShellLink { get; }\n    }\n\n    sealed class RunAsAdministratorItem : ToolStripMenuItem\n    {\n        public RunAsAdministratorItem(ITsiAdministratorItem item) : base(AppString.Menu.RunAsAdministrator)\n        {\n            item.ContextMenuStrip.Opening += (sender, e) =>\n            {\n                if(item.ShellLink == null)\n                {\n                    this.Enabled = false;\n                    return;\n                }\n                string filePath = item.ShellLink.TargetPath;\n                string extension = Path.GetExtension(filePath)?.ToLower();\n                switch(extension)\n                {\n                    case \".exe\":\n                    case \".bat\":\n                    case \".cmd\":\n                        this.Enabled = true;\n                        break;\n                    default:\n                        this.Enabled = false;\n                        break;\n                }\n                this.Checked = item.ShellLink.RunAsAdministrator;\n            };\n            this.Click += (sender, e) =>\n            {\n                item.ShellLink.RunAsAdministrator = !this.Checked;\n                item.ShellLink.Save();\n                if(item is WinXItem) ExplorerRestarter.Show();\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiCommandItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiCommandItem\n    {\n        string ItemCommand { get; set; }\n        ChangeCommandMenuItem TsiChangeCommand { get; set; }\n    }\n\n    sealed class ChangeCommandMenuItem : ToolStripMenuItem\n    {\n        public bool CommandCanBeEmpty { get; set; }\n\n        public ChangeCommandMenuItem(ITsiCommandItem item) : base(AppString.Menu.ChangeCommand)\n        {\n            this.Click += (sender, e) =>\n            {\n                string command = ChangeCommand(item.ItemCommand);\n                if(command != null) item.ItemCommand = command;\n            };\n        }\n\n        private string ChangeCommand(string command)\n        {\n            using(InputDialog dlg = new InputDialog())\n            {\n                dlg.Text = command;\n                dlg.Title = AppString.Menu.ChangeCommand;\n                dlg.Size = new Size(530, 260).DpiZoom();\n                if(dlg.ShowDialog() != DialogResult.OK) return null;\n                if(!CommandCanBeEmpty && string.IsNullOrEmpty(dlg.Text))\n                {\n                    AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);\n                    return ChangeCommand(command);\n                }\n                else return dlg.Text;\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiDeleteItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiDeleteItem\n    {\n        DeleteMeMenuItem TsiDeleteMe { get; set; }\n        void DeleteMe();\n    }\n\n    interface ITsiRegDeleteItem : ITsiDeleteItem\n    {\n        string Text { get; }\n        string RegPath { get; }\n    }\n\n    sealed class DeleteMeMenuItem : ToolStripMenuItem\n    {\n        public DeleteMeMenuItem(ITsiDeleteItem item) : base(AppString.Menu.Delete)\n        {\n            this.Click += (sender, e) =>\n            {\n                if(item is ITsiRegDeleteItem regItem && AppConfig.AutoBackup)\n                {\n                    if(AppMessageBox.Show(AppString.Message.DeleteButCanRestore,\n                     MessageBoxButtons.YesNo) != DialogResult.Yes) return;\n                    string date = DateTime.Today.ToString(\"yyyy-MM-dd\");\n                    string time = DateTime.Now.ToString(\"HH.mm.ss\");\n                    string filePath = $@\"{AppConfig.BackupDir}\\{date}\\{regItem.Text} - {time}.reg\";\n                    Directory.CreateDirectory(Path.GetDirectoryName(filePath));\n                    ExternalProgram.ExportRegistry(regItem.RegPath, filePath);\n                }\n                else if(AppMessageBox.Show(AppString.Message.ConfirmDeletePermanently,\n                     MessageBoxButtons.YesNo) != DialogResult.Yes) return;\n\n                MyListItem listItem = (MyListItem)item;\n                MyList list = (MyList)listItem.Parent;\n                int index = list.GetItemIndex(listItem);\n                if(index == list.Controls.Count - 1) index--;\n                try\n                {\n                    item.DeleteMe();\n                }\n                catch\n                {\n                    AppMessageBox.Show(AppString.Message.AuthorityProtection);\n                    return;\n                }\n                list.Controls.Remove(listItem);\n                list.Controls[index].Focus();\n                listItem.Dispose();\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiFilePathItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiFilePathItem\n    {\n        string ItemFilePath { get; }\n        ContextMenuStrip ContextMenuStrip { get; set; }\n        FileLocationMenuItem TsiFileLocation { get; set; }\n        FilePropertiesMenuItem TsiFileProperties { get; set; }\n    }\n\n    sealed class FileLocationMenuItem : ToolStripMenuItem\n    {\n        public FileLocationMenuItem(ITsiFilePathItem item) : base(AppString.Menu.FileLocation)\n        {\n            item.ContextMenuStrip.Opening += (sender, e) =>\n            {\n                this.Visible = item.ItemFilePath != null;\n            };\n            this.Click += (sender, e) => ExternalProgram.JumpExplorer(item.ItemFilePath, AppConfig.OpenMoreExplorer);\n        }\n    }\n\n    sealed class FilePropertiesMenuItem : ToolStripMenuItem\n    {\n        public FilePropertiesMenuItem(ITsiFilePathItem item) : base(AppString.Menu.FileProperties)\n        {\n            item.ContextMenuStrip.Opening += (sender, e) =>\n            {\n                string path = item.ItemFilePath;\n                this.Visible = Directory.Exists(path) || File.Exists(path);\n            };\n            this.Click += (sender, e) => ExternalProgram.ShowPropertiesDialog(item.ItemFilePath);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiGuidItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiGuidItem\n    {\n        Guid Guid { get; }\n        string ItemText { get; }\n        HandleGuidMenuItem TsiHandleGuid { get; set; }\n        DetailedEditButton BtnDetailedEdit { get; set; }\n    }\n\n    sealed class HandleGuidMenuItem : ToolStripMenuItem\n    {\n        public HandleGuidMenuItem(ITsiGuidItem item) : base(AppString.Menu.HandleGuid)\n        {\n            this.Item = item;\n            this.DropDownItems.AddRange(new ToolStripItem[] { TsiAddGuidDic,\n                new ToolStripSeparator(), TsiCopyGuid, TsiBlockGuid, TsiClsidLocation });\n            TsiCopyGuid.Click += (sender, e) => CopyGuid();\n            TsiBlockGuid.Click += (sender, e) => BlockGuid();\n            TsiAddGuidDic.Click += (sender, e) => AddGuidDic();\n            TsiClsidLocation.Click += (sender, e) => OpenClsidPath();\n            ((MyListItem)item).ContextMenuStrip.Opening += (sender, e) => RefreshMenuItem();\n        }\n\n        readonly ToolStripMenuItem TsiCopyGuid = new ToolStripMenuItem(AppString.Menu.CopyGuid);\n        readonly ToolStripMenuItem TsiBlockGuid = new ToolStripMenuItem(AppString.Menu.BlockGuid);\n        readonly ToolStripMenuItem TsiAddGuidDic = new ToolStripMenuItem(AppString.Menu.AddGuidDic);\n        readonly ToolStripMenuItem TsiClsidLocation = new ToolStripMenuItem(AppString.Menu.ClsidLocation);\n\n        public ITsiGuidItem Item { get; set; }\n\n        private void CopyGuid()\n        {\n            string guid = Item.Guid.ToString(\"B\");\n            Clipboard.SetText(guid);\n            AppMessageBox.Show($\"{AppString.Message.CopiedToClipboard}\\n{guid}\",\n                MessageBoxButtons.OK, MessageBoxIcon.Information);\n        }\n\n        private void BlockGuid()\n        {\n            foreach(string path in GuidBlockedList.BlockedPaths)\n            {\n                if(TsiBlockGuid.Checked)\n                {\n                    RegistryEx.DeleteValue(path, Item.Guid.ToString(\"B\"));\n                }\n                else\n                {\n                    if(Item.Guid.Equals(ShellExItem.LnkOpenGuid) && AppConfig.ProtectOpenItem)\n                    {\n                        if(AppMessageBox.Show(AppString.Message.PromptIsOpenItem,\n                            MessageBoxButtons.YesNo) != DialogResult.Yes) return;\n                    }\n                    Microsoft.Win32.Registry.SetValue(path, Item.Guid.ToString(\"B\"), string.Empty);\n                }\n            }\n            ExplorerRestarter.Show();\n        }\n\n        private void AddGuidDic()\n        {\n            using(AddGuidDicDialog dlg = new AddGuidDicDialog())\n            {\n                dlg.ItemText = GuidInfo.GetText(Item.Guid);\n                dlg.ItemIcon = GuidInfo.GetImage(Item.Guid);\n                var location = GuidInfo.GetIconLocation(Item.Guid);\n                dlg.ItemIconPath = location.IconPath;\n                dlg.ItemIconIndex = location.IconIndex;\n                IniWriter writer = new IniWriter\n                {\n                    FilePath = AppConfig.UserGuidInfosDic,\n                    DeleteFileWhenEmpty = true\n                };\n                string section = Item.Guid.ToString();\n                MyListItem listItem = (MyListItem)Item;\n                if(dlg.ShowDialog() != DialogResult.OK)\n                {\n                    if(dlg.IsDelete)\n                    {\n                        writer.DeleteSection(section);\n                        GuidInfo.RemoveDic(Item.Guid);\n                        listItem.Text = Item.ItemText;\n                        listItem.Image = GuidInfo.GetImage(Item.Guid);\n                    }\n                    return;\n                }\n                if(dlg.ItemText.IsNullOrWhiteSpace())\n                {\n                    AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);\n                    return;\n                }\n                dlg.ItemText = ResourceString.GetDirectString(dlg.ItemText);\n                if(dlg.ItemText.IsNullOrWhiteSpace())\n                {\n                    AppMessageBox.Show(AppString.Message.StringParsingFailed);\n                    return;\n                }\n                else\n                {\n                    GuidInfo.RemoveDic(Item.Guid);\n                    writer.SetValue(section, \"Text\", dlg.ItemText);\n                    writer.SetValue(section, \"Icon\", dlg.ItemIconLocation);\n                    listItem.Text = dlg.ItemText;\n                    listItem.Image = dlg.ItemIcon;\n                }\n            }\n        }\n\n        private void OpenClsidPath()\n        {\n            string clsidPath = GuidInfo.GetClsidPath(Item.Guid);\n            ExternalProgram.JumpRegEdit(clsidPath, null, AppConfig.OpenMoreRegedit);\n        }\n\n        private void RefreshMenuItem()\n        {\n            TsiClsidLocation.Visible = GuidInfo.GetClsidPath(Item.Guid) != null;\n            TsiBlockGuid.Visible = TsiBlockGuid.Checked = false;\n            if(Item is ShellExItem)\n            {\n                TsiBlockGuid.Visible = true;\n                foreach(string path in GuidBlockedList.BlockedPaths)\n                {\n                    if(Microsoft.Win32.Registry.GetValue(path, Item.Guid.ToString(\"B\"), null) != null)\n                    {\n                        TsiBlockGuid.Checked = true; break;\n                    }\n                }\n            }\n        }\n\n        sealed class AddGuidDicDialog : CommonDialog\n        {\n            public Image ItemIcon { get; set; }\n            public string ItemText { get; set; }\n            public bool IsDelete { get; private set; }\n            public string ItemIconPath { get; set; }\n            public int ItemIconIndex { get; set; }\n            public string ItemIconLocation\n            {\n                get\n                {\n                    if(ItemIconPath == null) return null;\n                    return $\"{ItemIconPath},{ItemIconIndex}\";\n                }\n            }\n\n            public override void Reset() { }\n\n            protected override bool RunDialog(IntPtr hwndOwner)\n            {\n                using(AddGuidDicForm frm = new AddGuidDicForm())\n                {\n                    frm.ItemText = this.ItemText;\n                    frm.ItemIcon = this.ItemIcon;\n                    frm.ItemIconPath = this.ItemIconPath;\n                    frm.ItemIconIndex = this.ItemIconIndex;\n                    frm.TopMost = AppConfig.TopMost;\n                    bool flag = frm.ShowDialog() == DialogResult.OK;\n                    if(flag)\n                    {\n                        this.ItemText = frm.ItemText;\n                        this.ItemIcon = frm.ItemIcon;\n                        this.ItemIconPath = frm.ItemIconPath;\n                        this.ItemIconIndex = frm.ItemIconIndex;\n                    }\n                    this.IsDelete = frm.IsDelete;\n                    return flag;\n                }\n            }\n\n            sealed class AddGuidDicForm : Form\n            {\n                public AddGuidDicForm()\n                {\n                    this.AcceptButton = btnOK;\n                    this.CancelButton = btnCancel;\n                    this.Font = SystemFonts.MenuFont;\n                    this.Text = AppString.Dialog.AddGuidDic;\n                    this.ShowIcon = this.ShowInTaskbar = false;\n                    this.MaximizeBox = this.MinimizeBox = false;\n                    this.FormBorderStyle = FormBorderStyle.FixedSingle;\n                    this.StartPosition = FormStartPosition.CenterParent;\n                    InitializeComponents();\n                }\n\n                public string ItemText\n                {\n                    get => txtName.Text;\n                    set => txtName.Text = value;\n                }\n                public Image ItemIcon\n                {\n                    get => picIcon.Image;\n                    set => picIcon.Image = value;\n                }\n                public string ItemIconPath { get; set; }\n                public int ItemIconIndex { get; set; }\n                public bool IsDelete { get; private set; }\n\n                readonly TextBox txtName = new TextBox();\n                readonly Label lblName = new Label\n                {\n                    Text = AppString.Dialog.ItemText,\n                    AutoSize = true\n                };\n                readonly Label lblIcon = new Label\n                {\n                    Text = AppString.Menu.ItemIcon,\n                    AutoSize = true\n                };\n                readonly PictureBox picIcon = new PictureBox\n                {\n                    Size = SystemInformation.IconSize\n                };\n                readonly Button btnBrowse = new Button\n                {\n                    Text = AppString.Dialog.Browse,\n                    AutoSize = true\n                };\n                readonly Button btnOK = new Button\n                {\n                    Text = ResourceString.OK,\n                    DialogResult = DialogResult.OK,\n                    AutoSize = true\n                };\n                readonly Button btnCancel = new Button\n                {\n                    Text = ResourceString.Cancel,\n                    DialogResult = DialogResult.Cancel,\n                    AutoSize = true\n                };\n                readonly Button btnDelete = new Button\n                {\n                    Text = AppString.Dialog.DeleteGuidDic,\n                    DialogResult = DialogResult.Cancel,\n                    AutoSize = true\n                };\n\n                private void InitializeComponents()\n                {\n                    this.Controls.AddRange(new Control[] { lblName, txtName, lblIcon, picIcon, btnBrowse, btnDelete, btnOK, btnCancel });\n                    int a = 20.DpiZoom();\n                    lblName.Left = lblName.Top = lblIcon.Left = btnDelete.Left = txtName.Top = a;\n                    txtName.Left = lblName.Right + a;\n                    btnOK.Left = btnDelete.Right + a;\n                    btnCancel.Left = btnOK.Right + a;\n                    txtName.Width = btnCancel.Right - txtName.Left;\n                    btnBrowse.Left = btnCancel.Right - btnBrowse.Width;\n                    picIcon.Left = btnOK.Left + (btnOK.Width - picIcon.Width) / 2;\n                    btnBrowse.Top = txtName.Bottom + a;\n                    picIcon.Top = btnBrowse.Top + (btnBrowse.Height - picIcon.Height) / 2;\n                    lblIcon.Top = btnBrowse.Top + (btnBrowse.Height - lblIcon.Height) / 2;\n                    btnDelete.Top = btnOK.Top = btnCancel.Top = btnBrowse.Bottom + a;\n                    this.ClientSize = new Size(btnCancel.Right + a, btnCancel.Bottom + a);\n                    ToolTipBox.SetToolTip(btnDelete, AppString.Tip.DeleteGuidDic);\n                    btnBrowse.Click += (sender, e) => SelectIcon();\n                    btnDelete.Click += (sender, e) => this.IsDelete = true;\n                }\n\n                private void SelectIcon()\n                {\n                    using(IconDialog dlg = new IconDialog())\n                    {\n                        dlg.IconPath = this.ItemIconPath;\n                        dlg.IconIndex = this.ItemIconIndex;\n                        if(dlg.ShowDialog() != DialogResult.OK) return;\n                        using(Icon icon = ResourceIcon.GetIcon(dlg.IconPath, dlg.IconIndex))\n                        {\n                            Image image = icon?.ToBitmap();\n                            if(image == null) return;\n                            picIcon.Image = image;\n                            this.ItemIconPath = dlg.IconPath;\n                            this.ItemIconIndex = dlg.IconIndex;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    sealed class DetailedEditButton : PictureButton\n    {\n        public DetailedEditButton(ITsiGuidItem item) : base(AppImage.SubItems)\n        {\n            MyListItem listItem = (MyListItem)item;\n            listItem.AddCtr(this);\n            ToolTipBox.SetToolTip(this, AppString.SideBar.DetailedEdit);\n            listItem.ParentChanged += (sender, e) =>\n            {\n                if(listItem.IsDisposed) return;\n                if(listItem.Parent == null) return;\n                this.Visible = XmlDicHelper.DetailedEditGuidDic.ContainsKey(item.Guid);\n            };\n            this.MouseDown += (sender, e) =>\n            {\n                using(DetailedEditDialog dlg = new DetailedEditDialog())\n                {\n                    dlg.GroupGuid = item.Guid;\n                    dlg.ShowDialog();\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiIconItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiIconItem\n    {\n        ChangeIconMenuItem TsiChangeIcon { get; set; }\n        string IconLocation { get; set; }\n        string IconPath { get; set; }\n        int IconIndex { get; set; }\n        Image Image { get; set; }\n        Icon ItemIcon { get; }\n    }\n\n    sealed class ChangeIconMenuItem : ToolStripMenuItem\n    {\n        public ChangeIconMenuItem(ITsiIconItem item) : base(AppString.Menu.ChangeIcon)\n        {\n            this.Click += (sender, e) =>\n            {\n                using(IconDialog dlg = new IconDialog())\n                {\n                    dlg.IconPath = item.IconPath;\n                    dlg.IconIndex = item.IconIndex;\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    using(Icon icon = ResourceIcon.GetIcon(dlg.IconPath, dlg.IconIndex))\n                    {\n                        Image image = icon?.ToBitmap();\n                        if(image == null) return;\n                        item.Image = image;\n                        item.IconPath = dlg.IconPath;\n                        item.IconIndex = dlg.IconIndex;\n                        item.IconLocation = $\"{dlg.IconPath},{dlg.IconIndex}\";\n                    }\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiRegExportItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiRegExportItem\n    {\n        string Text { get; set; }\n        string RegPath { get; }\n        ContextMenuStrip ContextMenuStrip { get; set; }\n        RegExportMenuItem TsiRegExport { get; set; }\n    }\n\n    sealed class RegExportMenuItem : ToolStripMenuItem\n    {\n        public RegExportMenuItem(ITsiRegExportItem item) : base(AppString.Menu.ExportRegistry)\n        {\n            item.ContextMenuStrip.Opening += (sender, e) =>\n            {\n                using(var key = RegistryEx.GetRegistryKey(item.RegPath))\n                    this.Visible = key != null;\n            };\n            this.Click += (sender, e) =>\n            {\n                using(SaveFileDialog dlg = new SaveFileDialog())\n                {\n                    string date = DateTime.Today.ToString(\"yyyy-MM-dd\");\n                    string time = DateTime.Now.ToString(\"HH.mm.ss\");\n                    string filePath = $@\"{AppConfig.BackupDir}\\{date}\\{item.Text} - {time}.reg\";\n                    string dirPath = Path.GetDirectoryName(filePath);\n                    string fileName = Path.GetFileName(filePath);\n                    Directory.CreateDirectory(dirPath);\n                    dlg.FileName = fileName;\n                    dlg.InitialDirectory = dirPath;\n                    dlg.Filter = $\"{AppString.Dialog.RegistryFile}|*.reg\";\n                    if(dlg.ShowDialog() == DialogResult.OK)\n                    {\n                        ExternalProgram.ExportRegistry(item.RegPath, dlg.FileName);\n                    }\n                    if(Directory.GetFileSystemEntries(dirPath).Length == 0)\n                    {\n                        Directory.Delete(dirPath);\n                    }\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiRegPathItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiRegPathItem\n    {\n        string RegPath { get; }\n        string ValueName { get; }\n        ContextMenuStrip ContextMenuStrip { get; set; }\n        RegLocationMenuItem TsiRegLocation { get; set; }\n    }\n\n    sealed class RegLocationMenuItem : ToolStripMenuItem\n    {\n        public RegLocationMenuItem(ITsiRegPathItem item) : base(AppString.Menu.RegistryLocation)\n        {\n            this.Click += (sender, e) => ExternalProgram.JumpRegEdit(item.RegPath, item.ValueName, AppConfig.OpenMoreRegedit);\n            item.ContextMenuStrip.Opening += (sender, e) =>\n            {\n                using(var key = RegistryEx.GetRegistryKey(item.RegPath))\n                    this.Visible = key != null;\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiShortcutCommandItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiShortcutCommandItem\n    {\n        ShellLink ShellLink { get; }\n        ShortcutCommandMenuItem TsiChangeCommand { get; set; }\n        ContextMenuStrip ContextMenuStrip { get; set; }\n    }\n\n    sealed class ShortcutCommandMenuItem : ToolStripMenuItem\n    {\n        public ShortcutCommandMenuItem(ITsiShortcutCommandItem item) : base(AppString.Menu.ChangeCommand)\n        {\n            item.ContextMenuStrip.Opening += (sender, e) =>\n            {\n                this.Visible = !string.IsNullOrEmpty(item.ShellLink?.TargetPath);\n            };\n        }\n\n        public bool ChangeCommand(ShellLink shellLink)\n        {\n            using(CommandDialog dlg = new CommandDialog())\n            {\n                dlg.Command = shellLink.TargetPath;\n                dlg.Arguments = shellLink.Arguments;\n                if(dlg.ShowDialog() != DialogResult.OK) return false;\n                shellLink.TargetPath = dlg.Command;\n                shellLink.Arguments = dlg.Arguments;\n                shellLink.Save();\n                return true;\n            }\n        }\n\n        sealed class CommandDialog : CommonDialog\n        {\n            public string Command { get; set; }\n            public string Arguments { get; set; }\n\n            public override void Reset() { }\n\n            protected override bool RunDialog(IntPtr hwndOwner)\n            {\n                using(CommandForm frm = new CommandForm())\n                {\n                    frm.Command = this.Command;\n                    frm.Arguments = this.Arguments;\n                    frm.TopMost = AppConfig.TopMost;\n                    bool flag = frm.ShowDialog() == DialogResult.OK;\n                    if(flag)\n                    {\n                        this.Command = frm.Command;\n                        this.Arguments = frm.Arguments;\n                    }\n                    return flag;\n                }\n            }\n\n            sealed class CommandForm : ResizeLimitedForm\n            {\n                public CommandForm()\n                {\n                    this.AcceptButton = btnOK;\n                    this.CancelButton = btnCancel;\n                    this.VerticalResizable = false;\n                    this.Font = SystemFonts.MessageBoxFont;\n                    this.Text = AppString.Menu.ChangeCommand;\n                    this.SizeGripStyle = SizeGripStyle.Hide;\n                    this.StartPosition = FormStartPosition.CenterParent;\n                    this.MaximizeBox = MinimizeBox = ShowIcon = ShowInTaskbar = false;\n                    InitializeComponents();\n                }\n\n                public string Command\n                {\n                    get => txtCommand.Text;\n                    set => txtCommand.Text = value;\n                }\n\n                public string Arguments\n                {\n                    get => txtArguments.Text;\n                    set => txtArguments.Text = value;\n                }\n\n                readonly Label lblCommand = new Label\n                {\n                    Text = AppString.Dialog.ItemCommand,\n                    AutoSize = true\n                };\n                readonly Label lblArguments = new Label\n                {\n                    Text = AppString.Dialog.CommandArguments,\n                    AutoSize = true\n                };\n                readonly TextBox txtCommand = new TextBox();\n                readonly TextBox txtArguments = new TextBox();\n                readonly Button btnOK = new Button\n                {\n                    DialogResult = DialogResult.OK,\n                    Text = ResourceString.OK,\n                    AutoSize = true\n                };\n                readonly Button btnCancel = new Button\n                {\n                    DialogResult = DialogResult.Cancel,\n                    Text = ResourceString.Cancel,\n                    AutoSize = true\n                };\n\n                private void InitializeComponents()\n                {\n                    this.Controls.AddRange(new Control[] { lblCommand, lblArguments, txtCommand, txtArguments, btnOK, btnCancel });\n                    int a = 20.DpiZoom();\n                    lblArguments.Left = lblCommand.Left = lblCommand.Top = txtCommand.Top = a;\n                    lblArguments.Top = txtArguments.Top = txtCommand.Bottom + a;\n                    btnOK.Top = btnCancel.Top = txtArguments.Bottom + a;\n                    int b = Math.Max(lblCommand.Width, lblArguments.Width) + 3 * a;\n                    this.ClientSize = new Size(250.DpiZoom() + b, btnOK.Bottom + a);\n                    btnOK.Anchor = btnCancel.Anchor = AnchorStyles.Right | AnchorStyles.Top;\n                    btnCancel.Left = this.ClientSize.Width - btnCancel.Width - a;\n                    btnOK.Left = btnCancel.Left - btnOK.Width - a;\n                    this.Resize += (sender, e) =>\n                    {\n                        txtArguments.Width = txtCommand.Width = this.ClientSize.Width - b;\n                        txtArguments.Left = txtCommand.Left = btnCancel.Right - txtCommand.Width;\n                    };\n                    this.OnResize(null);\n                    this.MinimumSize = this.Size;\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiTextItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiTextItem\n    {\n        string Text { get; set; }\n        string ItemText { get; set; }\n        ChangeTextMenuItem TsiChangeText { get; set; }\n    }\n\n    sealed class ChangeTextMenuItem : ToolStripMenuItem\n    {\n        public ChangeTextMenuItem(ITsiTextItem item) : base(AppString.Menu.ChangeText)\n        {\n            this.Click += (sender, e) =>\n            {\n                string name = ChangeText(item.Text);\n                if(name != null) item.ItemText = name;\n            };\n        }\n\n        private string ChangeText(string text)\n        {\n            using(InputDialog dlg = new InputDialog { Text = text, Title = AppString.Menu.ChangeText })\n            {\n                if(dlg.ShowDialog() != DialogResult.OK) return null;\n                if(dlg.Text.Length == 0)\n                {\n                    AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);\n                    return ChangeText(text);\n                }\n                else if(ResourceString.GetDirectString(dlg.Text).Length == 0)\n                {\n                    AppMessageBox.Show(AppString.Message.StringParsingFailed);\n                    return ChangeText(text);\n                }\n                else return dlg.Text;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ContextMenuManager/Controls/Interfaces/ITsiWebSearchItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls.Interfaces\n{\n    interface ITsiWebSearchItem\n    {\n        string SearchText { get; }\n        WebSearchMenuItem TsiSearch { get; set; }\n    }\n\n    sealed class WebSearchMenuItem : ToolStripMenuItem\n    {\n        public WebSearchMenuItem(ITsiWebSearchItem item) : base(AppString.Menu.WebSearch)\n        {\n            this.Click += (sender, e) =>\n            {\n                string url = AppConfig.EngineUrl.Replace(\"%s\", item.SearchText);\n                ExternalProgram.OpenWebUrl(url);\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/LanguagesBox.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Forms;\nusing System.Xml;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class LanguagesBox : FlowLayoutPanel\n    {\n        public LanguagesBox()\n        {\n            this.SuspendLayout();\n            this.Dock = DockStyle.Fill;\n            this.Font = SystemFonts.MenuFont;\n            this.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n            this.Controls.AddRange(new Control[] { cmbLanguages, btnOpenDir, btnDownLoad, btnTranslate, lblThank, pnlTranslators });\n            this.VisibleChanged += (sender, e) => this.SetEnabled(this.Visible);\n            cmbLanguages.SelectionChangeCommitted += (sender, e) => ChangeLanguage();\n            btnOpenDir.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(AppConfig.LangsDir);\n            lblThank.MouseEnter += (sender, e) => lblThank.ForeColor = Color.FromArgb(0, 162, 255);\n            lblThank.MouseLeave += (sender, e) => lblThank.ForeColor = Color.DimGray;\n            btnDownLoad.MouseDown += (sender, e) =>\n            {\n                this.Cursor = Cursors.WaitCursor;\n                this.ShowLanguageDialog();\n                this.Cursor = Cursors.Default;\n            };\n            btnTranslate.MouseDown += (sender, e) =>\n            {\n                using(TranslateDialog dlg = new TranslateDialog())\n                {\n                    dlg.ShowDialog();\n                }\n            };\n            ToolTipBox.SetToolTip(btnOpenDir, AppString.Menu.FileLocation);\n            ToolTipBox.SetToolTip(btnDownLoad, AppString.Dialog.DownloadLanguages);\n            ToolTipBox.SetToolTip(btnTranslate, AppString.Dialog.TranslateTool);\n            lblHeader.Font = new Font(this.Font, FontStyle.Bold);\n            cmbLanguages.AutosizeDropDownWidth();\n            this.OnResize(null);\n            this.ResumeLayout();\n        }\n\n        readonly ComboBox cmbLanguages = new ComboBox\n        {\n            DropDownStyle = ComboBoxStyle.DropDownList,\n            Width = 170.DpiZoom(),\n        };\n        readonly PictureButton btnOpenDir = new PictureButton(AppImage.Open);\n        readonly PictureButton btnDownLoad = new PictureButton(AppImage.DownLoad);\n        readonly PictureButton btnTranslate = new PictureButton(AppImage.Translate);\n        readonly ToolTip toolTip = new ToolTip { InitialDelay = 1 };\n        readonly Panel pnlTranslators = new Panel\n        {\n            BorderStyle = BorderStyle.FixedSingle,\n            AutoScroll = true\n        };\n        readonly Label lblHeader = new Label\n        {\n            Text = AppString.Other.Translators + \"\\r\\n\" + new string('-', 96),\n            ForeColor = Color.DarkCyan,\n            Dock = DockStyle.Top,\n            AutoSize = true\n        };\n        readonly Label lblThank = new Label\n        {\n            Font = new Font(\"Lucida Handwriting\", 11F),\n            Text = \"Thank you for your translation!\",\n            ForeColor = Color.DimGray,\n            AutoSize = true,\n        };\n        readonly List<string> languages = new List<string>();\n\n        protected override void OnResize(EventArgs e)\n        {\n            base.OnResize(e);\n            int a = 20.DpiZoom();\n            pnlTranslators.Width = this.ClientSize.Width - 2 * a;\n            pnlTranslators.Height = this.ClientSize.Height - pnlTranslators.Top - a;\n            cmbLanguages.Margin = pnlTranslators.Margin = lblThank.Margin = btnOpenDir.Margin\n                = btnDownLoad.Margin = btnTranslate.Margin = new Padding(a, a, 0, 0);\n        }\n\n        public void LoadLanguages()\n        {\n            cmbLanguages.Items.Clear();\n            cmbLanguages.Items.Add(\"(default) 简体中文\");\n            languages.Clear();\n            languages.Add(\"default\");\n            pnlTranslators.SuspendLayout();\n            pnlTranslators.Controls.Remove(lblHeader);\n            foreach(Control ctr in pnlTranslators.Controls) ctr.Dispose();\n            pnlTranslators.Controls.Clear();\n            pnlTranslators.Controls.Add(lblHeader);\n            if(Directory.Exists(AppConfig.LangsDir))\n            {\n                Dictionary<Label, Control[]> dic = new Dictionary<Label, Control[]>();\n                foreach(string fileName in Directory.GetFiles(AppConfig.LangsDir, \"*.ini\"))\n                {\n                    IniWriter writer = new IniWriter(fileName);\n                    string language = writer.GetValue(\"General\", \"Language\");\n                    string translator = writer.GetValue(\"General\", \"Translator\");\n                    string translatorUrl = writer.GetValue(\"General\", \"TranslatorUrl\");\n\n                    string langName = Path.GetFileNameWithoutExtension(fileName);\n                    if(string.IsNullOrEmpty(language)) language = langName;\n                    string[] translators = translator.Split(new[] { \"\\\\r\\\\n\", \"\\\\n\" }, StringSplitOptions.RemoveEmptyEntries);\n                    string[] urls = translatorUrl.Split(new[] { \"\\\\r\\\\n\", \"\\\\n\" }, StringSplitOptions.RemoveEmptyEntries);\n\n                    Label lblLanguage = new Label\n                    {\n                        ForeColor = Color.DodgerBlue,\n                        Text = language,\n                        AutoSize = true,\n                        Font = this.Font\n                    };\n                    Label[] ctrTranslators = new Label[translators.Length];\n                    for(int i = 0; i < translators.Length; i++)\n                    {\n                        ctrTranslators[i] = new Label\n                        {\n                            AutoSize = true,\n                            Font = this.Font,\n                            Text = translators[i],\n                            ForeColor = Color.DimGray,\n                        };\n                        if(urls.Length > i)\n                        {\n                            string url = urls[i].Trim();\n                            if(url != \"null\")\n                            {\n                                toolTip.SetToolTip(ctrTranslators[i], url);\n                                ctrTranslators[i].ForeColor = Color.SkyBlue;\n                                ctrTranslators[i].Font = new Font(ctrTranslators[i].Font, FontStyle.Underline);\n                                ctrTranslators[i].Click += (sender, e) => ExternalProgram.OpenWebUrl(url);\n                            }\n                        }\n                    }\n                    dic.Add(lblLanguage, ctrTranslators);\n                    cmbLanguages.Items.Add(language);\n                    languages.Add(langName);\n                }\n                int left = 0;\n                dic.Keys.ToList().ForEach(lbl => left = Math.Max(left, lbl.Width));\n                left += 250.DpiZoom();\n                int top = lblHeader.Bottom + 10.DpiZoom();\n                foreach(var item in dic)\n                {\n                    item.Key.Top = top;\n                    pnlTranslators.Controls.Add(item.Key);\n                    foreach(var ctr in item.Value)\n                    {\n                        ctr.Location = new Point(left, top);\n                        pnlTranslators.Controls.Add(ctr);\n                        top += ctr.Height + 10.DpiZoom();\n                    }\n                }\n            }\n            pnlTranslators.ResumeLayout();\n            cmbLanguages.SelectedIndex = GetSelectIndex();\n        }\n\n        private void ChangeLanguage()\n        {\n            int index = GetSelectIndex();\n            if(cmbLanguages.SelectedIndex == index) return;\n            string language = languages[cmbLanguages.SelectedIndex];\n            string msg = \"\";\n            if(cmbLanguages.SelectedIndex != 0)\n            {\n                string langPath = $@\"{AppConfig.LangsDir}\\{language}.ini\";\n                msg = new IniWriter(langPath).GetValue(\"Message\", \"RestartApp\");\n            }\n            if(msg == \"\") msg = AppString.Message.RestartApp;\n            if(AppMessageBox.Show(msg, MessageBoxButtons.OKCancel) != DialogResult.OK)\n            {\n                cmbLanguages.SelectedIndex = index;\n            }\n            else\n            {\n                if(language == CultureInfo.CurrentUICulture.Name) language = \"\";\n                AppConfig.Language = language;\n                SingleInstance.Restart();\n            }\n        }\n\n        private int GetSelectIndex()\n        {\n            int index = languages.FindIndex(language => language.Equals(AppConfig.Language, StringComparison.OrdinalIgnoreCase));\n            if(index == -1) index = 0;\n            return index;\n        }\n\n        public void ShowLanguageDialog()\n        {\n            using(UAWebClient client = new UAWebClient())\n            {\n                string apiUrl = AppConfig.RequestUseGithub ? AppConfig.GithubLangsApi : AppConfig.GiteeLangsApi;\n                XmlDocument doc = client.GetWebJsonToXml(apiUrl);\n                if(doc == null)\n                {\n                    AppMessageBox.Show(AppString.Message.WebDataReadFailed);\n                    return;\n                }\n                XmlNodeList list = doc.FirstChild.ChildNodes;\n                string[] langs = new string[list.Count];\n                for(int i = 0; i < list.Count; i++)\n                {\n                    XmlNode nameXN = list.Item(i).SelectSingleNode(\"name\");\n                    langs[i] = Path.GetFileNameWithoutExtension(nameXN.InnerText);\n                }\n                if(langs.Length == 0)\n                {\n                    AppMessageBox.Show(AppString.Message.WebDataReadFailed);\n                    return;\n                }\n                using(SelectDialog dlg = new SelectDialog())\n                {\n                    dlg.Items = langs;\n                    dlg.Title = AppString.Dialog.DownloadLanguages;\n                    string lang = CultureInfo.CurrentUICulture.Name;\n                    if(dlg.Items.Contains(lang)) dlg.Selected = lang;\n                    else dlg.SelectedIndex = 0;\n                    if(dlg.ShowDialog() == DialogResult.OK)\n                    {\n                        string fileName = $\"{dlg.Selected}.ini\";\n                        string filePath = $@\"{AppConfig.LangsDir}\\{fileName}\";\n                        string dirUrl = AppConfig.RequestUseGithub ? AppConfig.GithubLangsRawDir : AppConfig.GiteeLangsRawDir;\n                        string fileUrl = $\"{dirUrl}/{fileName}\";\n                        bool flag = client.WebStringToFile(filePath, fileUrl);\n                        if(!flag)\n                        {\n                            if(AppMessageBox.Show(AppString.Message.WebDataReadFailed + \"\\r\\n ● \" + fileName + \"\\r\\n\"\n                                + AppString.Message.OpenWebUrl, MessageBoxButtons.YesNo) == DialogResult.Yes)\n                            {\n                                ExternalProgram.OpenWebUrl(fileUrl);\n                            }\n                        }\n                        else\n                        {\n                            this.LoadLanguages();\n                            string language = new IniWriter(filePath).GetValue(\"General\", \"Language\");\n                            if(language == \"\") language = dlg.Selected;\n                            cmbLanguages.Text = language;\n                            ChangeLanguage();\n                        }\n                    }\n                }\n            }\n        }\n\n        sealed class TranslateDialog : CommonDialog\n        {\n            public override void Reset() { }\n\n            protected override bool RunDialog(IntPtr hwndOwner)\n            {\n                using(TranslateForm frm = new TranslateForm())\n                {\n                    frm.TopMost = AppConfig.TopMost;\n                    return frm.ShowDialog() == DialogResult.OK;\n                }\n            }\n\n            sealed class TranslateForm : Form\n            {\n                public TranslateForm()\n                {\n                    this.SuspendLayout();\n                    this.CancelButton = btnCancel;\n                    this.Font = SystemFonts.MessageBoxFont;\n                    this.SizeGripStyle = SizeGripStyle.Hide;\n                    this.Text = AppString.Dialog.TranslateTool;\n                    this.ShowInTaskbar = this.MinimizeBox = false;\n                    this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);\n                    this.StartPosition = FormStartPosition.CenterParent;\n                    this.InitializeComponents();\n                    this.ResumeLayout();\n                }\n\n                readonly Label lblSections = new Label\n                {\n                    AutoSize = true,\n                    Text = \"Section\"\n                };\n                readonly Label lblKeys = new Label\n                {\n                    AutoSize = true,\n                    Text = \"Key\"\n                };\n                readonly Label lblDefault = new Label\n                {\n                    Text = AppString.Dialog.DefaultText,\n                    AutoSize = true\n                };\n                readonly Label lblOld = new Label\n                {\n                    Text = AppString.Dialog.OldTranslation,\n                    AutoSize = true\n                };\n                readonly Label lblNew = new Label\n                {\n                    Text = AppString.Dialog.NewTranslation,\n                    AutoSize = true\n                };\n                readonly TextBox txtDefault = new TextBox\n                {\n                    Multiline = true,\n                    ReadOnly = true\n                };\n                readonly TextBox txtOld = new TextBox\n                {\n                    Multiline = true,\n                    ReadOnly = true\n                };\n                readonly TextBox txtNew = new TextBox\n                {\n                    Multiline = true\n                };\n                readonly ComboBox cmbSections = new ComboBox\n                {\n                    DropDownStyle = ComboBoxStyle.DropDownList\n                };\n                readonly ComboBox cmbKeys = new ComboBox\n                {\n                    DropDownStyle = ComboBoxStyle.DropDownList\n                };\n                readonly Button btnBrowse = new Button\n                {\n                    Text = AppString.Dialog.Browse,\n                    AutoSize = true\n                };\n                readonly Button btnSave = new Button\n                {\n                    Text = AppString.Menu.Save,\n                    AutoSize = true\n                };\n                readonly Button btnCancel = new Button\n                {\n                    DialogResult = DialogResult.Cancel,\n                    Text = ResourceString.Cancel,\n                    AutoSize = true\n                };\n\n                static TranslateForm()\n                {\n                    foreach(string section in AppString.DefLangReader.Sections)\n                    {\n                        var dic = new Dictionary<string, string>();\n                        foreach(string key in AppString.DefLangReader.GetSectionKeys(section))\n                        {\n                            dic.Add(key, string.Empty);\n                        }\n                        EditingDic.Add(section, dic);\n                    }\n                }\n\n                static readonly Dictionary<string, Dictionary<string, string>> EditingDic\n                    = new Dictionary<string, Dictionary<string, string>>();\n\n                static readonly IniWriter ReferentialWirter = new IniWriter();\n\n                private string Section => cmbSections.Text;\n                private string Key => cmbKeys.Text;\n\n                private void InitializeComponents()\n                {\n                    this.Controls.AddRange(new Control[] { lblSections, cmbSections, lblKeys,\n                    cmbKeys, lblDefault, txtDefault, lblOld, txtOld, lblNew,\n                    txtNew, btnBrowse, btnSave, btnCancel });\n\n                    txtDefault.SetAutoShowScroll(ScrollBars.Vertical);\n                    txtOld.SetAutoShowScroll(ScrollBars.Vertical);\n                    txtNew.SetAutoShowScroll(ScrollBars.Vertical);\n                    txtDefault.CanSelectAllWhenReadOnly();\n                    txtOld.CanSelectAllWhenReadOnly();\n                    cmbSections.AutosizeDropDownWidth();\n                    cmbKeys.AutosizeDropDownWidth();\n\n                    int a = 20.DpiZoom();\n\n                    lblSections.Top = lblSections.Left = cmbSections.Top = lblKeys.Left\n                        = lblDefault.Left = lblOld.Left = lblNew.Left = btnBrowse.Left = a;\n\n                    lblKeys.Top = cmbKeys.Top = cmbSections.Bottom + a;\n                    lblDefault.Top = txtDefault.Top = cmbKeys.Bottom + a;\n                    txtDefault.Height = txtOld.Height = txtNew.Height = 4 * a;\n                    cmbSections.Width = cmbKeys.Width = txtDefault.Width = txtOld.Width = txtNew.Width = 20 * a;\n\n                    int h = cmbSections.Height + cmbKeys.Height + btnBrowse.Height;\n                    int[] ws = { lblSections.Width, lblKeys.Width, lblDefault.Width, lblOld.Width, lblNew.Width };\n                    int w = ws.Max();\n\n                    cmbSections.Left = cmbKeys.Left = txtDefault.Left = txtOld.Left = txtNew.Left = w + 2 * a;\n\n                    this.Resize += (sender, e) =>\n                    {\n                        txtDefault.Height = txtOld.Height = txtNew.Height\n                            = (this.ClientSize.Height - h - 7 * a) / 3;\n\n                        lblOld.Top = txtOld.Top = txtDefault.Bottom + a;\n                        lblNew.Top = txtNew.Top = txtOld.Bottom + a;\n                        btnBrowse.Top = btnSave.Top = btnCancel.Top = txtNew.Bottom + a;\n\n                        cmbSections.Width = cmbKeys.Width = txtDefault.Width = txtOld.Width = txtNew.Width\n                            = this.ClientSize.Width - (w + 3 * a);\n\n                        btnCancel.Left = this.ClientSize.Width - btnCancel.Width - a;\n                        btnSave.Left = btnCancel.Left - btnSave.Width - a;\n                        btnBrowse.Left = btnSave.Left - btnBrowse.Width - a;\n                    };\n                    this.ClientSize = new Size(w + 23 * a, h + 3 * 4 * a + 7 * a);\n                    this.MinimumSize = this.Size;\n\n                    cmbSections.Items.AddRange(AppString.DefLangReader.Sections);\n                    cmbSections.SelectedIndexChanged += (sender, e) =>\n                    {\n                        cmbKeys.Items.Clear();\n                        cmbKeys.Items.AddRange(AppString.DefLangReader.GetSectionKeys(Section));\n                        cmbKeys.SelectedIndex = 0;\n                    };\n                    cmbKeys.SelectedIndexChanged += (sender, e) =>\n                    {\n                        txtDefault.Text = AppString.DefLangReader.GetValue(Section, Key).Replace(\"\\\\r\", \"\\r\").Replace(\"\\\\n\", \"\\n\");\n                        txtOld.Text = ReferentialWirter.GetValue(Section, Key).Replace(\"\\\\r\", \"\\r\").Replace(\"\\\\n\", \"\\n\");\n                        txtNew.Text = EditingDic[Section][Key].Replace(\"\\\\r\", \"\\r\").Replace(\"\\\\n\", \"\\n\");\n                    };\n                    cmbSections.SelectedIndex = 0;\n\n                    txtOld.TextChanged += (sender, e) => { if(txtNew.Text == string.Empty) txtNew.Text = txtOld.Text; };\n                    txtNew.TextChanged += (sender, e) => EditingDic[Section][Key] = txtNew.Text.Replace(\"\\n\", \"\\\\n\").Replace(\"\\r\", \"\\\\r\");\n                    btnBrowse.Click += (sender, e) => SelectFile();\n                    btnSave.Click += (sender, e) => Save();\n                }\n\n                private void SelectFile()\n                {\n                    using(OpenFileDialog dlg = new OpenFileDialog())\n                    {\n                        dlg.InitialDirectory = AppConfig.LangsDir;\n                        dlg.Filter = $\"{AppString.SideBar.AppLanguage}|*.ini\";\n                        if(dlg.ShowDialog() != DialogResult.OK) return;\n                        ReferentialWirter.FilePath = dlg.FileName;\n                        txtOld.Text = ReferentialWirter.GetValue(Section, Key).Replace(\"\\\\r\", \"\\r\").Replace(\"\\\\n\", \"\\n\");\n                    }\n                }\n\n                private void Save()\n                {\n                    using(SaveFileDialog dlg = new SaveFileDialog())\n                    {\n                        string language = EditingDic[\"General\"][\"Language\"];\n                        int index = language.IndexOf(' ');\n                        if(index > 0) language = language.Substring(0, index);\n                        dlg.FileName = $\"{language}.ini\";\n                        dlg.InitialDirectory = AppConfig.LangsDir;\n                        dlg.Filter = $\"{AppString.SideBar.AppLanguage}|*.ini\";\n                        if(dlg.ShowDialog() != DialogResult.OK) return;\n\n                        string contents = string.Empty;\n                        foreach(string section in EditingDic.Keys)\n                        {\n                            contents += $\"[{section}]\" + \"\\r\\n\";\n                            foreach(string key in EditingDic[section].Keys)\n                            {\n                                string value = EditingDic[section][key];\n                                contents += $\"{key} = {value}\" + \"\\r\\n\";\n                            }\n                            contents += \"\\r\\n\";\n                        }\n                        File.WriteAllText(dlg.FileName, contents, Encoding.Unicode);\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ContextMenuManager/Controls/NewIEDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class NewIEDialog : CommonDialog\n    {\n        public string RegPath { get; private set; }\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(NewIEForm frm = new NewIEForm())\n            {\n                frm.TopMost = AppConfig.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag) this.RegPath = frm.RegPath;\n                return flag;\n            }\n        }\n\n        sealed class NewIEForm : NewItemForm\n        {\n            public string RegPath { get; set; }\n\n            protected override void InitializeComponents()\n            {\n                base.InitializeComponents();\n                btnOK.Click += (sender, e) =>\n                {\n                    if(ItemText.IsNullOrWhiteSpace())\n                    {\n                        AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);\n                        return;\n                    }\n                    if(ItemCommand.IsNullOrWhiteSpace())\n                    {\n                        AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);\n                        return;\n                    }\n                    AddNewItem();\n                    DialogResult = DialogResult.OK;\n                };\n\n                btnBrowse.Click += (sender, e) =>\n                {\n                    using(OpenFileDialog dlg = new OpenFileDialog())\n                    {\n                        if(dlg.ShowDialog() != DialogResult.OK) return;\n                        this.ItemFilePath = dlg.FileName;\n                        this.ItemText = Path.GetFileNameWithoutExtension(dlg.FileName);\n                    }\n                };\n            }\n\n            private void AddNewItem()\n            {\n                this.RegPath = $@\"{IEList.IEPath}\\{IEItem.MeParts[0]}\\{ItemText.Replace(\"\\\\\", \"\")}\";\n                Microsoft.Win32.Registry.SetValue(RegPath, \"\", ItemCommand);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/NewItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\n\nnamespace ContextMenuManager.Controls\n{\n    class NewItem : MyListItem\n    {\n        public NewItem() : this(AppString.Other.NewItem) { }\n\n        public NewItem(string text)\n        {\n            this.Text = text;\n            this.Image = AppImage.NewItem;\n            this.AddCtr(BtnAddNewItem);\n            ToolTipBox.SetToolTip(BtnAddNewItem, text);\n            BtnAddNewItem.MouseDown += (sender, e) => AddNewItem?.Invoke();\n            this.MouseDoubleClick += (sender, e) => AddNewItem?.Invoke();\n\n        }\n        public Action AddNewItem;\n        readonly PictureButton BtnAddNewItem = new PictureButton(AppImage.AddNewItem);\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/NewItemForm.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    class NewItemForm : ResizeLimitedForm\n    {\n        public NewItemForm()\n        {\n            this.AcceptButton = btnOK;\n            this.CancelButton = btnCancel;\n            this.Text = AppString.Other.NewItem;\n            this.Font = SystemFonts.MenuFont;\n            this.MaximizeBox = this.MinimizeBox = false;\n            this.ShowIcon = this.ShowInTaskbar = false;\n            this.StartPosition = FormStartPosition.CenterParent;\n            this.SizeGripStyle = SizeGripStyle.Hide;\n            this.VerticalResizable = false;\n            InitializeComponents();\n        }\n\n        public string ItemText { get => txtText.Text; set => txtText.Text = value; }\n        public string ItemFilePath { get => txtFilePath.Text; set => txtFilePath.Text = value; }\n        public string Arguments { get => txtArguments.Text; set => txtArguments.Text = value; }\n        public string ItemCommand\n        {\n            get\n            {\n                string filePath = ItemFilePath;\n                string arguments = Arguments;\n                if(arguments.IsNullOrWhiteSpace()) return filePath;\n                if(filePath.IsNullOrWhiteSpace()) return arguments;\n                if(filePath.Contains(\" \")) filePath = $\"\\\"{filePath}\\\"\";\n                if(!arguments.Contains(\"\\\"\")) arguments = $\"\\\"{arguments}\\\"\";\n                return $\"{filePath} {arguments}\";\n            }\n        }\n\n        protected readonly Label lblText = new Label\n        {\n            Text = AppString.Dialog.ItemText,\n            AutoSize = true\n        };\n        protected readonly Label lblCommand = new Label\n        {\n            Text = AppString.Dialog.ItemCommand,\n            AutoSize = true\n        };\n        protected readonly Label lblArguments = new Label\n        {\n            Text = AppString.Dialog.CommandArguments,\n            AutoSize = true\n        };\n        protected readonly TextBox txtText = new TextBox();\n        protected readonly TextBox txtFilePath = new TextBox();\n        protected readonly TextBox txtArguments = new TextBox();\n        protected readonly Button btnBrowse = new Button\n        {\n            Text = AppString.Dialog.Browse,\n            AutoSize = true\n        };\n        protected readonly Button btnOK = new Button\n        {\n            Text = ResourceString.OK,\n            AutoSize = true\n        };\n        protected readonly Button btnCancel = new Button\n        {\n            DialogResult = DialogResult.Cancel,\n            Text = ResourceString.Cancel,\n            AutoSize = true\n        };\n\n        protected virtual void InitializeComponents()\n        {\n            this.Controls.AddRange(new Control[] { lblText, lblCommand, lblArguments,\n                txtText, txtFilePath, txtArguments, btnBrowse, btnOK, btnCancel });\n            int a = 20.DpiZoom();\n            btnBrowse.Anchor = btnOK.Anchor = btnCancel.Anchor = AnchorStyles.Right | AnchorStyles.Top;\n            txtText.Top = lblText.Top = lblText.Left = lblCommand.Left = lblArguments.Left = a;\n            btnBrowse.Top = txtFilePath.Top = lblCommand.Top = txtText.Bottom + a;\n            lblArguments.Top = txtArguments.Top = txtFilePath.Bottom + a;\n            btnOK.Top = btnCancel.Top = txtArguments.Bottom + a;\n            btnCancel.Left = btnBrowse.Left = this.ClientSize.Width - btnCancel.Width - a;\n            btnOK.Left = btnCancel.Left - btnOK.Width - a;\n            int b = Math.Max(Math.Max(lblText.Width, lblCommand.Width), lblArguments.Width) + btnBrowse.Width + 4 * a;\n            this.ClientSize = new Size(320.DpiZoom() + b, btnOK.Bottom + a);\n            this.MinimumSize = this.Size;\n            this.Resize += (sender, e) =>\n            {\n                txtText.Width = txtFilePath.Width = txtArguments.Width = this.ClientSize.Width - b;\n                txtText.Left = txtFilePath.Left = txtArguments.Left = btnBrowse.Left - txtFilePath.Width - a;\n            };\n            this.OnResize(null);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/NewLnkFileDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class NewLnkFileDialog : CommonDialog\n    {\n        public string ItemText { get; set; }\n        public string ItemFilePath { get; set; }\n        public string Arguments { get; set; }\n        public string FileFilter { get; set; }\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(NewLnkForm frm = new NewLnkForm())\n            {\n                frm.FileFilter = this.FileFilter;\n                frm.TopMost = AppConfig.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag)\n                {\n                    this.ItemText = frm.ItemText;\n                    this.ItemFilePath = frm.ItemFilePath;\n                    this.Arguments = frm.Arguments;\n                }\n                return flag;\n            }\n        }\n\n        sealed class NewLnkForm : NewItemForm\n        {\n            public string FileFilter { get; set; }\n\n            readonly RadioButton rdoFile = new RadioButton\n            {\n                Text = AppString.SideBar.File,\n                AutoSize = true,\n                Checked = true\n            };\n            readonly RadioButton rdoFolder = new RadioButton\n            {\n                Text = AppString.SideBar.Folder,\n                AutoSize = true\n            };\n\n            protected override void InitializeComponents()\n            {\n                base.InitializeComponents();\n                this.Controls.AddRange(new Control[] { rdoFile, rdoFolder });\n                rdoFile.Top = rdoFolder.Top = btnOK.Top + (btnOK.Height - rdoFile.Height) / 2;\n                rdoFile.Left = lblCommand.Left;\n                rdoFolder.Left = rdoFile.Right + 20.DpiZoom();\n\n                btnBrowse.Click += (sender, e) =>\n                {\n                    if(rdoFile.Checked) BrowseFile();\n                    else BrowseFolder();\n                };\n\n                btnOK.Click += (sender, e) =>\n                {\n                    if(ItemText.IsNullOrWhiteSpace())\n                    {\n                        AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);\n                    }\n                    else if(ItemFilePath.IsNullOrWhiteSpace())\n                    {\n                        AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);\n                    }\n                    else if(rdoFile.Checked && !ObjectPath.GetFullFilePath(ItemFilePath, out _))\n                    {\n                        AppMessageBox.Show(AppString.Message.FileNotExists);\n                    }\n                    else if(rdoFolder.Checked && !Directory.Exists(ItemFilePath))\n                    {\n                        AppMessageBox.Show(AppString.Message.FolderNotExists);\n                    }\n                    else DialogResult = DialogResult.OK;\n                };\n\n                txtFilePath.TextChanged += (sender, e) =>\n                {\n                    if(Path.GetExtension(ItemFilePath).ToLower() == \".lnk\")\n                    {\n                        using(ShellLink shortcut = new ShellLink(ItemFilePath))\n                        {\n                            if(File.Exists(shortcut.TargetPath))\n                            {\n                                ItemFilePath = shortcut.TargetPath;\n                            }\n                        }\n                    }\n                };\n            }\n\n            private void BrowseFile()\n            {\n                using(OpenFileDialog dlg = new OpenFileDialog())\n                {\n                    dlg.Filter = this.FileFilter;\n                    //取消获取lnk目标路径，可选中UWP快捷方式\n                    dlg.DereferenceLinks = false;\n                    if(dlg.ShowDialog() == DialogResult.OK)\n                    {\n                        ItemFilePath = dlg.FileName;\n                        string extension = Path.GetExtension(dlg.FileName).ToLower();\n                        if(extension == \".lnk\")\n                        {\n                            using(ShellLink shortcut = new ShellLink(dlg.FileName))\n                            {\n                                if(File.Exists(shortcut.TargetPath))\n                                {\n                                    ItemFilePath = shortcut.TargetPath;\n                                    Arguments = shortcut.Arguments;\n                                }\n                            }\n                        }\n                        ItemText = Path.GetFileNameWithoutExtension(dlg.FileName);\n                    }\n                }\n            }\n\n            private void BrowseFolder()\n            {\n                using(FolderBrowserDialog dlg = new FolderBrowserDialog())\n                {\n                    if(Directory.Exists(ItemFilePath)) dlg.SelectedPath = ItemFilePath;\n                    else dlg.SelectedPath = Application.StartupPath;\n                    if(dlg.ShowDialog() == DialogResult.OK)\n                    {\n                        ItemFilePath = dlg.SelectedPath;\n                        ItemText = Path.GetFileNameWithoutExtension(dlg.SelectedPath);\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/NewOpenWithDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class NewOpenWithDialog : CommonDialog\n    {\n        public string RegPath { get; private set; }\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(NewOpenWithForm frm = new NewOpenWithForm())\n            {\n                frm.TopMost = AppConfig.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag) this.RegPath = frm.RegPath;\n                return flag;\n            }\n        }\n\n        sealed class NewOpenWithForm : NewItemForm\n        {\n            public string RegPath { get; private set; }\n\n            private string FilePath;\n            private string FileName => Path.GetFileName(FilePath);\n            private string AppRegPath => $@\"{RegistryEx.CLASSES_ROOT}\\Applications\\{FileName}\";\n            private string CommandPath => $@\"{AppRegPath}\\shell\\open\\command\";\n\n            protected override void InitializeComponents()\n            {\n                base.InitializeComponents();\n                btnBrowse.Click += (sender, e) => BrowseFile();\n                btnOK.Click += (sender, e) =>\n                {\n                    if(string.IsNullOrEmpty(ItemText))\n                    {\n                        AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);\n                        return;\n                    }\n                    if(ItemCommand.IsNullOrWhiteSpace())\n                    {\n                        AppMessageBox.Show(AppString.Message.CommandCannotBeEmpty);\n                        return;\n                    }\n                    FilePath = ObjectPath.ExtractFilePath(base.ItemFilePath);\n                    using(var key = RegistryEx.GetRegistryKey(CommandPath))\n                    {\n                        string path = ObjectPath.ExtractFilePath(key?.GetValue(\"\")?.ToString());\n                        string name = Path.GetFileName(path);\n                        if(FilePath != null && FilePath.Equals(path, StringComparison.OrdinalIgnoreCase))\n                        {\n                            AppMessageBox.Show(AppString.Message.HasBeenAdded);\n                            return;\n                        }\n                        if(FileName == null || FileName.Equals(name, StringComparison.OrdinalIgnoreCase))\n                        {\n                            AppMessageBox.Show(AppString.Message.UnsupportedFilename);\n                            return;\n                        }\n                    }\n                    AddNewItem();\n                    this.DialogResult = DialogResult.OK;\n                };\n            }\n\n            private void BrowseFile()\n            {\n                using(OpenFileDialog dlg = new OpenFileDialog())\n                {\n                    dlg.Filter = $\"{AppString.Dialog.Program}|*.exe\";\n                    if(dlg.ShowDialog() == DialogResult.OK)\n                    {\n                        base.ItemFilePath = dlg.FileName;\n                        Arguments = \"\\\"%1\\\"\";\n                        ItemText = FileVersionInfo.GetVersionInfo(dlg.FileName).FileDescription;\n                    }\n                }\n            }\n\n            private void AddNewItem()\n            {\n                using(var key = RegistryEx.GetRegistryKey(AppRegPath, true, true))\n                {\n                    key.SetValue(\"FriendlyAppName\", ItemText);\n                }\n                using(var cmdKey = RegistryEx.GetRegistryKey(CommandPath, true, true))\n                {\n                    cmdKey.SetValue(\"\", ItemCommand);\n                    RegPath = cmdKey.Name;\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/NewShellDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class NewShellDialog : CommonDialog\n    {\n        public string ShellPath { get; set; }//传入的Shell注册表路径\n        public string ScenePath { get; set; }//菜单项所处环境注册表路径\n        public string NewItemRegPath { get; private set; }//返回的新ShellItem的注册表路径\n        public string NewItemKeyName => RegistryEx.GetKeyName(NewItemRegPath);\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(NewShellForm frm = new NewShellForm\n            {\n                ScenePath = this.ScenePath,\n                ShellPath = this.ShellPath\n            })\n            {\n                frm.TopMost = AppConfig.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag) this.NewItemRegPath = frm.NewItemRegPath;\n                return flag;\n            }\n        }\n\n        sealed class NewShellForm : NewItemForm\n        {\n            public string ShellPath { get; set; }\n            public string NewItemRegPath { get; private set; }//返回的新建菜单项注册表路径\n            public string ScenePath { get; set; }//菜单所处环境路径，用于判断添加后缀\n\n            readonly RadioButton rdoSingle = new RadioButton\n            {\n                Text = AppString.Dialog.SingleMenu,\n                AutoSize = true,\n                Checked = true\n            };\n            readonly RadioButton rdoMulti = new RadioButton\n            {\n                Text = AppString.Dialog.MultiMenu,\n                AutoSize = true\n            };\n            readonly ShellExecuteCheckBox chkSE = new ShellExecuteCheckBox();\n\n            static readonly string[] DirScenePaths = {\n                ShellList.MENUPATH_DIRECTORY,\n                ShellList.MENUPATH_BACKGROUND,\n                $@\"{ShellList.SYSFILEASSPATH}\\Directory.\"\n            };\n            static readonly string[] FileObjectsScenePaths = {\n                ShellList.MENUPATH_FILE,\n                ShellList.MENUPATH_FOLDER,\n                ShellList.MENUPATH_ALLOBJECTS,\n                ShellList.SYSFILEASSPATH,\n                ShellList.MENUPATH_UNKNOWN,\n                ShellList.MENUPATH_UWPLNK\n            };\n\n            protected override void InitializeComponents()\n            {\n                base.InitializeComponents();\n                this.Controls.AddRange(new Control[] { rdoSingle, rdoMulti, chkSE });\n                rdoSingle.Top = rdoMulti.Top = chkSE.Top = btnOK.Top + (btnOK.Height - rdoSingle.Height) / 2;\n                rdoSingle.Left = lblCommand.Left;\n                rdoMulti.Left = rdoSingle.Right + 20.DpiZoom();\n                chkSE.Left = rdoMulti.Right + 20.DpiZoom();\n\n                rdoMulti.CheckedChanged += (sender, e) =>\n                {\n                    if(rdoMulti.Checked)\n                    {\n                        chkSE.Checked = false;\n                        if(WinOsVersion.Current == WinOsVersion.Vista)\n                        {\n                            AppMessageBox.Show(AppString.Message.VistaUnsupportedMulti);\n                            rdoSingle.Checked = true;\n                            return;\n                        }\n                    }\n                    lblCommand.Enabled = txtFilePath.Enabled = lblArguments.Enabled\n                    = txtArguments.Enabled = btnBrowse.Enabled = chkSE.Enabled = !rdoMulti.Checked;\n                };\n\n                btnBrowse.Click += (sender, e) => BrowseFile();\n\n                btnOK.Click += (sender, e) =>\n                {\n                    if(txtText.Text.IsNullOrWhiteSpace())\n                    {\n                        AppMessageBox.Show(AppString.Message.TextCannotBeEmpty);\n                    }\n                    else\n                    {\n                        AddNewItem();\n                        DialogResult = DialogResult.OK;\n                    }\n                };\n            }\n\n            private void BrowseFile()\n            {\n                using(OpenFileDialog dlg = new OpenFileDialog())\n                {\n                    dlg.DereferenceLinks = false;\n                    dlg.Filter = $\"{AppString.Dialog.Program}|*.exe|{AppString.Dialog.AllFiles}|*\";\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    string filePath = dlg.FileName;\n                    string arguments = \"\";\n                    ItemText = Path.GetFileNameWithoutExtension(filePath);\n                    string extension = Path.GetExtension(filePath).ToLower();\n                    if(extension == \".lnk\")\n                    {\n                        using(ShellLink shellLink = new ShellLink(filePath))\n                        {\n                            filePath = shellLink.TargetPath;\n                            arguments = shellLink.Arguments;\n                            extension = Path.GetExtension(filePath);\n                        }\n                    }\n                    string exePath = FileExtension.GetExtentionInfo(FileExtension.AssocStr.Executable, extension);\n                    if(File.Exists(exePath))\n                    {\n                        ItemFilePath = exePath;\n                        Arguments = filePath;\n                        if(!arguments.IsNullOrWhiteSpace()) Arguments += \" \" + arguments;\n                    }\n                    else\n                    {\n                        ItemFilePath = filePath;\n                        Arguments = arguments;\n                    }\n                    if(Array.FindIndex(DirScenePaths, path\n                       => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)\n                    {\n                        if(ScenePath != ShellList.MENUPATH_BACKGROUND)\n                        {\n                            if(!Arguments.IsNullOrWhiteSpace()) Arguments += \" \";\n                            Arguments += \"\\\"%V\\\"\";//自动加目录后缀\n                        }\n                    }\n                    else if(Array.FindIndex(FileObjectsScenePaths, path\n                       => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)\n                    {\n                        if(!Arguments.IsNullOrWhiteSpace()) Arguments += \" \";\n                        Arguments += \"\\\"%1\\\"\";//自动加文件对象后缀\n                    }\n                }\n            }\n\n            private void AddNewItem()\n            {\n                using(var shellKey = RegistryEx.GetRegistryKey(ShellPath, true, true))\n                {\n                    string keyName = \"Item\";\n                    NewItemRegPath = ObjectPath.GetNewPathWithIndex($@\"{ShellPath}\\{keyName}\", ObjectPath.PathType.Registry, 0);\n                    keyName = RegistryEx.GetKeyName(NewItemRegPath);\n\n                    using(var key = shellKey.CreateSubKey(keyName, true))\n                    {\n                        key.SetValue(\"MUIVerb\", ItemText);\n                        if(rdoMulti.Checked)\n                            key.SetValue(\"SubCommands\", \"\");\n                        else\n                        {\n                            if(!ItemCommand.IsNullOrWhiteSpace())\n                            {\n                                string command;\n                                if(!chkSE.Checked) command = ItemCommand;\n                                else command = ShellExecuteDialog.GetCommand(ItemFilePath, Arguments, chkSE.Verb, chkSE.WindowStyle);\n                                key.CreateSubKey(\"command\", true).SetValue(\"\", command);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/OpenWithItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class OpenWithItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem, ITsiTextItem,\n        ITsiCommandItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiRegPathItem, ITsiRegDeleteItem, ITsiRegExportItem\n    {\n\n        public OpenWithItem(string regPath)\n        {\n            InitializeComponents();\n            this.RegPath = regPath;\n        }\n\n        private string regPath;\n        public string RegPath\n        {\n            get => regPath;\n            set\n            {\n                regPath = value;\n                this.ItemFilePath = ObjectPath.ExtractFilePath(ItemCommand);\n                this.Text = this.ItemText;\n                this.Image = this.ItemIcon.ToBitmap();\n            }\n        }\n        public string ValueName => null;\n        private string ShellPath => RegistryEx.GetParentPath(RegPath);\n        private string AppPath => RegistryEx.GetParentPath(RegistryEx.GetParentPath(ShellPath));\n        private bool NameEquals => RegistryEx.GetKeyName(AppPath).Equals(Path.GetFileName(ItemFilePath), StringComparison.OrdinalIgnoreCase);\n        private Icon ItemIcon => Icon.ExtractAssociatedIcon(ItemFilePath);\n\n        public string ItemText\n        {\n            get\n            {\n                string name = null;\n                if(NameEquals)\n                {\n                    name = Registry.GetValue(AppPath, \"FriendlyAppName\", null)?.ToString();\n                    name = ResourceString.GetDirectString(name);\n                }\n                if(string.IsNullOrEmpty(name)) name = FileVersionInfo.GetVersionInfo(ItemFilePath).FileDescription;\n                if(string.IsNullOrEmpty(name)) name = Path.GetFileName(ItemFilePath);\n                return name;\n            }\n            set\n            {\n                Registry.SetValue(AppPath, \"FriendlyAppName\", value);\n                this.Text = ResourceString.GetDirectString(value);\n            }\n        }\n\n        public string ItemCommand\n        {\n            get => Registry.GetValue(RegPath, \"\", null)?.ToString();\n            set\n            {\n                if(ObjectPath.ExtractFilePath(value) != ItemFilePath)\n                {\n                    AppMessageBox.Show(AppString.Message.CannotChangePath);\n                }\n                else Registry.SetValue(RegPath, \"\", value);\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get => Registry.GetValue(AppPath, \"NoOpenWith\", null) == null;\n            set\n            {\n                if(value) RegistryEx.DeleteValue(AppPath, \"NoOpenWith\");\n                else Registry.SetValue(AppPath, \"NoOpenWith\", \"\");\n            }\n        }\n\n        public string SearchText => $\"{AppString.SideBar.OpenWith} {Text}\";\n        public string ItemFilePath { get; private set; }\n\n        public VisibleCheckBox ChkVisible { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        public ChangeCommandMenuItem TsiChangeCommand { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public RegExportMenuItem TsiRegExport { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            TsiChangeCommand = new ChangeCommandMenuItem(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiRegExport = new RegExportMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText,\n                new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),\n                TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport });\n\n            ContextMenuStrip.Opening += (sender, e) => TsiChangeText.Enabled = this.NameEquals;\n        }\n\n        public void DeleteMe()\n        {\n            RegistryEx.DeleteKeyTree(this.RegPath);\n            using(RegistryKey key = RegistryEx.GetRegistryKey(ShellPath))\n            {\n                if(key.GetSubKeyNames().Length == 0) RegistryEx.DeleteKeyTree(this.AppPath);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/OpenWithList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class OpenWithList : MyList\n    {\n        public void LoadItems()\n        {\n            this.LoadOpenWithItems();\n            this.SortItemByText();\n            this.AddNewItem();\n            VisibleRegRuleItem storeItem = new VisibleRegRuleItem(VisibleRegRuleItem.UseStoreOpenWith)\n            {\n                //Win8及以上版本系统才有在应用商店中查找应用\n                Visible = WinOsVersion.Current >= WinOsVersion.Win8\n            };\n            this.InsertItem(storeItem, 1);\n        }\n\n        private void LoadOpenWithItems()\n        {\n            using(RegistryKey root = Registry.ClassesRoot)\n            using(RegistryKey appKey = root.OpenSubKey(\"Applications\"))\n            {\n                foreach(string appName in appKey.GetSubKeyNames())\n                {\n                    if(!appName.Contains('.')) continue;//需要为有扩展名的文件名\n                    using(RegistryKey shellKey = appKey.OpenSubKey($@\"{appName}\\shell\"))\n                    {\n                        if(shellKey == null) continue;\n\n                        List<string> names = shellKey.GetSubKeyNames().ToList();\n                        if(names.Contains(\"open\", StringComparer.OrdinalIgnoreCase)) names.Insert(0, \"open\");\n\n                        string keyName = names.Find(name =>\n                        {\n                            using(RegistryKey cmdKey = shellKey.OpenSubKey(name))\n                                return cmdKey.GetValue(\"NeverDefault\") == null;\n                        });\n                        if(keyName == null) continue;\n\n                        using(RegistryKey commandKey = shellKey.OpenSubKey($@\"{keyName}\\command\"))\n                        {\n                            string command = commandKey?.GetValue(\"\")?.ToString();\n                            if(ObjectPath.ExtractFilePath(command) != null)\n                                this.AddItem(new OpenWithItem(commandKey.Name));\n                        }\n                    }\n                }\n            }\n        }\n\n        private void AddNewItem()\n        {\n            NewItem newItem = new NewItem();\n            this.InsertItem(newItem, 0);\n            newItem.AddNewItem += () =>\n            {\n                using(NewOpenWithDialog dlg = new NewOpenWithDialog())\n                {\n                    if(dlg.ShowDialog() == DialogResult.OK)\n                        this.InsertItem(new OpenWithItem(dlg.RegPath), 2);\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/RuleItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    class RuleItem : FoldSubItem, IBtnShowMenuItem, ITsiWebSearchItem\n    {\n        public RuleItem(ItemInfo info)\n        {\n            this.Text = info.Text;\n            this.Image = info.Image;\n            this.RestartExplorer = info.RestartExplorer;\n            BtnShowMenu = new MenuButton(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            this.ContextMenuStrip = new ContextMenuStrip();\n            this.ContextMenuStrip.Items.Add(TsiSearch);\n        }\n\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n\n        public bool RestartExplorer { get; set; }\n\n        public string SearchText\n        {\n            get\n            {\n                if(this.FoldGroupItem == null) return this.Text;\n                else return $\"{FoldGroupItem.Text} {this.Text}\";\n            }\n        }\n    }\n\n    public struct ItemInfo\n    {\n        public string Text { get; set; }\n        public Image Image { get; set; }\n        public string Tip { get; set; }\n        public bool RestartExplorer { get; set; }\n    }\n\n    sealed class VisibleRegRuleItem : RuleItem, IChkVisibleItem, ITsiRegPathItem\n    {\n        public struct RegRule\n        {\n            public string RegPath { get; set; }\n            public string ValueName { get; set; }\n            public RegistryValueKind ValueKind { get; set; }\n            public object TurnOnValue { get; set; }\n            public object TurnOffValue { get; set; }\n            public RegRule(string regPath, string valueName, object turnOnValue,\n                object turnOffValue, RegistryValueKind valueKind = RegistryValueKind.DWord)\n            {\n                this.RegPath = regPath; this.ValueName = valueName;\n                this.TurnOnValue = turnOnValue; this.TurnOffValue = turnOffValue;\n                this.ValueKind = valueKind;\n            }\n        }\n\n        public struct RuleAndInfo\n        {\n            public RegRule[] Rules { get; set; }\n            public ItemInfo ItemInfo { get; set; }\n        }\n\n        private VisibleRegRuleItem(ItemInfo info) : base(info)\n        {\n            ChkVisible = new VisibleCheckBox(this);\n            ToolTipBox.SetToolTip(ChkVisible, info.Tip);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            this.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { new ToolStripSeparator(), TsiRegLocation });\n        }\n\n        public VisibleRegRuleItem(RegRule[] rules, ItemInfo info)\n            : this(info) { this.Rules = rules; }\n\n        public VisibleRegRuleItem(RegRule rule, ItemInfo info)\n            : this(info) { this.Rules = new[] { rule }; }\n\n        public VisibleRegRuleItem(RuleAndInfo ruleAndInfo)\n            : this(ruleAndInfo.Rules, ruleAndInfo.ItemInfo) { }\n\n        public RegRule[] Rules { get; set; }\n\n        public VisibleCheckBox ChkVisible { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n\n        public bool ItemVisible\n        {\n            get\n            {\n                for(int i = 0; i < Rules.Length; i++)\n                {\n                    RegRule rule = Rules[i];\n                    using(RegistryKey key = RegistryEx.GetRegistryKey(rule.RegPath))\n                    {\n                        string value = key?.GetValue(rule.ValueName)?.ToString().ToLower();\n                        string turnOnValue = rule.TurnOnValue?.ToString().ToLower();\n                        string turnOffValue = rule.TurnOffValue?.ToString().ToLower();\n                        if(value == null || key.GetValueKind(rule.ValueName) != rule.ValueKind)\n                        {\n                            if(i < Rules.Length - 1) continue;\n                        }\n                        if(value == turnOnValue) return true;\n                        if(value == turnOffValue) return false;\n                    }\n                }\n                return true;\n            }\n            set\n            {\n                foreach(RegRule rule in Rules)\n                {\n                    object data = value ? rule.TurnOnValue : rule.TurnOffValue;\n                    if(data != null)\n                    {\n                        Registry.SetValue(rule.RegPath, rule.ValueName, data, rule.ValueKind);\n                    }\n                    else\n                    {\n                        RegistryEx.DeleteValue(rule.RegPath, rule.ValueName);\n                    }\n                }\n                if(RestartExplorer) ExplorerRestarter.Show();\n            }\n        }\n\n        public string RegPath => Rules[0].RegPath;\n        public string ValueName => Rules[0].ValueName;\n\n        const string LM_SMWCPE = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\";\n        const string CU_SMWCPE = @\"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\";\n        const string LM_SMWCE = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\";\n        const string CU_SMWCE = @\"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\";\n        const string LM_SPMWE = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer\";\n        const string CU_SPMWE = @\"HKEY_CURRENT_USER\\Software\\Policies\\Microsoft\\Windows\\Explorer\";\n\n        public static readonly RuleAndInfo CustomFolder = new RuleAndInfo\n        {\n            Rules = new[] {\n                new RegRule(LM_SMWCPE, \"NoCustomizeThisFolder\", null, 1),\n                new RegRule(LM_SMWCPE, \"NoCustomizeWebView\", null, 1),\n                new RegRule(CU_SMWCPE, \"NoCustomizeThisFolder\", null, 1),\n                new RegRule(CU_SMWCPE, \"NoCustomizeWebView\", null, 1)\n            },\n            ItemInfo = new ItemInfo\n            {\n                Text = AppString.Other.CustomFolder,\n                Image = AppImage.Folder,\n                Tip = AppString.Tip.CustomFolder,\n                RestartExplorer = true\n            }\n        };\n\n        public static readonly RuleAndInfo NetworkDrive = new RuleAndInfo\n        {\n            Rules = new[] {\n                new RegRule(LM_SMWCPE, \"NoNetConnectDisconnect\", null, 1),\n                new RegRule(CU_SMWCPE, \"NoNetConnectDisconnect\", null, 1)\n            },\n            ItemInfo = new ItemInfo\n            {\n                Text = $\"{ResourceString.GetDirectString(\"@AppResolver.dll,-8556\")} && {ResourceString.GetDirectString(\"@AppResolver.dll,-8557\")}\",\n                Image = AppImage.NetworkDrive,\n                RestartExplorer = true\n            }\n        };\n\n        public static readonly RuleAndInfo RecycleBinProperties = new RuleAndInfo\n        {\n            Rules = new[] {\n                new RegRule(LM_SMWCPE, \"NoPropertiesRecycleBin\", null, 1),\n                new RegRule(CU_SMWCPE, \"NoPropertiesRecycleBin\", null, 1)\n            },\n            ItemInfo = new ItemInfo\n            {\n                Text = ResourceString.GetDirectString(\"@AppResolver.dll,-8553\"),\n                Image = AppImage.RecycleBin,\n                RestartExplorer = true\n            }\n        };\n\n        public static readonly RuleAndInfo SendToDrive = new RuleAndInfo\n        {\n            Rules = new[] {\n                new RegRule(LM_SMWCPE, \"NoDrivesInSendToMenu\", null, 1),\n                new RegRule(CU_SMWCPE, \"NoDrivesInSendToMenu\", null, 1)\n            },\n            ItemInfo = new ItemInfo\n            {\n                Text = ResourceString.GetDirectString(\"@shell32.dll,-9309\"),\n                Image = AppImage.Drive,\n                Tip = AppString.Tip.SendToDrive,\n                RestartExplorer = true\n            }\n        };\n\n        public static readonly RuleAndInfo DeferBuildSendTo = new RuleAndInfo\n        {\n            Rules = new[] {\n                new RegRule(LM_SMWCE, \"DelaySendToMenuBuild\", null, 1),\n                new RegRule(CU_SMWCE, \"DelaySendToMenuBuild\", null, 1)\n            },\n            ItemInfo = new ItemInfo\n            {\n                Text = AppString.Other.BuildSendtoMenu,\n                Image = AppImage.SendTo,\n                Tip = AppString.Tip.BuildSendtoMenu\n            }\n        };\n\n        public static readonly RuleAndInfo UseStoreOpenWith = new RuleAndInfo\n        {\n            Rules = new[] {\n                new RegRule(LM_SPMWE, \"NoUseStoreOpenWith\", null, 1),\n                new RegRule(CU_SPMWE, \"NoUseStoreOpenWith\", null, 1)\n            },\n            ItemInfo = new ItemInfo\n            {\n                Text = ResourceString.GetDirectString(\"@shell32.dll,-5383\"),\n                Image = AppImage.MicrosoftStore\n            }\n        };\n    }\n\n    sealed class NumberRegRuleItem : RuleItem, ITsiRegPathItem\n    {\n        public struct RegRule\n        {\n            public string RegPath { get; set; }\n            public string ValueName { get; set; }\n            public RegistryValueKind ValueKind { get; set; }\n            public int MaxValue { get; set; }\n            public int MinValue { get; set; }\n            public int DefaultValue { get; set; }\n        }\n\n        readonly NumericUpDown NudValue = new NumericUpDown\n        {\n            TextAlign = HorizontalAlignment.Center,\n            Width = 80.DpiZoom()\n        };\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n\n        public NumberRegRuleItem(RegRule rule, ItemInfo info) : base(info)\n        {\n            this.AddCtr(NudValue);\n            ToolTipBox.SetToolTip(NudValue, info.Tip);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            this.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { new ToolStripSeparator(), TsiRegLocation });\n            this.Rule = rule;\n            NudValue.Maximum = rule.MaxValue;\n            NudValue.Minimum = rule.MinValue;\n            NudValue.Font = new Font(this.Font.FontFamily, this.Font.Size + 3F);\n            NudValue.ValueChanged += (sender, e) =>\n            {\n                if(NudValue.Value == Rule.DefaultValue)\n                {\n                    NudValue.ForeColor = Color.FromArgb(0, 138, 217);\n                    NudValue.Font = new Font(NudValue.Font, FontStyle.Bold);\n                }\n                else\n                {\n                    NudValue.ForeColor = Color.Black;\n                    NudValue.Font = new Font(NudValue.Font, FontStyle.Regular);\n                }\n                this.ItemValue = (int)NudValue.Value;\n            };\n            NudValue.Value = ItemValue;\n        }\n\n        public string RegPath => Rule.RegPath;\n        public string ValueName => Rule.ValueName;\n        public RegRule Rule { get; set; }\n\n        public int ItemValue\n        {\n            get\n            {\n                object value = Registry.GetValue(Rule.RegPath, Rule.ValueName, null);\n                if(value == null) return Rule.DefaultValue;\n                int num = Convert.ToInt32(value);\n                if(num > Rule.MaxValue) return Rule.MaxValue;\n                if(num < Rule.MinValue) return Rule.MinValue;\n                else return num;\n            }\n            set\n            {\n                Registry.SetValue(Rule.RegPath, Rule.ValueName, value, Rule.ValueKind);\n                if(RestartExplorer) ExplorerRestarter.Show();\n            }\n        }\n    }\n\n    sealed class StringRegRuleItem : RuleItem, ITsiRegPathItem\n    {\n        public struct RegRule\n        {\n            public string RegPath { get; set; }\n            public string ValueName { get; set; }\n        }\n\n        readonly Label LblValue = new Label\n        {\n            BorderStyle = BorderStyle.FixedSingle,\n            ForeColor = Color.FromArgb(80, 80, 80),\n            Cursor = Cursors.Hand,\n            AutoSize = true\n        };\n\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n\n        public StringRegRuleItem(RegRule rule, ItemInfo info) : base(info)\n        {\n            this.AddCtr(LblValue);\n            ToolTipBox.SetToolTip(LblValue, info.Tip);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            this.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { new ToolStripSeparator(), TsiRegLocation });\n            this.Rule = rule;\n            LblValue.Text = ItemValue;\n            LblValue.Font = new Font(this.Font.FontFamily, this.Font.Size + 3F);\n            LblValue.MouseDown += (sender, e) =>\n            {\n                using(InputDialog dlg = new InputDialog())\n                {\n                    dlg.Title = AppString.Menu.ChangeText;\n                    dlg.Text = ItemValue;\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    ItemValue = LblValue.Text = dlg.Text;\n                }\n            };\n            LblValue.TextChanged += (sender, e) => ItemValue = LblValue.Text;\n        }\n\n        public string RegPath => Rule.RegPath;\n        public string ValueName => Rule.ValueName;\n        public RegRule Rule { get; set; }\n\n        public string ItemValue\n        {\n            get => Registry.GetValue(Rule.RegPath, Rule.ValueName, null)?.ToString();\n            set\n            {\n                Registry.SetValue(Rule.RegPath, Rule.ValueName, value);\n                if(RestartExplorer) ExplorerRestarter.Show();\n            }\n        }\n    }\n\n    sealed class VisbleIniRuleItem : RuleItem, IChkVisibleItem\n    {\n        public struct IniRule\n        {\n            public string IniPath { get; set; }\n            public string Section { get; set; }\n            public string KeyName { get; set; }\n            public string TurnOnValue { get; set; }\n            public string TurnOffValue { get; set; }\n        }\n\n        public VisbleIniRuleItem(IniRule rule, ItemInfo info) : base(info)\n        {\n            this.Rule = rule;\n            this.IniWriter = new IniWriter(rule.IniPath);\n            ChkVisible = new VisibleCheckBox(this);\n            ToolTipBox.SetToolTip(ChkVisible, info.Tip);\n        }\n\n        public IniRule Rule { get; set; }\n        public IniWriter IniWriter { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n        public bool ItemVisible\n        {\n            get => IniWriter.GetValue(Rule.Section, Rule.KeyName) == Rule.TurnOnValue;\n            set\n            {\n                IniWriter.SetValue(Rule.Section, Rule.KeyName, value ? Rule.TurnOnValue : Rule.TurnOffValue);\n                if(RestartExplorer) ExplorerRestarter.Show();\n            }\n        }\n    }\n\n    sealed class NumberIniRuleItem : RuleItem\n    {\n        public struct IniRule\n        {\n            public string IniPath { get; set; }\n            public string Section { get; set; }\n            public string KeyName { get; set; }\n            public int MaxValue { get; set; }\n            public int MinValue { get; set; }\n            public int DefaultValue { get; set; }\n        }\n\n        public NumberIniRuleItem(IniRule rule, ItemInfo info) : base(info)\n        {\n            this.AddCtr(NudValue);\n            this.Rule = rule;\n            this.IniWriter = new IniWriter(rule.IniPath);\n            ToolTipBox.SetToolTip(NudValue, info.Tip);\n            NudValue.Maximum = rule.MaxValue;\n            NudValue.Minimum = rule.MinValue;\n            NudValue.Font = new Font(this.Font.FontFamily, this.Font.Size + 3F);\n            NudValue.ValueChanged += (sender, e) =>\n            {\n                if(NudValue.Value == Rule.DefaultValue)\n                {\n                    NudValue.ForeColor = Color.FromArgb(0, 138, 217);\n                    NudValue.Font = new Font(NudValue.Font, FontStyle.Bold);\n                }\n                else\n                {\n                    NudValue.ForeColor = Color.Black;\n                    NudValue.Font = new Font(NudValue.Font, FontStyle.Regular);\n                }\n                this.ItemValue = (int)NudValue.Value;\n            };\n            NudValue.Value = ItemValue;\n        }\n\n        public IniRule Rule { get; set; }\n        public IniWriter IniWriter { get; set; }\n\n        readonly NumericUpDown NudValue = new NumericUpDown\n        {\n            TextAlign = HorizontalAlignment.Center,\n            Width = 80.DpiZoom()\n        };\n\n        public int ItemValue\n        {\n            get\n            {\n                string value = IniWriter.GetValue(Rule.Section, Rule.KeyName);\n                if(value.IsNullOrWhiteSpace()) return Rule.DefaultValue;\n                int num = Convert.ToInt32(value);\n                if(num > Rule.MaxValue) return Rule.MaxValue;\n                if(num < Rule.MinValue) return Rule.MinValue;\n                else return num;\n            }\n            set\n            {\n                IniWriter.SetValue(Rule.Section, Rule.KeyName, value);\n                if(RestartExplorer) ExplorerRestarter.Show();\n            }\n        }\n    }\n\n    sealed class StringIniRuleItem : RuleItem\n    {\n        public struct IniRule\n        {\n            public string IniPath { get; set; }\n            public string Secation { get; set; }\n            public string KeyName { get; set; }\n        }\n\n\n        readonly Label LblValue = new Label\n        {\n            BorderStyle = BorderStyle.FixedSingle,\n            ForeColor = Color.FromArgb(80, 80, 80),\n            Cursor = Cursors.Hand,\n            AutoSize = true\n        };\n\n        public StringIniRuleItem(IniRule rule, ItemInfo info) : base(info)\n        {\n            this.Rule = rule;\n            this.IniWriter = new IniWriter(rule.IniPath);\n            this.AddCtr(LblValue);\n            ToolTipBox.SetToolTip(LblValue, info.Tip);\n            LblValue.Text = ItemValue;\n            LblValue.Font = new Font(this.Font.FontFamily, this.Font.Size + 3F);\n            LblValue.MouseDown += (sender, e) =>\n            {\n                using(InputDialog dlg = new InputDialog())\n                {\n                    dlg.Title = AppString.Menu.ChangeText;\n                    dlg.Text = ItemValue;\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    ItemValue = LblValue.Text = dlg.Text;\n                }\n            };\n            LblValue.TextChanged += (sender, e) => ItemValue = LblValue.Text;\n        }\n\n        public IniRule Rule { get; set; }\n        public IniWriter IniWriter { get; set; }\n\n        public string ItemValue\n        {\n            get => IniWriter.GetValue(Rule.Secation, Rule.KeyName);\n            set\n            {\n                IniWriter.SetValue(Rule.Secation, Rule.KeyName, value);\n                if(RestartExplorer) ExplorerRestarter.Show();\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/SendToItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class SendToItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem, ITsiTextItem, ITsiAdministratorItem,\n        ITsiIconItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiDeleteItem, ITsiShortcutCommandItem\n    {\n        public SendToItem(string filePath)\n        {\n            InitializeComponents();\n            this.FilePath = filePath;\n        }\n\n        private string filePath;\n        public string FilePath\n        {\n            get => filePath;\n            set\n            {\n                filePath = value;\n                if(IsShortcut) this.ShellLink = new ShellLink(value);\n                this.Text = this.ItemText;\n                this.Image = this.ItemImage;\n            }\n        }\n\n        public ShellLink ShellLink { get; private set; }\n        private string FileExtension => Path.GetExtension(FilePath);\n        private bool IsShortcut => FileExtension.ToLower() == \".lnk\";\n        public string SearchText => $\"{AppString.SideBar.SendTo} {Text}\";\n        private Image ItemImage => ItemIcon?.ToBitmap() ?? AppImage.NotFound;\n\n        public string ItemFilePath\n        {\n            get\n            {\n                string path = null;\n                if(IsShortcut) path = ShellLink.TargetPath;\n                else\n                {\n                    using(RegistryKey root = Registry.ClassesRoot)\n                    using(RegistryKey extKey = root.OpenSubKey(FileExtension))\n                    {\n                        string guidPath = extKey?.GetValue(\"\")?.ToString();\n                        if(!string.IsNullOrEmpty(guidPath))\n                        {\n                            using(RegistryKey ipsKey = root.OpenSubKey($@\"{guidPath}\\InProcServer32\"))\n                            {\n                                path = ipsKey?.GetValue(\"\")?.ToString();\n                            }\n                        }\n                    }\n                }\n                if(!File.Exists(path) && !Directory.Exists(path)) path = FilePath;\n                return path;\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get => (File.GetAttributes(FilePath) & FileAttributes.Hidden) != FileAttributes.Hidden;\n            set\n            {\n                FileAttributes attributes = File.GetAttributes(FilePath);\n                if(value) attributes &= ~FileAttributes.Hidden;\n                else attributes |= FileAttributes.Hidden;\n                File.SetAttributes(FilePath, attributes);\n            }\n        }\n\n        public string ItemText\n        {\n            get\n            {\n                string name = DesktopIni.GetLocalizedFileNames(FilePath, true);\n                if(name == string.Empty) name = Path.GetFileNameWithoutExtension(FilePath);\n                if(name == string.Empty) name = FileExtension;\n                return name;\n            }\n            set\n            {\n                DesktopIni.SetLocalizedFileNames(FilePath, value);\n                this.Text = ResourceString.GetDirectString(value);\n                ExplorerRestarter.Show();\n            }\n        }\n\n        public Icon ItemIcon\n        {\n            get\n            {\n                Icon icon = ResourceIcon.GetIcon(IconLocation, out string iconPath, out int iconIndex);\n                IconPath = iconPath; IconIndex = iconIndex;\n                if(icon != null) return icon;\n                if(IsShortcut)\n                {\n                    string path = ItemFilePath;\n                    if(File.Exists(path)) icon = ResourceIcon.GetExtensionIcon(path);\n                    else if(Directory.Exists(path)) icon = ResourceIcon.GetFolderIcon(path);\n                }\n                if(icon == null) icon = ResourceIcon.GetExtensionIcon(FileExtension);\n                return icon;\n            }\n        }\n\n        public string IconLocation\n        {\n            get\n            {\n                string location = null;\n                if(IsShortcut)\n                {\n                    ShellLink.ICONLOCATION iconLocation = ShellLink.IconLocation;\n                    string iconPath = iconLocation.IconPath;\n                    int iconIndex = iconLocation.IconIndex;\n                    if(string.IsNullOrEmpty(iconPath)) iconPath = ShellLink.TargetPath;\n                    location = $@\"{iconPath},{iconIndex}\";\n                }\n                else\n                {\n                    using(RegistryKey root = Registry.ClassesRoot)\n                    using(RegistryKey extensionKey = root.OpenSubKey(FileExtension))\n                    {\n                        string guidPath = extensionKey.GetValue(\"\")?.ToString();\n                        if(guidPath != null)\n                        {\n                            using(RegistryKey guidKey = root.OpenSubKey($@\"{guidPath}\\DefaultIcon\"))\n                            {\n                                location = guidKey.GetValue(\"\")?.ToString();\n                            }\n                        }\n                    }\n                }\n                return location;\n            }\n            set\n            {\n                if(IsShortcut)\n                {\n                    ShellLink.IconLocation = new ShellLink.ICONLOCATION\n                    {\n                        IconPath = this.IconPath,\n                        IconIndex = this.IconIndex\n                    };\n                    ShellLink.Save();\n                }\n                else\n                {\n                    using(RegistryKey root = Registry.ClassesRoot)\n                    using(RegistryKey extensionKey = root.OpenSubKey(FileExtension))\n                    {\n                        string guidPath = extensionKey.GetValue(\"\")?.ToString();\n                        if(guidPath != null)\n                        {\n                            string regPath = $@\"{root.Name}\\{guidPath}\\DefaultIcon\";\n                            RegTrustedInstaller.TakeRegTreeOwnerShip(regPath);\n                            Registry.SetValue(regPath, \"\", value);\n                            ExplorerRestarter.Show();\n                        }\n                    }\n                }\n            }\n        }\n\n        public string IconPath { get; set; }\n        public int IconIndex { get; set; }\n\n        public VisibleCheckBox ChkVisible { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        public ChangeIconMenuItem TsiChangeIcon { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public ShortcutCommandMenuItem TsiChangeCommand { get; set; }\n        public RunAsAdministratorItem TsiAdministrator { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            TsiChangeIcon = new ChangeIconMenuItem(this);\n            TsiChangeCommand = new ShortcutCommandMenuItem(this);\n            TsiAdministrator = new RunAsAdministratorItem(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText, new ToolStripSeparator(),\n                TsiChangeIcon, new ToolStripSeparator(), TsiAdministrator, new ToolStripSeparator(),\n                TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),\n                TsiChangeCommand, TsiFileProperties, TsiFileLocation });\n\n            ContextMenuStrip.Opening += (sender, e) => TsiChangeCommand.Visible = IsShortcut;\n\n            TsiChangeCommand.Click += (sender, e) =>\n            {\n                if(TsiChangeCommand.ChangeCommand(ShellLink))\n                {\n                    Image = this.ItemImage;\n                }\n            };\n        }\n\n        public void DeleteMe()\n        {\n            File.Delete(this.FilePath);\n            DesktopIni.DeleteLocalizedFileNames(FilePath);\n            this.ShellLink?.Dispose();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/SendToList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class SendToList : MyList\n    {\n        private static readonly string SendToPath = Environment.ExpandEnvironmentVariables(@\"%AppData%\\Microsoft\\Windows\\SendTo\");\n        private static readonly string DefaultSendToPath = Environment.ExpandEnvironmentVariables(@\"%SystemDrive%\\Users\\Default\\AppData\\Roaming\\Microsoft\\Windows\\SendTo\");\n\n        public void LoadItems()\n        {\n            foreach(string path in Directory.GetFileSystemEntries(SendToPath))\n            {\n                if(Path.GetFileName(path).ToLower() == \"desktop.ini\") continue;\n                this.AddItem(new SendToItem(path));\n            }\n            this.SortItemByText();\n            this.AddNewItem();\n            this.AddDirItem();\n            this.AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.SendToDrive));\n            this.AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.DeferBuildSendTo));\n        }\n\n        private void AddNewItem()\n        {\n            NewItem newItem = new NewItem();\n            this.InsertItem(newItem, 0);\n            newItem.AddNewItem += () =>\n            {\n                using(NewLnkFileDialog dlg = new NewLnkFileDialog())\n                {\n                    dlg.FileFilter = $\"{AppString.Dialog.Program}|*.exe;*.bat;*.cmd;*.vbs;*.vbe;*.js;*.jse;*.wsf\";\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    string lnkPath = $@\"{SendToPath}\\{ObjectPath.RemoveIllegalChars(dlg.ItemText)}.lnk\";\n                    lnkPath = ObjectPath.GetNewPathWithIndex(lnkPath, ObjectPath.PathType.File);\n                    using(ShellLink shellLink = new ShellLink(lnkPath))\n                    {\n                        shellLink.TargetPath = dlg.ItemFilePath;\n                        shellLink.WorkingDirectory = Path.GetDirectoryName(dlg.ItemFilePath);\n                        shellLink.Arguments = dlg.Arguments;\n                        shellLink.Save();\n                    }\n                    DesktopIni.SetLocalizedFileNames(lnkPath, dlg.ItemText);\n                    this.InsertItem(new SendToItem(lnkPath), 2);\n                }\n            };\n        }\n\n        private void AddDirItem()\n        {\n            MyListItem item = new MyListItem\n            {\n                Text = Path.GetFileNameWithoutExtension(SendToPath),\n                Image = ResourceIcon.GetFolderIcon(SendToPath).ToBitmap()\n            };\n            PictureButton btnPath = new PictureButton(AppImage.Open);\n            ToolTipBox.SetToolTip(btnPath, AppString.Menu.FileLocation);\n            btnPath.MouseDown += (sender, e) => ExternalProgram.OpenDirectory(SendToPath);\n            item.AddCtr(btnPath);\n            this.InsertItem(item, 1);\n            item.ContextMenuStrip = new ContextMenuStrip();\n            ToolStripMenuItem tsiRestoreDefault = new ToolStripMenuItem(AppString.Menu.RestoreDefault);\n            item.ContextMenuStrip.Items.Add(tsiRestoreDefault);\n            tsiRestoreDefault.Enabled = Directory.Exists(DefaultSendToPath);\n            tsiRestoreDefault.Click += (sender, e) =>\n            {\n                if(AppMessageBox.Show(AppString.Message.RestoreDefault, MessageBoxButtons.OKCancel) == DialogResult.OK)\n                {\n                    File.SetAttributes(SendToPath, FileAttributes.Normal);\n                    Directory.Delete(SendToPath, true);\n                    Directory.CreateDirectory(SendToPath);\n                    File.SetAttributes(SendToPath, File.GetAttributes(DefaultSendToPath));\n                    foreach(string srcPath in Directory.GetFiles(DefaultSendToPath))\n                    {\n                        string dstPath = $@\"{SendToPath}\\{Path.GetFileName(srcPath)}\";\n                        File.Copy(srcPath, dstPath);\n                    }\n                    this.ClearItems();\n                    this.LoadItems();\n                }\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellExItem.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ShellExItem : FoldSubItem, IChkVisibleItem, IBtnShowMenuItem, ITsiGuidItem,\n        ITsiWebSearchItem, ITsiFilePathItem, ITsiRegPathItem, ITsiRegDeleteItem, ITsiRegExportItem, IProtectOpenItem\n    {\n        public static Dictionary<string, Guid> GetPathAndGuids(string shellExPath, bool isDragDrop = false)\n        {\n            Dictionary<string, Guid> dic = new Dictionary<string, Guid>();\n            string[] parts = isDragDrop ? DdhParts : CmhParts;\n            foreach(string part in parts)\n            {\n                using(RegistryKey cmKey = RegistryEx.GetRegistryKey($@\"{shellExPath}\\{part}\"))\n                {\n                    if(cmKey == null) continue;\n                    foreach(string keyName in cmKey.GetSubKeyNames())\n                    {\n                        try\n                        {\n                            using(RegistryKey key = cmKey.OpenSubKey(keyName))\n                            {\n                                if(!GuidEx.TryParse(key.GetValue(\"\")?.ToString(), out Guid guid))\n                                    GuidEx.TryParse(keyName, out guid);\n                                if(!guid.Equals(Guid.Empty))\n                                    dic.Add(key.Name, guid);\n                            }\n                        }\n                        catch { continue; }\n                    }\n                }\n            }\n            return dic;\n        }\n\n        public static readonly string[] DdhParts = { \"DragDropHandlers\", \"-DragDropHandlers\" };\n        public static readonly string[] CmhParts = { \"ContextMenuHandlers\", \"-ContextMenuHandlers\" };\n        public static readonly Guid LnkOpenGuid = new Guid(\"00021401-0000-0000-c000-000000000046\");\n\n        public ShellExItem(Guid guid, string regPath)\n        {\n            InitializeComponents();\n            this.Guid = guid;\n            this.RegPath = regPath;\n        }\n\n        private string regPath;\n        public string RegPath\n        {\n            get => regPath;\n            set\n            {\n                regPath = value;\n                this.Text = this.ItemText;\n                this.Image = GuidInfo.GetImage(Guid);\n            }\n        }\n\n        public Guid Guid { get; set; }\n        public string ValueName => null;\n        public string SearchText => Text;\n        public string ItemFilePath => GuidInfo.GetFilePath(Guid);\n        private string KeyName => RegistryEx.GetKeyName(RegPath);\n        private string ParentPath => RegistryEx.GetParentPath(RegPath);\n        private string ShellExPath => RegistryEx.GetParentPath(ParentPath);\n        private string ParentKeyName => RegistryEx.GetKeyName(ParentPath);\n        private string DefaultValue => Registry.GetValue(RegPath, \"\", null)?.ToString();\n        public string ItemText => GuidInfo.GetText(Guid) ?? (KeyName.Equals(Guid.ToString(\"B\"), StringComparison.OrdinalIgnoreCase) ? DefaultValue : KeyName);\n        public bool IsDragDropItem => ParentKeyName.EndsWith(DdhParts[0], StringComparison.OrdinalIgnoreCase);\n\n        private string BackupPath\n        {\n            get\n            {\n                string[] parts = IsDragDropItem ? DdhParts : CmhParts;\n                return $@\"{ShellExPath}\\{(ItemVisible ? parts[1] : parts[0])}\\{KeyName}\";\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get\n            {\n                string[] parts = IsDragDropItem ? DdhParts : CmhParts;\n                return ParentKeyName.Equals(parts[0], StringComparison.OrdinalIgnoreCase);\n            }\n            set\n            {\n                try\n                {\n                    RegistryEx.MoveTo(RegPath, BackupPath);\n                }\n                catch\n                {\n                    AppMessageBox.Show(AppString.Message.AuthorityProtection);\n                    return;\n                }\n                RegPath = BackupPath;\n            }\n        }\n\n        public MenuButton BtnShowMenu { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n        public DetailedEditButton BtnDetailedEdit { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public RegExportMenuItem TsiRegExport { get; set; }\n        public HandleGuidMenuItem TsiHandleGuid { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            BtnDetailedEdit = new DetailedEditButton(this);\n            TsiHandleGuid = new HandleGuidMenuItem(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiRegExport = new RegExportMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiHandleGuid, new ToolStripSeparator(),\n                TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),\n                TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport});\n\n            ContextMenuStrip.Opening += (sender, e) => TsiDeleteMe.Enabled = !(Guid.Equals(LnkOpenGuid) && AppConfig.ProtectOpenItem);\n            ChkVisible.PreCheckChanging += TryProtectOpenItem;\n        }\n\n        public bool TryProtectOpenItem()\n        {\n            if(!ChkVisible.Checked || !Guid.Equals(LnkOpenGuid) || !AppConfig.ProtectOpenItem) return true;\n            return AppMessageBox.Show(AppString.Message.PromptIsOpenItem, MessageBoxButtons.YesNo) == DialogResult.Yes;\n        }\n\n        public void DeleteMe()\n        {\n            RegistryEx.DeleteKeyTree(this.RegPath, true);\n            RegistryEx.DeleteKeyTree(this.BackupPath);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellExecuteDialog.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ShellExecuteDialog : CommonDialog\n    {\n        public string Verb { get; set; }\n        public int WindowStyle { get; set; }\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(ShellExecuteForm frm = new ShellExecuteForm())\n            {\n                frm.TopMost = AppConfig.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag)\n                {\n                    this.Verb = frm.Verb;\n                    this.WindowStyle = frm.WindowStyle;\n                }\n                return flag;\n            }\n        }\n\n        public static string GetCommand(string fileName, string arguments, string verb, int windowStyle, string directory = null)\n        {\n            arguments = arguments.Replace(\"\\\"\", \"\\\"\\\"\");\n            if(directory == null)\n            {\n                ObjectPath.GetFullFilePath(fileName, out string filePath);\n                directory = Path.GetDirectoryName(filePath);\n            }\n            return \"mshta vbscript:createobject(\\\"shell.application\\\").shellexecute\" +\n                $\"(\\\"{fileName}\\\",\\\"{arguments}\\\",\\\"{directory}\\\",\\\"{verb}\\\",{windowStyle})(close)\";\n        }\n\n        sealed class ShellExecuteForm : Form\n        {\n            private const string ApiInfoUrl = \"https://docs.microsoft.com/windows/win32/api/shellapi/nf-shellapi-shellexecutea\";\n            private static readonly string[] Verbs = new[] { \"open\", \"runas\", \"edit\", \"print\", \"find\", \"explore\" };\n            public ShellExecuteForm()\n            {\n                this.SuspendLayout();\n                this.HelpButton = true;\n                this.Text = \"ShellExecute\";\n                this.AcceptButton = btnOK;\n                this.CancelButton = btnCancel;\n                this.Font = SystemFonts.MenuFont;\n                this.FormBorderStyle = FormBorderStyle.FixedSingle;\n                this.StartPosition = FormStartPosition.CenterParent;\n                this.ShowIcon = ShowInTaskbar = MaximizeBox = MinimizeBox = false;\n                this.HelpButtonClicked += (sender, e) => ExternalProgram.OpenWebUrl(ApiInfoUrl);\n                this.InitializeComponents();\n                this.ResumeLayout();\n            }\n            public string Verb { get; set; }\n            public int WindowStyle { get; set; }\n\n            readonly RadioButton[] rdoVerbs = new RadioButton[6];\n            readonly GroupBox grpVerb = new GroupBox { Text = \"Verb\" };\n            readonly Label lblStyle = new Label\n            {\n                Text = \"WindowStyle\",\n                AutoSize = true\n            };\n            readonly NumericUpDown nudStyle = new NumericUpDown\n            {\n                TextAlign = HorizontalAlignment.Center,\n                Width = 80.DpiZoom(),\n                Maximum = 10,\n                Minimum = 0,\n                Value = 1\n            };\n            readonly Button btnOK = new Button\n            {\n                Text = ResourceString.OK,\n                DialogResult = DialogResult.OK,\n                AutoSize = true\n            };\n            readonly Button btnCancel = new Button\n            {\n                Text = ResourceString.Cancel,\n                DialogResult = DialogResult.Cancel,\n                AutoSize = true\n            };\n\n            private void InitializeComponents()\n            {\n                this.Controls.AddRange(new Control[] { grpVerb, lblStyle, nudStyle, btnOK, btnCancel });\n                int a = 10.DpiZoom();\n                int b = 2 * a;\n                for(int i = 0; i < 6; i++)\n                {\n                    rdoVerbs[i] = new RadioButton\n                    {\n                        Text = Verbs[i],\n                        AutoSize = true,\n                        Parent = grpVerb,\n                        Location = new Point(a, b + a)\n                    };\n                    if(i > 0) rdoVerbs[i].Left += rdoVerbs[i - 1].Right;\n                }\n                rdoVerbs[0].Checked = true;\n                grpVerb.Width = rdoVerbs[5].Right + a;\n                grpVerb.Height = rdoVerbs[5].Bottom + b;\n                lblStyle.Left = grpVerb.Left = grpVerb.Top = b;\n                btnOK.Top = btnCancel.Top = lblStyle.Top = nudStyle.Top = grpVerb.Bottom + b;\n                nudStyle.Left = lblStyle.Right + b;\n                btnCancel.Left = grpVerb.Right - btnCancel.Width;\n                btnOK.Left = btnCancel.Left - btnOK.Width - b;\n                this.ClientSize = new Size(btnCancel.Right + b, btnCancel.Bottom + b);\n                btnOK.Click += (sender, e) =>\n                {\n                    for(int i = 0; i < 6; i++)\n                    {\n                        if(rdoVerbs[i].Checked)\n                        {\n                            this.Verb = rdoVerbs[i].Text;\n                            break;\n                        }\n                    }\n                    this.WindowStyle = (int)nudStyle.Value;\n                };\n            }\n        }\n    }\n\n    sealed class ShellExecuteCheckBox : CheckBox\n    {\n        public ShellExecuteCheckBox()\n        {\n            this.Text = \"ShellExecute\";\n            this.AutoSize = true;\n            //this.Font = SystemFonts.DialogFont;\n            //this.Font = new Font(this.Font.FontFamily, this.Font.Size - 1F);\n        }\n\n        public string Verb { get; set; }\n        public int WindowStyle { get; set; }\n\n        readonly ToolTip ttpInfo = new ToolTip { InitialDelay = 1 };\n\n        protected override void OnClick(EventArgs e)\n        {\n            if(this.Checked)\n            {\n                this.Checked = false;\n                ttpInfo.RemoveAll();\n            }\n            else\n            {\n                using(ShellExecuteDialog dlg = new ShellExecuteDialog())\n                {\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    this.Verb = dlg.Verb;\n                    this.WindowStyle = dlg.WindowStyle;\n                    this.Checked = true;\n                    ttpInfo.SetToolTip(this, $\"Verb: \\\"{Verb}\\\"\\nWindowStyle: {WindowStyle}\");\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    class ShellItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem, ITsiTextItem, ITsiCommandItem, IProtectOpenItem,\n        ITsiIconItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiRegPathItem, ITsiRegDeleteItem, ITsiRegExportItem\n    {\n        /// <summary>Shell公共引用子菜单注册表项路径</summary>\n        public const string CommandStorePath = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CommandStore\\shell\";\n\n        private const string OpenInNewWindowPath = @\"HKEY_CLASSES_ROOT\\Folder\\shell\\opennewwindow\";\n\n        /// <summary>Shell类型菜单特殊注册表项名默认名称</summary>\n        /// <remarks>字符串资源在windows.storage.dll里面</remarks>\n        private static readonly Dictionary<string, int> DefaultNameIndexs\n            = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase)\n            {\n                { \"open\", 8496 }, { \"edit\", 8516 }, { \"print\", 8497 }, { \"find\", 8503 },\n                { \"play\", 8498 }, { \"runas\", 8505 }, { \"explore\", 8502 }, { \"preview\", 8499 }\n            };\n\n        /// <summary>菜单项目在菜单中出现的位置</summary>\n        enum Positions { Default, Top, Bottom }\n\n        public ShellItem(string regPath)\n        {\n            InitializeComponents();\n            this.RegPath = regPath;\n        }\n\n        private string regPath;\n        public string RegPath\n        {\n            get => regPath;\n            set\n            {\n                regPath = value;\n                this.Text = this.ItemText;\n                this.Image = this.ItemIcon.ToBitmap();\n                if(!HasIcon) this.Image = Image.ToTransparent();\n                BtnSubItems.Visible = IsMultiItem;\n            }\n        }\n\n        public string ValueName => null;\n        public string SearchText => Text;\n        private string CommandPath => $@\"{RegPath}\\command\";\n        public string KeyName => RegistryEx.GetKeyName(RegPath);\n        protected virtual bool IsSubItem => false;\n        private bool IsOpenItem => KeyName.ToLower() == \"open\";\n        public string ItemFilePath => GuidInfo.GetFilePath(Guid) ?? ObjectPath.ExtractFilePath(ItemCommand);\n        private bool HasIcon => !IconLocation.IsNullOrWhiteSpace() || HasLUAShield;\n\n        private bool IsMultiItem\n        {\n            get\n            {\n                object value = Registry.GetValue(RegPath, \"SubCommands\", null);\n                if(value != null) return true;\n                value = Registry.GetValue(RegPath, \"ExtendedSubCommandsKey\", null);\n                if(!string.IsNullOrEmpty(value?.ToString())) return true;\n                return false;\n            }\n        }\n\n        private bool OnlyInExplorer\n        {\n            get => Registry.GetValue(RegPath, \"OnlyInBrowserWindow\", null) != null;\n            set\n            {\n                if(value)\n                {\n                    if(!TryProtectOpenItem()) return;\n                    Registry.SetValue(RegPath, \"OnlyInBrowserWindow\", \"\");\n                }\n                else RegistryEx.DeleteValue(RegPath, \"OnlyInBrowserWindow\");\n            }\n        }\n\n        private bool OnlyWithShift\n        {\n            get => Registry.GetValue(RegPath, \"Extended\", null) != null;\n            set\n            {\n                if(value)\n                {\n                    if(!TryProtectOpenItem()) return;\n                    Registry.SetValue(RegPath, \"Extended\", \"\");\n                }\n                else RegistryEx.DeleteValue(RegPath, \"Extended\");\n            }\n        }\n\n        private bool NoWorkingDirectory\n        {\n            get => Registry.GetValue(RegPath, \"NoWorkingDirectory\", null) != null;\n            set\n            {\n                if(!TryProtectOpenItem()) return;\n                if(value) Registry.SetValue(RegPath, \"NoWorkingDirectory\", \"\");\n                else RegistryEx.DeleteValue(RegPath, \"NoWorkingDirectory\");\n            }\n        }\n\n        private bool NeverDefault\n        {\n            get => Registry.GetValue(RegPath, \"NeverDefault\", null) != null;\n            set\n            {\n                if(!TryProtectOpenItem()) return;\n                if(value) Registry.SetValue(RegPath, \"NeverDefault\", \"\");\n                else RegistryEx.DeleteValue(RegPath, \"NeverDefault\");\n            }\n        }\n\n        private bool ShowAsDisabledIfHidden\n        {\n            get => Registry.GetValue(RegPath, \"ShowAsDisabledIfHidden\", null) != null;\n            set\n            {\n                if(!TryProtectOpenItem()) return;\n                if(value) Registry.SetValue(RegPath, \"ShowAsDisabledIfHidden\", \"\");\n                else RegistryEx.DeleteValue(RegPath, \"ShowAsDisabledIfHidden\");\n                if(value && !ItemVisible) ItemVisible = false;\n            }\n        }\n\n        private Positions ItemPosition\n        {\n            get\n            {\n                string value = Registry.GetValue(RegPath, \"Position\", null)?.ToString()?.ToLower();\n                switch(value)\n                {\n                    case \"top\":\n                        return Positions.Top;\n                    case \"bottom\":\n                        return Positions.Bottom;\n                    default:\n                        return Positions.Default;\n                }\n            }\n            set\n            {\n                switch(value)\n                {\n                    case Positions.Top:\n                        Registry.SetValue(RegPath, \"Position\", \"top\");\n                        break;\n                    case Positions.Bottom:\n                        Registry.SetValue(RegPath, \"Position\", \"bottom\");\n                        break;\n                    case Positions.Default:\n                        RegistryEx.DeleteValue(RegPath, \"Position\");\n                        break;\n                }\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get\n            {\n                if(WinOsVersion.Current >= WinOsVersion.Win10_1703)\n                {\n                    //HideBasedOnVelocityId键值仅适用于Win10系统1703以上版本\n                    if(Convert.ToInt32(Registry.GetValue(RegPath, \"HideBasedOnVelocityId\", 0)) == 0x639bc8) return false;\n                }\n                if(!IsSubItem)\n                {\n                    //LegacyDisable和ProgrammaticAccessOnly键值不适用于子菜单\n                    if(Registry.GetValue(RegPath, \"LegacyDisable\", null) != null) return false;\n                    if(Registry.GetValue(RegPath, \"ProgrammaticAccessOnly\", null) != null) return false;\n                    //CommandFlags键值不适用于Vista系统，子菜单中该键值我用来做分割线键值\n                    if(WinOsVersion.Current > WinOsVersion.Vista && Convert.ToInt32(Registry.GetValue(RegPath, \"CommandFlags\", 0)) % 16 >= 8) return false;\n                }\n                return true;\n            }\n            set\n            {\n                try\n                {\n                    void DeleteSomeValues()\n                    {\n                        RegistryEx.DeleteValue(RegPath, \"LegacyDisable\");\n                        RegistryEx.DeleteValue(RegPath, \"ProgrammaticAccessOnly\");\n                        if(WinOsVersion.Current > WinOsVersion.Vista && Convert.ToInt32(Registry.GetValue(RegPath, \"CommandFlags\", 0)) % 16 >= 8)\n                        {\n                            RegistryEx.DeleteValue(RegPath, \"CommandFlags\");\n                        }\n                    };\n\n                    if(value)\n                    {\n                        RegistryEx.DeleteValue(RegPath, \"HideBasedOnVelocityId\");\n                        DeleteSomeValues();\n                    }\n                    else\n                    {\n                        if(WinOsVersion.Current >= WinOsVersion.Win10_1703)\n                        {\n                            Registry.SetValue(RegPath, \"HideBasedOnVelocityId\", 0x639bc8);\n                        }\n                        else\n                        {\n                            if(IsSubItem)\n                            {\n                                AppMessageBox.Show(AppString.Message.CannotHideSubItem);\n                                return;\n                            }\n                        }\n                        if(!IsSubItem)\n                        {\n                            //当LegaryDisable键值作用于文件夹-\"在新窗口中打开\"时\n                            //会导致点击任务栏explorer图标和 Win+E 快捷键错误访问\n                            if(!RegPath.StartsWith(OpenInNewWindowPath, StringComparison.OrdinalIgnoreCase))\n                            {\n                                Registry.SetValue(RegPath, \"LegacyDisable\", \"\");\n                            }\n                            Registry.SetValue(RegPath, \"ProgrammaticAccessOnly\", \"\");\n                        }\n                        if(ShowAsDisabledIfHidden) DeleteSomeValues();\n                    }\n                }\n                catch\n                {\n                    AppMessageBox.Show(AppString.Message.AuthorityProtection);\n                }\n            }\n        }\n\n        public string ItemText\n        {\n            get\n            {\n                string name;\n                //菜单名称优先级别：MUIVerb > 默认值 > 特殊键值名 > 项名\n                List<string> valueNames = new List<string> { \"MUIVerb\" };\n                if(!IsMultiItem) valueNames.Add(\"\");//多级母菜单不支持使用默认值作为名称\n                foreach(string valueName in valueNames)\n                {\n                    name = Registry.GetValue(RegPath, valueName, null)?.ToString();\n                    name = ResourceString.GetDirectString(name);\n                    if(!string.IsNullOrEmpty(name)) return name;\n                }\n                if(DefaultNameIndexs.TryGetValue(KeyName, out int index))\n                {\n                    name = $\"@windows.storage.dll,-{index}\";\n                    name = ResourceString.GetDirectString(name);\n                    if(!string.IsNullOrEmpty(name)) return name;\n                }\n                return KeyName;\n            }\n            set\n            {\n                //MUIVerb长度不可超过80,超过80系统会隐藏该菜单项目\n                if(ResourceString.GetDirectString(value).Length >= 80)\n                {\n                    AppMessageBox.Show(AppString.Message.TextLengthCannotExceed80);\n                }\n                else\n                {\n                    Registry.SetValue(RegPath, \"MUIVerb\", value);\n                    this.Text = ResourceString.GetDirectString(value);\n                }\n            }\n        }\n\n        public string ItemCommand\n        {\n            get\n            {\n                if(IsMultiItem) return null;\n                else return Registry.GetValue(CommandPath, \"\", null)?.ToString();\n            }\n            set\n            {\n                if(!TryProtectOpenItem()) return;\n                Registry.SetValue(CommandPath, \"\", value);\n                if(!this.HasIcon) this.Image = this.ItemIcon.ToBitmap().ToTransparent();\n            }\n        }\n\n        private bool HasLUAShield\n        {\n            get => Registry.GetValue(RegPath, \"HasLUAShield\", null) != null;\n            set\n            {\n                if(value) Registry.SetValue(RegPath, \"HasLUAShield\", \"\");\n                else RegistryEx.DeleteValue(RegPath, \"HasLUAShield\");\n            }\n        }\n\n        public string IconLocation\n        {\n            get => Registry.GetValue(RegPath, \"Icon\", null)?.ToString();\n            set\n            {\n                if(value != null) Registry.SetValue(RegPath, \"Icon\", value);\n                else RegistryEx.DeleteValue(RegPath, \"Icon\");\n            }\n        }\n\n        public string IconPath { get; set; }\n        public int IconIndex { get; set; }\n        public Icon ItemIcon\n        {\n            get\n            {\n                //菜单图标优先级别：Icon > HasLUAShield\n                //只要有Icon键值，不论数据是否为空，HasLUAShield键值就不起作用\n                Icon icon;\n                string iconPath;\n                int iconIndex;\n                if(IconLocation != null)\n                {\n                    icon = ResourceIcon.GetIcon(IconLocation, out iconPath, out iconIndex);\n                    if(icon == null && Path.GetExtension(iconPath)?.ToLower() == \".exe\")//文件不存在，或为没有图标的exe文件\n                        icon = ResourceIcon.GetIcon(iconPath = \"imageres.dll\", iconIndex = -15);//不含图标的默认exe图标\n                }\n                else if(HasLUAShield)\n                    icon = ResourceIcon.GetIcon(iconPath = \"imageres.dll\", iconIndex = -78);//管理员小盾牌图标\n                else icon = ResourceIcon.GetIcon(iconPath = ItemFilePath, iconIndex = 0);//文件第一个图标\n                if(icon == null) icon = ResourceIcon.GetExtensionIcon(iconPath = ItemFilePath)//文件类型图标\n                        ?? ResourceIcon.GetIcon(iconPath = \"imageres.dll\", iconIndex = -2);//图标资源不存在，白纸图标\n                IconPath = iconPath;\n                IconIndex = iconIndex;\n                return icon;\n            }\n        }\n\n        private Guid Guid\n        {\n            get\n            {\n                Dictionary<string, string> keyValues = new Dictionary<string, string>\n                {\n                    { CommandPath , \"DelegateExecute\" },\n                    { $@\"{RegPath}\\DropTarget\" , \"CLSID\" },\n                    { RegPath , \"ExplorerCommandHandler\" },\n                };\n                foreach(var item in keyValues)\n                {\n                    string value = Registry.GetValue(item.Key, item.Value, null)?.ToString();\n                    if(GuidEx.TryParse(value, out Guid guid)) return guid;\n                }\n                return Guid.Empty;\n            }\n        }\n\n        public VisibleCheckBox ChkVisible { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        public ChangeIconMenuItem TsiChangeIcon { get; set; }\n        public ChangeCommandMenuItem TsiChangeCommand { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public RegExportMenuItem TsiRegExport { get; set; }\n\n        protected readonly PictureButton BtnSubItems = new PictureButton(AppImage.SubItems);\n        protected readonly ToolStripMenuItem TsiOtherAttributes = new ToolStripMenuItem(AppString.Menu.OtherAttributes);\n        readonly ToolStripMenuItem TsiItemIcon = new ToolStripMenuItem(AppString.Menu.ItemIcon);\n        readonly ToolStripMenuItem TsiDeleteIcon = new ToolStripMenuItem(AppString.Menu.DeleteIcon);\n        readonly ToolStripMenuItem TsiShieldIcon = new ToolStripMenuItem(AppString.Menu.ShieldIcon);\n        readonly ToolStripMenuItem TsiPosition = new ToolStripMenuItem(AppString.Menu.ItemPosition);\n        readonly ToolStripMenuItem TsiDefault = new ToolStripMenuItem(AppString.Menu.SetDefault);\n        readonly ToolStripMenuItem TsiSetTop = new ToolStripMenuItem(AppString.Menu.SetTop);\n        readonly ToolStripMenuItem TsiSetBottom = new ToolStripMenuItem(AppString.Menu.SetBottom);\n        readonly ToolStripMenuItem TsiOnlyWithShift = new ToolStripMenuItem(AppString.Menu.OnlyWithShift);\n        readonly ToolStripMenuItem TsiOnlyInExplorer = new ToolStripMenuItem(AppString.Menu.OnlyInExplorer);\n        readonly ToolStripMenuItem TsiNoWorkDir = new ToolStripMenuItem(AppString.Menu.NoWorkingDirectory);\n        readonly ToolStripMenuItem TsiNeverDefault = new ToolStripMenuItem(AppString.Menu.NeverDefault);\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n        readonly ToolStripMenuItem TsiShowAsDisabled = new ToolStripMenuItem(AppString.Menu.ShowAsDisabledIfHidden);\n        readonly ToolStripMenuItem TsiClsidLocation = new ToolStripMenuItem(AppString.Menu.ClsidLocation);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            TsiChangeCommand = new ChangeCommandMenuItem(this);\n            TsiChangeIcon = new ChangeIconMenuItem(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiRegExport = new RegExportMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText, new ToolStripSeparator(), TsiItemIcon,\n                TsiPosition, TsiOtherAttributes, new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDeleteMe});\n\n            TsiItemIcon.DropDownItems.AddRange(new ToolStripItem[] { TsiChangeIcon, TsiDeleteIcon, TsiShieldIcon });\n\n            TsiPosition.DropDownItems.AddRange(new ToolStripItem[] { TsiDefault, TsiSetTop, TsiSetBottom });\n\n            TsiOtherAttributes.DropDownItems.AddRange(new ToolStripItem[] { TsiOnlyWithShift, TsiOnlyInExplorer,\n                TsiNoWorkDir, TsiNeverDefault, TsiShowAsDisabled });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),\n                TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport, TsiClsidLocation});\n\n            TsiDeleteIcon.Click += (sender, e) => DeleteIcon();\n            TsiSetTop.Click += (sender, e) => this.ItemPosition = Positions.Top;\n            TsiSetBottom.Click += (sender, e) => this.ItemPosition = Positions.Bottom;\n            TsiDefault.Click += (sender, e) => this.ItemPosition = Positions.Default;\n            TsiOnlyInExplorer.Click += (sender, e) => this.OnlyInExplorer = !TsiOnlyInExplorer.Checked;\n            TsiOnlyWithShift.Click += (sender, e) => this.OnlyWithShift = !TsiOnlyWithShift.Checked;\n            TsiNoWorkDir.Click += (sender, e) => this.NoWorkingDirectory = !TsiNoWorkDir.Checked;\n            TsiNeverDefault.Click += (sender, e) => this.NeverDefault = !TsiNeverDefault.Checked;\n            TsiShowAsDisabled.Click += (sender, e) => this.ShowAsDisabledIfHidden = !TsiShowAsDisabled.Checked;\n            TsiClsidLocation.Click += (sender, e) => ExternalProgram.JumpRegEdit(GuidInfo.GetClsidPath(Guid), null, AppConfig.OpenMoreRegedit);\n            ChkVisible.PreCheckChanging += () => !ChkVisible.Checked || TryProtectOpenItem();\n            ContextMenuStrip.Opening += (sender, e) => RefreshMenuItem();\n            BtnSubItems.MouseDown += (sender, e) => ShowSubItems();\n            TsiShieldIcon.Click += (sender, e) => UseShieldIcon();\n            ToolTipBox.SetToolTip(BtnSubItems, AppString.Tip.EditSubItems);\n            this.AddCtr(BtnSubItems);\n        }\n\n        private void DeleteIcon()\n        {\n            this.IconLocation = null;\n            this.HasLUAShield = false;\n            this.Image = this.Image.ToTransparent();\n        }\n\n        private void UseShieldIcon()\n        {\n            bool flag = this.HasLUAShield = TsiShieldIcon.Checked = !TsiShieldIcon.Checked;\n            if(IconLocation == null)\n            {\n                if(flag)\n                {\n                    this.Image = AppImage.Shield;\n                    this.IconPath = \"imageres.dll\";\n                    this.IconIndex = -78;\n                }\n                else\n                {\n                    this.Image = this.Image.ToTransparent();\n                }\n            }\n        }\n\n        private void RefreshMenuItem()\n        {\n            TsiOnlyWithShift.Visible = !IsSubItem;\n            TsiDeleteMe.Enabled = !(IsOpenItem && AppConfig.ProtectOpenItem);\n            TsiNoWorkDir.Checked = this.NoWorkingDirectory;\n            TsiShowAsDisabled.Visible = WinOsVersion.Current >= WinOsVersion.Win10_1703;\n            TsiShowAsDisabled.Checked = this.ShowAsDisabledIfHidden;\n            TsiChangeCommand.Visible = !IsMultiItem && Guid.Equals(Guid.Empty);\n            TsiClsidLocation.Visible = GuidInfo.GetClsidPath(Guid) != null;\n            if(!this.IsSubItem) TsiOnlyWithShift.Checked = this.OnlyWithShift;\n\n            if(WinOsVersion.Current >= WinOsVersion.Vista)\n            {\n                TsiItemIcon.Visible = true;\n                TsiPosition.Visible = !IsSubItem;\n                TsiOnlyInExplorer.Visible = !IsSubItem;\n                TsiNeverDefault.Visible = !IsSubItem;\n                if(this.HasIcon)\n                {\n                    TsiChangeIcon.Text = AppString.Menu.ChangeIcon;\n                    TsiDeleteIcon.Visible = true;\n                }\n                else\n                {\n                    TsiChangeIcon.Text = AppString.Menu.AddIcon;\n                    TsiDeleteIcon.Visible = false;\n                }\n                TsiShieldIcon.Checked = HasLUAShield;\n\n                if(!IsSubItem)\n                {\n                    TsiOnlyInExplorer.Checked = this.OnlyInExplorer;\n                    TsiNeverDefault.Checked = this.NeverDefault;\n                    TsiDefault.Checked = TsiSetTop.Checked = TsiSetBottom.Checked = false;\n                    switch(this.ItemPosition)\n                    {\n                        case Positions.Default:\n                            TsiDefault.Checked = true;\n                            break;\n                        case Positions.Top:\n                            TsiSetTop.Checked = true;\n                            break;\n                        case Positions.Bottom:\n                            TsiSetBottom.Checked = true;\n                            break;\n                    }\n                }\n            }\n            else\n            {\n                TsiItemIcon.Visible = false;\n                TsiPosition.Visible = false;\n                TsiOnlyInExplorer.Visible = false;\n                TsiNeverDefault.Visible = false;\n            }\n        }\n\n        private void ShowSubItems()\n        {\n            if(WinOsVersion.Current == WinOsVersion.Vista)\n            {\n                AppMessageBox.Show(AppString.Message.VistaUnsupportedMulti);\n                return;\n            }\n            using(ShellSubMenuDialog dlg = new ShellSubMenuDialog())\n            {\n                dlg.Text = AppString.Dialog.EditSubItems.Replace(\"%s\", this.Text);\n                dlg.Icon = ResourceIcon.GetIcon(IconPath, IconIndex);\n                dlg.ParentPath = this.RegPath;\n                dlg.ShowDialog();\n            }\n        }\n\n        public bool TryProtectOpenItem()\n        {\n            if(!IsOpenItem) return true;\n            if(!AppConfig.ProtectOpenItem) return true;\n            return AppMessageBox.Show(AppString.Message.PromptIsOpenItem, MessageBoxButtons.YesNo) == DialogResult.Yes;\n        }\n\n        public virtual void DeleteMe()\n        {\n            RegistryEx.DeleteKeyTree(this.RegPath, true);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing System.Linq;\nusing System.Windows.Forms;\nusing System.Xml;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ShellList : MyList\n    {\n        public const string MENUPATH_FILE = @\"HKEY_CLASSES_ROOT\\*\";//文件\n        public const string MENUPATH_FOLDER = @\"HKEY_CLASSES_ROOT\\Folder\";//文件夹\n        public const string MENUPATH_DIRECTORY = @\"HKEY_CLASSES_ROOT\\Directory\";//目录\n        public const string MENUPATH_BACKGROUND = @\"HKEY_CLASSES_ROOT\\Directory\\Background\";//目录背景\n        public const string MENUPATH_DESKTOP = @\"HKEY_CLASSES_ROOT\\DesktopBackground\";//桌面背景\n        public const string MENUPATH_DRIVE = @\"HKEY_CLASSES_ROOT\\Drive\";//磁盘分区\n        public const string MENUPATH_ALLOBJECTS = @\"HKEY_CLASSES_ROOT\\AllFilesystemObjects\";//所有对象\n        public const string MENUPATH_COMPUTER = @\"HKEY_CLASSES_ROOT\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\";//此电脑\n        public const string MENUPATH_RECYCLEBIN = @\"HKEY_CLASSES_ROOT\\CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\";//回收站\n        public const string MENUPATH_LIBRARY = @\"HKEY_CLASSES_ROOT\\LibraryFolder\";//库\n        public const string MENUPATH_LIBRARY_BACKGROUND = @\"HKEY_CLASSES_ROOT\\LibraryFolder\\Background\";//库背景\n        public const string MENUPATH_LIBRARY_USER = @\"HKEY_CLASSES_ROOT\\UserLibraryFolder\";//用户库\n        public const string MENUPATH_UWPLNK = @\"HKEY_CLASSES_ROOT\\Launcher.ImmersiveApplication\";//UWP快捷方式\n        public const string MENUPATH_UNKNOWN = @\"HKEY_CLASSES_ROOT\\Unknown\";//未知格式\n        public const string SYSFILEASSPATH = @\"HKEY_CLASSES_ROOT\\SystemFileAssociations\";//系统扩展名注册表父项路径\n        private const string LASTKEYPATH = @\"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\";//上次打开的注册表项路径记录\n\n        public enum Scenes\n        {\n            File, Folder, Directory, Background, Desktop, Drive, AllObjects, Computer, RecycleBin, Library,\n            LnkFile, UwpLnk, ExeFile, UnknownType, CustomExtension, PerceivedType, DirectoryType,\n            CommandStore, DragDrop, CustomRegPath, MenuAnalysis, CustomExtensionPerceivedType\n        }\n\n        private static readonly List<string> DirectoryTypes = new List<string>\n        {\n            \"Document\", \"Image\", \"Video\", \"Audio\"\n        };\n        private static readonly List<string> PerceivedTypes = new List<string>\n        {\n            null, \"Text\", \"Document\", \"Image\",\n            \"Video\", \"Audio\", \"Compressed\", \"System\"\n        };\n        private static readonly string[] PerceivedTypeNames =\n        {\n            AppString.Dialog.NoPerceivedType, AppString.Dialog.TextFile, AppString.Dialog.DocumentFile, AppString.Dialog.ImageFile,\n            AppString.Dialog.VideoFile, AppString.Dialog.AudioFile, AppString.Dialog.CompressedFile, AppString.Dialog.SystemFile\n        };\n        private static readonly string[] DirectoryTypeNames =\n        {\n            AppString.Dialog.DocumentDirectory, AppString.Dialog.ImageDirectory,\n            AppString.Dialog.VideoDirectory, AppString.Dialog.AudioDirectory\n        };\n\n        private static string GetDirectoryTypeName(string directoryType)\n        {\n            if(directoryType == null) return null;\n            int index = DirectoryTypes.FindIndex(type => directoryType.Equals(type, StringComparison.OrdinalIgnoreCase));\n            if(index >= 0) return DirectoryTypeNames[index];\n            else return null;\n        }\n\n        private static string GetPerceivedTypeName(string perceivedType)\n        {\n            int index = 0;\n            if(perceivedType != null) index = PerceivedTypes.FindIndex(type => perceivedType.Equals(type, StringComparison.OrdinalIgnoreCase));\n            if(index == -1) index = 0;\n            return PerceivedTypeNames[index];\n        }\n\n        private static readonly string[] DropEffectPaths =\n        {\n            MENUPATH_FILE, MENUPATH_ALLOBJECTS,\n            MENUPATH_FOLDER, MENUPATH_DIRECTORY\n        };\n        private static readonly string[] DropEffectNames =\n        {\n            AppString.Dialog.DefaultDropEffect, AppString.Dialog.CopyDropEffect,\n            AppString.Dialog.MoveDropEffect, AppString.Dialog.CreateLinkDropEffect\n        };\n\n        private enum DropEffect { Default = 0, Copy = 1, Move = 2, CreateLink = 4 }\n\n        private static DropEffect DefaultDropEffect\n        {\n            get\n            {\n                foreach(string path in DropEffectPaths)\n                {\n                    object value = Registry.GetValue(path, \"DefaultDropEffect\", null);\n                    if(value != null)\n                    {\n                        switch(value)\n                        {\n                            case 1:\n                                return DropEffect.Copy;\n                            case 2:\n                                return DropEffect.Move;\n                            case 4:\n                                return DropEffect.CreateLink;\n                        }\n                    }\n                }\n                return DropEffect.Default;\n            }\n            set\n            {\n                object data;\n                switch(value)\n                {\n                    case DropEffect.Copy:\n                        data = 1; break;\n                    case DropEffect.Move:\n                        data = 2; break;\n                    case DropEffect.CreateLink:\n                        data = 4; break;\n                    default:\n                        data = 0; break;\n                }\n                foreach(string path in DropEffectPaths)\n                {\n                    Registry.SetValue(path, \"DefaultDropEffect\", data, RegistryValueKind.DWord);\n                }\n            }\n        }\n\n        private static string GetDropEffectName()\n        {\n            switch(DefaultDropEffect)\n            {\n                case DropEffect.Copy:\n                    return DropEffectNames[1];\n                case DropEffect.Move:\n                    return DropEffectNames[2];\n                case DropEffect.CreateLink:\n                    return DropEffectNames[3];\n                default:\n                    return DropEffectNames[0];\n            }\n        }\n\n        private static string CurrentExtension = null;\n        private static string CurrentDirectoryType = null;\n        private static string CurrentPerceivedType = null;\n        public static string CurrentCustomRegPath = null;\n        public static string CurrentFileObjectPath = null;\n\n        private static string CurrentExtensionPerceivedType\n        {\n            get => GetPerceivedType(CurrentExtension);\n            set\n            {\n                string path = $@\"{RegistryEx.CLASSES_ROOT}\\{CurrentExtension}\";\n                if(value == null) RegistryEx.DeleteValue(path, \"PerceivedType\");\n                else Registry.SetValue(path, \"PerceivedType\", value, RegistryValueKind.String);\n            }\n        }\n\n        private static string GetShellPath(string scenePath) => $@\"{scenePath}\\shell\";\n        private static string GetShellExPath(string scenePath) => $@\"{scenePath}\\ShellEx\";\n        private static string GetSysAssExtPath(string typeName) => typeName != null ? $@\"{SYSFILEASSPATH}\\{typeName}\" : null;\n        private static string GetOpenMode(string extension) => FileExtension.GetOpenMode(extension);\n        private static string GetOpenModePath(string extension) => extension != null ? $@\"{RegistryEx.CLASSES_ROOT}\\{GetOpenMode(extension)}\" : null;\n        private static string GetPerceivedType(string extension) => Registry.GetValue($@\"{RegistryEx.CLASSES_ROOT}\\{extension}\", \"PerceivedType\", null)?.ToString();\n\n        public Scenes Scene { get; set; }\n\n        public void LoadItems()\n        {\n            string scenePath = null;\n            switch(Scene)\n            {\n                case Scenes.File:\n                    scenePath = MENUPATH_FILE; break;\n                case Scenes.Folder:\n                    scenePath = MENUPATH_FOLDER; break;\n                case Scenes.Directory:\n                    scenePath = MENUPATH_DIRECTORY; break;\n                case Scenes.Background:\n                    scenePath = MENUPATH_BACKGROUND; break;\n                case Scenes.Desktop:\n                    //Vista系统没有这一项\n                    if(WinOsVersion.Current == WinOsVersion.Vista) return;\n                    scenePath = MENUPATH_DESKTOP; break;\n                case Scenes.Drive:\n                    scenePath = MENUPATH_DRIVE; break;\n                case Scenes.AllObjects:\n                    scenePath = MENUPATH_ALLOBJECTS; break;\n                case Scenes.Computer:\n                    scenePath = MENUPATH_COMPUTER; break;\n                case Scenes.RecycleBin:\n                    scenePath = MENUPATH_RECYCLEBIN; break;\n                case Scenes.Library:\n                    //Vista系统没有这一项\n                    if(WinOsVersion.Current == WinOsVersion.Vista) return;\n                    scenePath = MENUPATH_LIBRARY; break;\n                case Scenes.LnkFile:\n                    scenePath = GetOpenModePath(\".lnk\"); break;\n                case Scenes.UwpLnk:\n                    //Win8之前没有Uwp\n                    if(WinOsVersion.Current < WinOsVersion.Win8) return;\n                    scenePath = MENUPATH_UWPLNK; break;\n                case Scenes.ExeFile:\n                    scenePath = GetSysAssExtPath(\".exe\"); break;\n                case Scenes.UnknownType:\n                    scenePath = MENUPATH_UNKNOWN; break;\n                case Scenes.CustomExtension:\n                    bool isLnk = CurrentExtension?.ToLower() == \".lnk\";\n                    if(isLnk) scenePath = GetOpenModePath(\".lnk\");\n                    else scenePath = GetSysAssExtPath(CurrentExtension);\n                    break;\n                case Scenes.PerceivedType:\n                    scenePath = GetSysAssExtPath(CurrentPerceivedType); break;\n                case Scenes.DirectoryType:\n                    if(CurrentDirectoryType == null) scenePath = null;\n                    else scenePath = GetSysAssExtPath($\"Directory.{CurrentDirectoryType}\"); break;\n                case Scenes.MenuAnalysis:\n                    this.AddItem(new SelectItem(Scene));\n                    this.LoadAnalysisItems();\n                    return;\n                case Scenes.CustomRegPath:\n                    scenePath = CurrentCustomRegPath; break;\n                case Scenes.CommandStore:\n                    //Vista系统没有这一项\n                    if(WinOsVersion.Current == WinOsVersion.Vista) return;\n                    this.AddNewItem(RegistryEx.GetParentPath(ShellItem.CommandStorePath));\n                    this.LoadStoreItems();\n                    return;\n                case Scenes.DragDrop:\n                    this.AddItem(new SelectItem(Scene));\n                    this.AddNewItem(MENUPATH_FOLDER);\n                    this.LoadShellExItems(GetShellExPath(MENUPATH_FOLDER));\n                    this.LoadShellExItems(GetShellExPath(MENUPATH_DIRECTORY));\n                    this.LoadShellExItems(GetShellExPath(MENUPATH_DRIVE));\n                    this.LoadShellExItems(GetShellExPath(MENUPATH_ALLOBJECTS));\n                    return;\n            }\n            this.AddNewItem(scenePath);\n            this.LoadItems(scenePath);\n            if(WinOsVersion.Current >= WinOsVersion.Win10)\n            {\n                this.LoadUwpModeItem();\n            }\n            switch(Scene)\n            {\n                case Scenes.Background:\n                    this.AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.CustomFolder));\n                    break;\n                case Scenes.Computer:\n                    this.AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.NetworkDrive));\n                    break;\n                case Scenes.RecycleBin:\n                    this.AddItem(new VisibleRegRuleItem(VisibleRegRuleItem.RecycleBinProperties));\n                    break;\n                case Scenes.Library:\n                    this.LoadItems(MENUPATH_LIBRARY_BACKGROUND);\n                    this.LoadItems(MENUPATH_LIBRARY_USER);\n                    break;\n                case Scenes.ExeFile:\n                    this.LoadItems(GetOpenModePath(\".exe\"));\n                    break;\n                case Scenes.CustomExtension:\n                case Scenes.PerceivedType:\n                case Scenes.DirectoryType:\n                case Scenes.CustomRegPath:\n                    this.InsertItem(new SelectItem(Scene), 0);\n                    if(Scene == Scenes.CustomExtension && CurrentExtension != null)\n                    {\n                        this.LoadItems(GetOpenModePath(CurrentExtension));\n                        this.InsertItem(new SelectItem(Scenes.CustomExtensionPerceivedType), 1);\n                    }\n                    break;\n            }\n        }\n\n        private void LoadItems(string scenePath)\n        {\n            if(scenePath == null) return;\n            RegTrustedInstaller.TakeRegKeyOwnerShip(scenePath);\n            this.LoadShellItems(GetShellPath(scenePath));\n            this.LoadShellExItems(GetShellExPath(scenePath));\n        }\n\n        private void LoadShellItems(string shellPath)\n        {\n            using(RegistryKey shellKey = RegistryEx.GetRegistryKey(shellPath))\n            {\n                if(shellKey == null) return;\n                RegTrustedInstaller.TakeRegTreeOwnerShip(shellKey.Name);\n                foreach(string keyName in shellKey.GetSubKeyNames())\n                {\n                    this.AddItem(new ShellItem($@\"{shellPath}\\{keyName}\"));\n                }\n            }\n        }\n\n        private void LoadShellExItems(string shellExPath)\n        {\n            List<string> names = new List<string>();\n            using(RegistryKey shellExKey = RegistryEx.GetRegistryKey(shellExPath))\n            {\n                if(shellExKey == null) return;\n                bool isDragDrop = Scene == Scenes.DragDrop;\n                RegTrustedInstaller.TakeRegTreeOwnerShip(shellExKey.Name);\n                Dictionary<string, Guid> dic = ShellExItem.GetPathAndGuids(shellExPath, isDragDrop);\n                FoldGroupItem groupItem = null;\n                if(isDragDrop)\n                {\n                    groupItem = GetDragDropGroupItem(shellExPath);\n                    this.AddItem(groupItem);\n                }\n                foreach(string path in dic.Keys)\n                {\n                    string keyName = RegistryEx.GetKeyName(path);\n                    if(!names.Contains(keyName))\n                    {\n                        ShellExItem item = new ShellExItem(dic[path], path);\n                        if(groupItem != null)\n                        {\n                            item.FoldGroupItem = groupItem;\n                            item.Indent();\n                        }\n                        this.AddItem(item);\n                        names.Add(keyName);\n                    }\n                }\n                groupItem?.SetVisibleWithSubItemCount();\n            }\n        }\n\n        private FoldGroupItem GetDragDropGroupItem(string shellExPath)\n        {\n            string text = null;\n            Image image = null;\n            string path = shellExPath.Substring(0, shellExPath.LastIndexOf('\\\\'));\n            switch(path)\n            {\n                case MENUPATH_FOLDER:\n                    text = AppString.SideBar.Folder;\n                    image = AppImage.Folder;\n                    break;\n                case MENUPATH_DIRECTORY:\n                    text = AppString.SideBar.Directory;\n                    image = AppImage.Directory;\n                    break;\n                case MENUPATH_DRIVE:\n                    text = AppString.SideBar.Drive;\n                    image = AppImage.Drive;\n                    break;\n                case MENUPATH_ALLOBJECTS:\n                    text = AppString.SideBar.AllObjects;\n                    image = AppImage.AllObjects;\n                    break;\n            }\n            return new FoldGroupItem(shellExPath, ObjectPath.PathType.Registry) { Text = text, Image = image };\n        }\n\n        private void AddNewItem(string scenePath)\n        {\n            if(scenePath == null) return;\n            string shellPath = GetShellPath(scenePath);\n            NewItem newItem = new NewItem();\n            PictureButton btnAddExisting = new PictureButton(AppImage.AddExisting);\n            PictureButton btnEnhanceMenu = new PictureButton(AppImage.Enhance);\n            ToolTipBox.SetToolTip(btnAddExisting, AppString.Tip.AddFromPublic);\n            ToolTipBox.SetToolTip(btnEnhanceMenu, AppString.StatusBar.EnhanceMenu);\n            if(Scene == Scenes.DragDrop || ShellItem.CommandStorePath.Equals(shellPath,\n                StringComparison.OrdinalIgnoreCase)) btnAddExisting.Visible = false;\n            else\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey(ShellItem.CommandStorePath))\n                {\n                    List<string> subKeyNames = key.GetSubKeyNames().ToList();\n                    if(AppConfig.HideSysStoreItems) subKeyNames.RemoveAll(name => name.StartsWith(\"Windows.\", StringComparison.OrdinalIgnoreCase));\n                    if(subKeyNames.Count == 0) btnAddExisting.Visible = false;\n                }\n            }\n            if(!XmlDicHelper.EnhanceMenuPathDic.ContainsKey(scenePath)) btnEnhanceMenu.Visible = false;\n            newItem.AddCtrs(new[] { btnAddExisting, btnEnhanceMenu });\n            this.AddItem(newItem);\n\n            newItem.AddNewItem += () =>\n            {\n                bool isShell;\n                if(Scene == Scenes.CommandStore) isShell = true;\n                else if(Scene == Scenes.DragDrop) isShell = false;\n                else\n                {\n                    using(SelectDialog dlg = new SelectDialog())\n                    {\n                        dlg.Items = new[] { \"Shell\", \"ShellEx\" };\n                        dlg.Title = AppString.Dialog.SelectNewItemType;\n                        if(dlg.ShowDialog() != DialogResult.OK) return;\n                        isShell = dlg.SelectedIndex == 0;\n                    }\n                }\n                if(isShell) this.AddNewShellItem(scenePath);\n                else this.AddNewShellExItem(scenePath);\n            };\n\n            btnAddExisting.MouseDown += (sender, e) =>\n            {\n                using(ShellStoreDialog dlg = new ShellStoreDialog())\n                {\n                    dlg.IsReference = false;\n                    dlg.ShellPath = ShellItem.CommandStorePath;\n                    dlg.Filter = new Func<string, bool>(itemName => !(AppConfig.HideSysStoreItems\n                        && itemName.StartsWith(\"Windows.\", StringComparison.OrdinalIgnoreCase)));\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    foreach(string keyName in dlg.SelectedKeyNames)\n                    {\n                        string srcPath = $@\"{dlg.ShellPath}\\{keyName}\";\n                        string dstPath = ObjectPath.GetNewPathWithIndex($@\"{shellPath}\\{keyName}\", ObjectPath.PathType.Registry);\n\n                        RegistryEx.CopyTo(srcPath, dstPath);\n                        this.AddItem(new ShellItem(dstPath));\n                    }\n                }\n            };\n\n            btnEnhanceMenu.MouseDown += (sender, e) =>\n            {\n                string tempPath1 = Path.GetTempFileName();\n                string tempPath2 = Path.GetTempFileName();\n                ExternalProgram.ExportRegistry(scenePath, tempPath1);\n                using(EnhanceMenusDialog dlg = new EnhanceMenusDialog())\n                {\n                    dlg.ScenePath = scenePath;\n                    dlg.ShowDialog();\n                }\n                ExternalProgram.ExportRegistry(scenePath, tempPath2);\n                string str1 = File.ReadAllText(tempPath1);\n                string str2 = File.ReadAllText(tempPath2);\n                File.Delete(tempPath1);\n                File.Delete(tempPath2);\n                if(!str1.Equals(str2))\n                {\n                    MainForm mainForm = (MainForm)this.FindForm();\n                    mainForm.JumpItem(mainForm.ToolBar.SelectedIndex, mainForm.SideBar.SelectedIndex);\n                }\n            };\n        }\n\n        private void AddNewShellItem(string scenePath)\n        {\n            string shellPath = GetShellPath(scenePath);\n            using(NewShellDialog dlg = new NewShellDialog())\n            {\n                dlg.ScenePath = scenePath;\n                dlg.ShellPath = shellPath;\n                if(dlg.ShowDialog() != DialogResult.OK) return;\n                for(int i = 0; i < this.Controls.Count; i++)\n                {\n                    if(this.Controls[i] is NewItem)\n                    {\n                        ShellItem item;\n                        if(Scene != Scenes.CommandStore) item = new ShellItem(dlg.NewItemRegPath);\n                        else item = new StoreShellItem(dlg.NewItemRegPath, true, false);\n                        this.InsertItem(item, i + 1);\n                        break;\n                    }\n                }\n            }\n        }\n\n        private void AddNewShellExItem(string scenePath)\n        {\n            bool isDragDrop = Scene == Scenes.DragDrop;\n            using(InputDialog dlg1 = new InputDialog { Title = AppString.Dialog.InputGuid })\n            {\n                if(GuidEx.TryParse(Clipboard.GetText(), out Guid guid)) dlg1.Text = guid.ToString();\n                if(dlg1.ShowDialog() != DialogResult.OK) return;\n                if(GuidEx.TryParse(dlg1.Text, out guid))\n                {\n                    if(isDragDrop)\n                    {\n                        using(SelectDialog dlg2 = new SelectDialog())\n                        {\n                            dlg2.Title = AppString.Dialog.SelectGroup;\n                            dlg2.Items = new[] { AppString.SideBar.Folder, AppString.SideBar.Directory,\n                                        AppString.SideBar.Drive, AppString.SideBar.AllObjects };\n                            if(dlg2.ShowDialog() != DialogResult.OK) return;\n                            switch(dlg2.SelectedIndex)\n                            {\n                                case 0:\n                                    scenePath = MENUPATH_FOLDER; break;\n                                case 1:\n                                    scenePath = MENUPATH_DIRECTORY; break;\n                                case 2:\n                                    scenePath = MENUPATH_DRIVE; break;\n                                case 3:\n                                    scenePath = MENUPATH_ALLOBJECTS; break;\n                            }\n                        }\n                    }\n                    string shellExPath = GetShellExPath(scenePath);\n                    if(ShellExItem.GetPathAndGuids(shellExPath, isDragDrop).Values.Contains(guid))\n                    {\n                        AppMessageBox.Show(AppString.Message.HasBeenAdded);\n                    }\n                    else\n                    {\n                        string part = isDragDrop ? ShellExItem.DdhParts[0] : ShellExItem.CmhParts[0];\n                        string regPath = $@\"{shellExPath}\\{part}\\{guid:B}\";\n                        Registry.SetValue(regPath, \"\", guid.ToString(\"B\"));\n                        ShellExItem item = new ShellExItem(guid, regPath);\n                        for(int i = 0; i < this.Controls.Count; i++)\n                        {\n                            if(isDragDrop)\n                            {\n                                if(this.Controls[i] is FoldGroupItem groupItem)\n                                {\n                                    if(groupItem.GroupPath.Equals(shellExPath, StringComparison.OrdinalIgnoreCase))\n                                    {\n                                        this.InsertItem(item, i + 1);\n                                        item.FoldGroupItem = groupItem;\n                                        groupItem.SetVisibleWithSubItemCount();\n                                        item.Visible = !groupItem.IsFold;\n                                        item.Indent();\n                                        break;\n                                    }\n                                }\n                            }\n                            else\n                            {\n                                if(this.Controls[i] is NewItem)\n                                {\n                                    this.InsertItem(item, i + 1);\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n                else\n                {\n                    AppMessageBox.Show(AppString.Message.MalformedGuid);\n                }\n            }\n        }\n\n        private void LoadStoreItems()\n        {\n            using(RegistryKey shellKey = RegistryEx.GetRegistryKey(ShellItem.CommandStorePath))\n            {\n                foreach(string itemName in shellKey.GetSubKeyNames())\n                {\n                    if(AppConfig.HideSysStoreItems && itemName.StartsWith(\"Windows.\", StringComparison.OrdinalIgnoreCase)) continue;\n                    this.AddItem(new StoreShellItem($@\"{ShellItem.CommandStorePath}\\{itemName}\", true, false));\n                }\n            }\n        }\n\n        private void LoadUwpModeItem()\n        {\n            foreach(XmlDocument doc in XmlDicHelper.UwpModeItemsDic)\n            {\n                if(doc?.DocumentElement == null) continue;\n                foreach(XmlNode sceneXN in doc.DocumentElement.ChildNodes)\n                {\n                    if(sceneXN.Name == Scene.ToString())\n                    {\n                        foreach(XmlElement itemXE in sceneXN.ChildNodes)\n                        {\n                            if(GuidEx.TryParse(itemXE.GetAttribute(\"Guid\"), out Guid guid))\n                            {\n                                bool isAdded = false;\n                                foreach(Control ctr in this.Controls)\n                                {\n                                    if(ctr is UwpModeItem item && item.Guid == guid) { isAdded = true; break; }\n                                }\n                                if(isAdded) continue;\n                                if(GuidInfo.GetFilePath(guid) == null) continue;\n                                string uwpName = GuidInfo.GetUwpName(guid);\n                                this.AddItem(new UwpModeItem(uwpName, guid));\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private void LoadAnalysisItems()\n        {\n            if(CurrentFileObjectPath == null) return;\n\n            void AddFileItems(string filePath)\n            {\n                string extension = Path.GetExtension(filePath).ToLower();\n                if(extension == string.Empty) extension = \".\";\n                string perceivedType = GetPerceivedType(extension);\n                string perceivedTypeName = GetPerceivedTypeName(perceivedType);\n                JumpItem.TargetPath = filePath;\n                JumpItem.Extension = extension;\n                JumpItem.PerceivedType = perceivedType;\n                this.AddItem(new JumpItem(Scenes.File));\n                this.AddItem(new JumpItem(Scenes.AllObjects));\n                if(extension == \".exe\") this.AddItem(new JumpItem(Scenes.ExeFile));\n                else this.AddItem(new JumpItem(Scenes.CustomExtension));\n                if(GetOpenMode(extension) == null) this.AddItem(new JumpItem(Scenes.UnknownType));\n                if(perceivedType != null) this.AddItem(new JumpItem(Scenes.PerceivedType));\n            }\n\n            void AddDirItems(string dirPath)\n            {\n                if(!dirPath.EndsWith(\":\\\\\"))\n                {\n                    this.AddItem(new JumpItem(Scenes.Folder));\n                    this.AddItem(new JumpItem(Scenes.Directory));\n                    this.AddItem(new JumpItem(Scenes.AllObjects));\n                    this.AddItem(new JumpItem(Scenes.DirectoryType));\n                }\n                else\n                {\n                    this.AddItem(new JumpItem(Scenes.Folder));\n                    this.AddItem(new JumpItem(Scenes.Drive));\n                }\n            }\n\n            if(File.Exists(CurrentFileObjectPath))\n            {\n                string extension = Path.GetExtension(CurrentFileObjectPath).ToLower();\n                if(extension == \".lnk\")\n                {\n                    using(ShellLink shellLink = new ShellLink(CurrentFileObjectPath))\n                    {\n                        string targetPath = shellLink.TargetPath;\n                        if(File.Exists(targetPath)) AddFileItems(targetPath);\n                        else if(Directory.Exists(targetPath)) AddDirItems(targetPath);\n                    }\n                    this.AddItem(new JumpItem(Scenes.LnkFile));\n                }\n                else AddFileItems(CurrentFileObjectPath);\n            }\n            else if(Directory.Exists(CurrentFileObjectPath)) AddDirItems(CurrentFileObjectPath);\n        }\n\n        sealed class SelectItem : MyListItem\n        {\n            public SelectItem(Scenes scene)\n            {\n                this.Scene = scene;\n                this.AddCtr(BtnSelect);\n                this.SetTextAndTip();\n                this.SetImage();\n                BtnSelect.MouseDown += (sender, e) => ShowSelectDialog();\n                this.MouseDoubleClick += (sender, e) => ShowSelectDialog();\n            }\n\n            readonly PictureButton BtnSelect = new PictureButton(AppImage.Select);\n\n            public Scenes Scene { get; private set; }\n            public string SelectedPath { get; set; }\n\n            private void SetTextAndTip()\n            {\n                string tip = \"\";\n                string text = \"\";\n                switch(Scene)\n                {\n                    case Scenes.CustomExtension:\n                        tip = AppString.Dialog.SelectExtension;\n                        if(CurrentExtension == null) text = tip;\n                        else text = AppString.Other.CurrentExtension.Replace(\"%s\", CurrentExtension);\n                        break;\n                    case Scenes.PerceivedType:\n                        tip = AppString.Dialog.SelectPerceivedType;\n                        if(CurrentPerceivedType == null) text = tip;\n                        else text = AppString.Other.CurrentPerceivedType.Replace(\"%s\", GetPerceivedTypeName(CurrentPerceivedType));\n                        break;\n                    case Scenes.DirectoryType:\n                        tip = AppString.Dialog.SelectDirectoryType;\n                        if(CurrentDirectoryType == null) text = tip;\n                        else text = AppString.Other.CurrentDirectoryType.Replace(\"%s\", GetDirectoryTypeName(CurrentDirectoryType));\n                        break;\n                    case Scenes.CustomRegPath:\n                        this.SelectedPath = CurrentCustomRegPath;\n                        tip = AppString.Other.SelectRegPath;\n                        if(this.SelectedPath == null) text = tip;\n                        else text = AppString.Other.CurrentRegPath + \"\\n\" + this.SelectedPath;\n                        break;\n                    case Scenes.MenuAnalysis:\n                        this.SelectedPath = CurrentFileObjectPath;\n                        tip = AppString.Tip.DropOrSelectObject;\n                        if(this.SelectedPath == null) text = tip;\n                        else text = AppString.Other.CurrentFilePath + \"\\n\" + this.SelectedPath;\n                        break;\n                    case Scenes.DragDrop:\n                        this.SelectedPath = GetDropEffectName();\n                        tip = AppString.Dialog.SelectDropEffect;\n                        text = AppString.Other.SetDefaultDropEffect + \" \" + this.SelectedPath;\n                        break;\n                    case Scenes.CustomExtensionPerceivedType:\n                        tip = AppString.Dialog.SelectPerceivedType;\n                        text = AppString.Other.SetPerceivedType.Replace(\"%s\", CurrentExtension) + \" \" + GetPerceivedTypeName(CurrentExtensionPerceivedType);\n                        break;\n                }\n                ToolTipBox.SetToolTip(BtnSelect, tip);\n                this.Text = text;\n            }\n\n            private void SetImage()\n            {\n                switch(Scene)\n                {\n                    case Scenes.CustomExtensionPerceivedType:\n                        using(Icon icon = ResourceIcon.GetExtensionIcon(CurrentExtension))\n                            this.Image = icon?.ToBitmap();\n                        break;\n                }\n                if(this.Image == null) this.Image = AppImage.Custom;\n            }\n\n            private void ShowSelectDialog()\n            {\n                SelectDialog dlg = null;\n                switch(Scene)\n                {\n                    case Scenes.CustomExtension:\n                        dlg = new FileExtensionDialog\n                        {\n                            Selected = CurrentExtension?.Substring(1)\n                        };\n                        break;\n                    case Scenes.PerceivedType:\n                        dlg = new SelectDialog\n                        {\n                            Items = PerceivedTypeNames,\n                            Title = AppString.Dialog.SelectPerceivedType,\n                            Selected = GetPerceivedTypeName(CurrentPerceivedType)\n                        };\n                        break;\n                    case Scenes.DirectoryType:\n                        dlg = new SelectDialog\n                        {\n                            Items = DirectoryTypeNames,\n                            Title = AppString.Dialog.SelectDirectoryType,\n                            Selected = GetDirectoryTypeName(CurrentDirectoryType)\n                        };\n                        break;\n                    case Scenes.CustomExtensionPerceivedType:\n                        dlg = new SelectDialog\n                        {\n                            Items = PerceivedTypeNames,\n                            Title = AppString.Dialog.SelectPerceivedType,\n                            Selected = GetPerceivedTypeName(CurrentExtensionPerceivedType)\n                        };\n                        break;\n                    case Scenes.DragDrop:\n                        dlg = new SelectDialog\n                        {\n                            Items = DropEffectNames,\n                            Title = AppString.Dialog.SelectDropEffect,\n                            Selected = GetDropEffectName()\n                        };\n                        break;\n                    case Scenes.MenuAnalysis:\n                        dlg = new SelectDialog\n                        {\n                            Items = new[] { AppString.SideBar.File, AppString.SideBar.Directory },\n                            Title = AppString.Dialog.SelectObjectType,\n                        };\n                        break;\n                    case Scenes.CustomRegPath:\n                        if(AppMessageBox.Show(AppString.Message.SelectRegPath,\n                            MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;\n                        Form frm = this.FindForm();\n                        frm.Hide();\n                        using(Process process = Process.Start(\"regedit.exe\", \"-m\"))\n                        {\n                            process.WaitForExit();\n                        }\n                        string path = Registry.GetValue(LASTKEYPATH, \"LastKey\", \"\").ToString();\n                        int index = path.IndexOf('\\\\');\n                        if(index == -1) return;\n                        path = path.Substring(index + 1);\n                        CurrentCustomRegPath = path;\n                        this.RefreshList();\n                        frm.Show();\n                        frm.Activate();\n                        break;\n                }\n                switch(Scene)\n                {\n                    case Scenes.CustomExtension:\n                    case Scenes.PerceivedType:\n                    case Scenes.DirectoryType:\n                    case Scenes.MenuAnalysis:\n                    case Scenes.DragDrop:\n                    case Scenes.CustomExtensionPerceivedType:\n                        if(dlg.ShowDialog() != DialogResult.OK) return;\n                        break;\n                }\n                switch(Scene)\n                {\n                    case Scenes.CustomExtension:\n                        CurrentExtension = dlg.Selected;\n                        this.RefreshList();\n                        break;\n                    case Scenes.PerceivedType:\n                        CurrentPerceivedType = PerceivedTypes[dlg.SelectedIndex];\n                        this.RefreshList();\n                        break;\n                    case Scenes.DirectoryType:\n                        CurrentDirectoryType = DirectoryTypes[dlg.SelectedIndex];\n                        this.RefreshList();\n                        break;\n                    case Scenes.CustomExtensionPerceivedType:\n                        string selected = PerceivedTypes[dlg.SelectedIndex];\n                        CurrentExtensionPerceivedType = selected;\n                        this.Text = AppString.Other.SetPerceivedType.Replace(\"%s\", CurrentExtension) + \" \" + GetPerceivedTypeName(selected);\n                        break;\n                    case Scenes.DragDrop:\n                        switch(dlg.SelectedIndex)\n                        {\n                            case 0: DefaultDropEffect = DropEffect.Default; break;\n                            case 1: DefaultDropEffect = DropEffect.Copy; break;\n                            case 2: DefaultDropEffect = DropEffect.Move; break;\n                            case 3: DefaultDropEffect = DropEffect.CreateLink; break;\n                        }\n                        this.Text = AppString.Other.SetDefaultDropEffect + \" \" + GetDropEffectName();\n                        break;\n                    case Scenes.MenuAnalysis:\n                        if(dlg.SelectedIndex == 0)\n                        {\n                            using(var dlg1 = new System.Windows.Forms.OpenFileDialog())\n                            {\n                                dlg1.DereferenceLinks = false;\n                                if(dlg1.ShowDialog() != DialogResult.OK) return;\n                                CurrentFileObjectPath = dlg1.FileName;\n                            }\n                        }\n                        else\n                        {\n                            using(var dlg2 = new FolderBrowserDialog())\n                            {\n                                if(dlg2.ShowDialog() != DialogResult.OK) return;\n                                CurrentFileObjectPath = dlg2.SelectedPath;\n                            }\n                        }\n                        this.RefreshList();\n                        break;\n                }\n            }\n\n            private void RefreshList()\n            {\n                ShellList list = (ShellList)this.Parent;\n                list.ClearItems();\n                list.LoadItems();\n            }\n        }\n\n        sealed class JumpItem : MyListItem\n        {\n            public JumpItem(Scenes scene)\n            {\n                this.AddCtr(btnJump);\n                Image image = null;\n                int index1 = 0;\n                int index2 = 0;\n                string[] txts = null;\n                switch(scene)\n                {\n                    case Scenes.File:\n                        txts = new[] { AppString.ToolBar.Home, AppString.SideBar.File };\n                        image = AppImage.File;\n                        break;\n                    case Scenes.Folder:\n                        txts = new[] { AppString.ToolBar.Home, AppString.SideBar.Folder };\n                        image = AppImage.Folder;\n                        index2 = 1;\n                        break;\n                    case Scenes.Directory:\n                        txts = new[] { AppString.ToolBar.Home, AppString.SideBar.Directory };\n                        image = AppImage.Directory;\n                        index2 = 2;\n                        break;\n                    case Scenes.Drive:\n                        txts = new[] { AppString.ToolBar.Home, AppString.SideBar.Drive };\n                        image = AppImage.Drive;\n                        index2 = 5;\n                        break;\n                    case Scenes.AllObjects:\n                        txts = new[] { AppString.ToolBar.Home, AppString.SideBar.AllObjects };\n                        image = AppImage.AllObjects;\n                        index2 = 6;\n                        break;\n                    case Scenes.LnkFile:\n                        txts = new[] { AppString.ToolBar.Type, AppString.SideBar.LnkFile };\n                        image = AppImage.LnkFile;\n                        index1 = 1;\n                        break;\n                    case Scenes.ExeFile:\n                        txts = new[] { AppString.ToolBar.Type, AppString.SideBar.ExeFile };\n                        using(Icon icon = ResourceIcon.GetExtensionIcon(TargetPath)) image = icon.ToBitmap();\n                        index1 = 1;\n                        index2 = 2;\n                        break;\n                    case Scenes.UnknownType:\n                        txts = new[] { AppString.ToolBar.Type, AppString.SideBar.UnknownType };\n                        image = AppImage.NotFound;\n                        index1 = 1;\n                        index2 = 8;\n                        break;\n                    case Scenes.CustomExtension:\n                        txts = new[] { AppString.ToolBar.Type, AppString.SideBar.CustomExtension, Extension };\n                        using(Icon icon = ResourceIcon.GetExtensionIcon(Extension)) image = icon.ToBitmap();\n                        index1 = 1;\n                        index2 = 4;\n                        break;\n                    case Scenes.PerceivedType:\n                        txts = new[] { AppString.ToolBar.Type, AppString.SideBar.PerceivedType, GetPerceivedTypeName(PerceivedType) };\n                        image = AppImage.File;\n                        index1 = 1;\n                        index2 = 5;\n                        break;\n                    case Scenes.DirectoryType:\n                        txts = new[] { AppString.ToolBar.Type, AppString.SideBar.DirectoryType };\n                        image = AppImage.Directory;\n                        index1 = 1;\n                        index2 = 6;\n                        break;\n                }\n                this.Text = \"[ \" + string.Join(\" ]  ▶  [ \", txts) + \" ]\";\n                this.Image = image;\n                void SwitchTab()\n                {\n                    switch(scene)\n                    {\n                        case Scenes.CustomExtension:\n                            CurrentExtension = Extension; break;\n                        case Scenes.PerceivedType:\n                            CurrentPerceivedType = PerceivedType; break;\n                    }\n                    ((MainForm)this.FindForm()).JumpItem(index1, index2);\n                };\n                btnJump.MouseDown += (sender, e) => SwitchTab();\n                this.DoubleClick += (sender, e) => SwitchTab();\n            }\n\n            readonly PictureButton btnJump = new PictureButton(AppImage.Jump);\n\n            public static string Extension = null;\n            public static string PerceivedType = null;\n            public static string TargetPath = null;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellNewItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Drawing;\nusing System.IO;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    /* 新建菜单项成立条件与相关规则:（恶心的关联方式，反复研究了好久）\n     * \n     * 1.① 扩展名的关联打开方式（以下简称[OpenMode]，对应路径简称[OpenModePath]）\n     *   ② HKCR默认值打开方式（以下简称[DefaultOpenMode]，对应路径简称[DefaultOpenModePath]）\n     *   以上两个打开方式不一定相同\n     * \n     * 2.① [DefaultOpenMode]不能为空，[DefaultOpenModePath]必须存在\n     *   ② 菜单文本也不可为空\n     *   ③ ShellNew项中必须存在 NullFile、Data、FileName、Directory、Command 中的一个或多个键值\n     *   以上三个条件缺一不可，否则菜单不成立\n     *   \n     * 3.菜单名称取值优先级:\n     *   ① ShellNew项的 MenuText 键值（必须为带@的资源文件字符串)\n     *   ② [DefaultOpenModePath] 的 FriendlyTypeName 键值\n     *   ③ [DefaultOpenModePath] 的默认键值\n     *   ④ ②和③虽然不是第一优先级，但至少得存在一个，否则菜单不成立\n     *   \n     * 4.菜单图标取值优先级:\n     *   ① ShellNew项的 IconPath 键值\n     *   ② [OpenModePath]\\DefaultIcon 的默认键值\n     *   ③ 关联程序图标\n     */\n\n    sealed class ShellNewItem : MyListItem, IChkVisibleItem, ITsiTextItem, IBtnShowMenuItem, IBtnMoveUpDownItem,\n         ITsiIconItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiRegPathItem, ITsiRegDeleteItem, ITsiRegExportItem, ITsiCommandItem\n    {\n        public static readonly string[] SnParts = { \"ShellNew\", \"-ShellNew\" };\n        public static readonly string[] UnableSortExtensions = { \"Folder\", \".library-ms\" };\n        public static readonly string[] DefaultBeforeSeparatorExtensions = { \"Folder\", \".library-ms\", \".lnk\" };\n        public static readonly string[] EffectValueNames = { \"NullFile\", \"Data\", \"FileName\", \"Directory\", \"Command\" };\n        private static readonly string[] UnableEditDataValues = { \"Directory\", \"FileName\", \"Handler\", \"Command\" };\n        private static readonly string[] UnableChangeCommandValues = { \"Data\", \"Directory\", \"FileName\", \"Handler\" };\n\n        public ShellNewItem(ShellNewList list, string regPath)\n        {\n            this.Owner = list;\n            InitializeComponents();\n            this.RegPath = regPath;\n            SetSortabled(ShellNewList.ShellNewLockItem.IsLocked);\n        }\n\n        private string regPath;\n        public string RegPath\n        {\n            get => regPath;\n            set\n            {\n                regPath = value;\n                this.Text = this.ItemText;\n                this.Image = this.ItemIcon.ToBitmap();\n            }\n        }\n\n        public string ValueName => null;\n        public string SearchText => $\"{AppString.SideBar.New} {Text}\";\n        public string Extension => RegPath.Split('\\\\')[1];\n        private string SnKeyName => RegistryEx.GetKeyName(RegPath);\n        private string BackupPath => $@\"{RegistryEx.GetParentPath(RegPath)}\\{(ItemVisible ? SnParts[1] : SnParts[0])}\";\n        private string OpenMode => FileExtension.GetOpenMode(Extension);//关联打开方式\n        private string OpenModePath => $@\"{RegistryEx.CLASSES_ROOT}\\{OpenMode}\";//关联打开方式注册表路径\n        private string DefaultOpenMode => Registry.GetValue($@\"{RegistryEx.CLASSES_ROOT}\\{Extension}\", \"\", null)?.ToString();//HKCR默认值打开方式\n        private string DefaultOpenModePath => $@\"{RegistryEx.CLASSES_ROOT}\\{DefaultOpenMode}\";//HKCR默认值打开方式路径\n        public bool CanSort => !UnableSortExtensions.Contains(Extension, StringComparer.OrdinalIgnoreCase);//能够排序的\n        private bool CanEditData => UnableEditDataValues.All(value => Registry.GetValue(RegPath, value, null) == null);//能够编辑初始数据的\n        private bool CanChangeCommand => UnableChangeCommandValues.All(value => Registry.GetValue(RegPath, value, null) == null);//能够更改菜单命令的\n        private bool DefaultBeforeSeparator => DefaultBeforeSeparatorExtensions.Contains(Extension, StringComparer.OrdinalIgnoreCase);//默认显示在分割线上不可更改的\n\n        public string ItemFilePath\n        {\n            get\n            {\n                string filePath = FileExtension.GetExtentionInfo(FileExtension.AssocStr.Executable, Extension);\n                if(File.Exists(filePath)) return filePath;\n                using(RegistryKey oKey = RegistryEx.GetRegistryKey(OpenModePath))\n                {\n                    using(RegistryKey aKey = oKey.OpenSubKey(\"Application\"))\n                    {\n                        string uwp = aKey?.GetValue(\"AppUserModelID\")?.ToString();\n                        if(uwp != null) return \"shell:AppsFolder\\\\\" + uwp;\n                    }\n                    using(RegistryKey cKey = oKey.OpenSubKey(\"CLSID\"))\n                    {\n                        string value = cKey?.GetValue(\"\")?.ToString();\n                        if(GuidEx.TryParse(value, out Guid guid))\n                        {\n                            filePath = GuidInfo.GetFilePath(guid);\n                            if(filePath != null) return filePath;\n                        }\n                    }\n                }\n                return null;\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get => SnKeyName.Equals(SnParts[0], StringComparison.OrdinalIgnoreCase);\n            set\n            {\n                RegistryEx.MoveTo(RegPath, BackupPath);\n                this.RegPath = BackupPath;\n            }\n        }\n\n        public string ItemText\n        {\n            get\n            {\n                string name = Registry.GetValue(RegPath, \"MenuText\", null)?.ToString();\n                if(name!=null&&name.StartsWith(\"@\"))\n                {\n                    name = ResourceString.GetDirectString(name);\n                    if(!string.IsNullOrEmpty(name)) return name;\n                }\n                name = Registry.GetValue(DefaultOpenModePath, \"FriendlyTypeName\", null)?.ToString();\n                name = ResourceString.GetDirectString(name);\n                if(!string.IsNullOrEmpty(name)) return name;\n                name = Registry.GetValue(DefaultOpenModePath, \"\", null)?.ToString();\n                if(!string.IsNullOrEmpty(name)) return name;\n                return null;\n            }\n            set\n            {\n                RegistryEx.DeleteValue(RegPath, \"MenuText\");\n                Registry.SetValue(DefaultOpenModePath, \"FriendlyTypeName\", value);\n                this.Text = ResourceString.GetDirectString(value);\n            }\n        }\n\n        public string IconLocation\n        {\n            get\n            {\n                string value = Registry.GetValue(RegPath, \"IconPath\", null)?.ToString();\n                if(!value.IsNullOrWhiteSpace()) return value;\n                value = Registry.GetValue($@\"{OpenModePath}\\DefaultIcon\", \"\", null)?.ToString();\n                if(!value.IsNullOrWhiteSpace()) return value;\n                return ItemFilePath;\n            }\n            set => Registry.SetValue(RegPath, \"IconPath\", value);\n        }\n\n        public Icon ItemIcon\n        {\n            get\n            {\n                string location = IconLocation;\n                if(location == null || location.StartsWith(\"@\"))\n                {\n                    return ResourceIcon.GetExtensionIcon(Extension);\n                } \n                Icon icon = ResourceIcon.GetIcon(location, out string path, out int index);\n                if(icon == null) icon = ResourceIcon.GetIcon(path = \"imageres.dll\", index = -2);\n                IconPath = path; IconIndex = index;\n                return icon;\n            }\n        }\n\n        public string IconPath { get; set; }\n        public int IconIndex { get; set; }\n\n        private object InitialData\n        {\n            get => Registry.GetValue(RegPath, \"Data\", null);\n            set => Registry.SetValue(RegPath, \"Data\", value);\n        }\n\n        public string ItemCommand\n        {\n            get => Registry.GetValue(RegPath, \"Command\", null)?.ToString();\n            set\n            {\n                if(value.IsNullOrWhiteSpace())\n                {\n                    if(Registry.GetValue(RegPath, \"NullFile\", null) != null)\n                    {\n                        RegistryEx.DeleteValue(RegPath, \"Command\");\n                    }\n                }\n                else\n                {\n                    Registry.SetValue(RegPath, \"Command\", value);\n                }\n            }\n        }\n\n        public bool BeforeSeparator\n        {\n            get\n            {\n                if(DefaultBeforeSeparator) return true;\n                else return Registry.GetValue($@\"{RegPath}\\Config\", \"BeforeSeparator\", null) != null;\n            }\n            set\n            {\n                if(value)\n                {\n                    Registry.SetValue($@\"{RegPath}\\Config\", \"BeforeSeparator\", \"\");\n                }\n                else\n                {\n                    using(RegistryKey snkey = RegistryEx.GetRegistryKey(RegPath, true))\n                    using(RegistryKey ckey = snkey.OpenSubKey(\"Config\", true))\n                    {\n                        ckey.DeleteValue(\"BeforeSeparator\");\n                        if(ckey.GetValueNames().Length == 0 && ckey.GetSubKeyNames().Length == 0)\n                        {\n                            snkey.DeleteSubKey(\"Config\");\n                        }\n                    }\n                }\n            }\n        }\n\n        public ShellNewList Owner { get; private set; }\n        public MoveButton BtnMoveUp { get; set; }\n        public MoveButton BtnMoveDown { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        public ChangeIconMenuItem TsiChangeIcon { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public RegExportMenuItem TsiRegExport { get; set; }\n        public ChangeCommandMenuItem TsiChangeCommand { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n        readonly ToolStripMenuItem TsiOtherAttributes = new ToolStripMenuItem(AppString.Menu.OtherAttributes);\n        readonly ToolStripMenuItem TsiBeforeSeparator = new ToolStripMenuItem(AppString.Menu.BeforeSeparator);\n        readonly ToolStripMenuItem TsiEditData = new ToolStripMenuItem(AppString.Menu.InitialData);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            BtnMoveDown = new MoveButton(this, false);\n            BtnMoveUp = new MoveButton(this, true);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            TsiChangeIcon = new ChangeIconMenuItem(this);\n            TsiChangeCommand = new ChangeCommandMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiRegExport = new RegExportMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n            TsiChangeCommand.CommandCanBeEmpty = true;\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] {TsiChangeText,\n                new ToolStripSeparator(), TsiChangeIcon, new ToolStripSeparator(), TsiOtherAttributes,\n                new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n\n            TsiOtherAttributes.DropDownItems.AddRange(new[] { TsiBeforeSeparator, TsiEditData });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch,\n                new ToolStripSeparator(), TsiChangeCommand, TsiFileProperties,\n                TsiFileLocation, TsiRegLocation, TsiRegExport });\n\n            ContextMenuStrip.Opening += (sender, e) =>\n            {\n                TsiEditData.Visible = CanEditData;\n                TsiChangeCommand.Visible = CanChangeCommand;\n                TsiBeforeSeparator.Enabled = !DefaultBeforeSeparator;\n                TsiBeforeSeparator.Checked = BeforeSeparator;\n            };\n            TsiEditData.Click += (sender, e) => EditInitialData();\n            TsiBeforeSeparator.Click += (sender, e) => MoveWithSeparator(!TsiBeforeSeparator.Checked);\n            BtnMoveUp.MouseDown += (sender, e) => Owner.MoveItem(this, true);\n            BtnMoveDown.MouseDown += (sender, e) => Owner.MoveItem(this, false);\n        }\n\n        private void EditInitialData()\n        {\n            if(AppMessageBox.Show(AppString.Message.EditInitialData,\n                MessageBoxButtons.YesNo) != DialogResult.Yes) return;\n            using(InputDialog dlg = new InputDialog\n            {\n                Title = AppString.Menu.InitialData,\n                Text = this.InitialData?.ToString()\n            })\n            {\n                if(dlg.ShowDialog() == DialogResult.OK) this.InitialData = dlg.Text;\n            }\n        }\n\n        public void SetSortabled(bool isLocked)\n        {\n            BtnMoveDown.Visible = BtnMoveUp.Visible = isLocked && CanSort;\n        }\n\n        private void MoveWithSeparator(bool isBefore)\n        {\n            BeforeSeparator = isBefore;\n            ShellNewList list = (ShellNewList)this.Parent;\n            int index = list.GetItemIndex(list.Separator);\n            list.SetItemIndex(this, index);\n            if(ShellNewList.ShellNewLockItem.IsLocked) list.SaveSorting();\n        }\n\n        public void DeleteMe()\n        {\n            RegistryEx.DeleteKeyTree(this.RegPath);\n            RegistryEx.DeleteKeyTree(this.BackupPath);\n            this.Parent.Controls.Remove(this);\n            if(ShellNewList.ShellNewLockItem.IsLocked) Owner.SaveSorting();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellNewList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\nusing System.Security.AccessControl;\nusing System.Security.Principal;\nusing System.Windows.Forms;\nusing System.Xml;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ShellNewList : MyList\n    {\n        public const string ShellNewPath = @\"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Discardable\\PostSetup\\ShellNew\";\n\n        public ShellNewSeparator Separator;\n\n        public void LoadItems()\n        {\n            this.AddNewItem();\n            this.AddItem(new ShellNewLockItem(this));\n            Separator = new ShellNewSeparator();\n            this.AddItem(Separator);\n            if(ShellNewLockItem.IsLocked) this.LoadLockItems();\n            else this.LoadUnlockItems();\n        }\n\n        /// <summary>直接扫描所有扩展名</summary>\n        private void LoadUnlockItems()\n        {\n            List<string> extensions = new List<string> { \"Folder\" };//文件夹\n            using(RegistryKey root = Registry.ClassesRoot)\n            {\n                extensions.AddRange(Array.FindAll(root.GetSubKeyNames(), keyName => keyName.StartsWith(\".\")));\n                if(WinOsVersion.Current < WinOsVersion.Win10) extensions.Add(\"Briefcase\");//公文包(Win10没有)\n                this.LoadItems(extensions);\n            }\n        }\n\n        /// <summary>根据ShellNewPath的Classes键值扫描</summary>\n        private void LoadLockItems()\n        {\n            string[] extensions = (string[])Registry.GetValue(ShellNewPath, \"Classes\", null);\n            this.LoadItems(extensions.ToList());\n        }\n\n        private void LoadItems(List<string> extensions)\n        {\n            foreach(string extension in ShellNewItem.UnableSortExtensions)\n            {\n                if(extensions.Contains(extension, StringComparer.OrdinalIgnoreCase))\n                {\n                    extensions.Remove(extension);\n                    extensions.Insert(0, extension);\n                }\n            }\n            using(RegistryKey root = Registry.ClassesRoot)\n            {\n                foreach(string extension in extensions)\n                {\n                    using(RegistryKey extKey = root.OpenSubKey(extension))\n                    {\n                        string defalutOpenMode = extKey?.GetValue(\"\")?.ToString();\n                        if(string.IsNullOrEmpty(defalutOpenMode) || defalutOpenMode.Length > 255) continue;\n                        using(RegistryKey openModeKey = root.OpenSubKey(defalutOpenMode))\n                        {\n                            if(openModeKey == null) continue;\n                            string value1 = openModeKey.GetValue(\"FriendlyTypeName\")?.ToString();\n                            string value2 = openModeKey.GetValue(\"\")?.ToString();\n                            value1 = ResourceString.GetDirectString(value1);\n                            if(value1.IsNullOrWhiteSpace() && value2.IsNullOrWhiteSpace()) continue;\n                        }\n                        using(RegistryKey tKey = extKey.OpenSubKey(defalutOpenMode))\n                        {\n                            foreach(string part in ShellNewItem.SnParts)\n                            {\n                                string snPart = part;\n                                if(tKey != null) snPart = $@\"{defalutOpenMode}\\{snPart}\";\n                                using(RegistryKey snKey = extKey.OpenSubKey(snPart))\n                                {\n                                    if(ShellNewItem.EffectValueNames.Any(valueName => snKey?.GetValue(valueName) != null))\n                                    {\n                                        ShellNewItem item = new ShellNewItem(this, snKey.Name);\n                                        if(item.BeforeSeparator)\n                                        {\n                                            int index2 = this.GetItemIndex(Separator);\n                                            this.InsertItem(item, index2);\n                                        }\n                                        else\n                                        {\n                                            this.AddItem(item);\n                                        }\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        public void MoveItem(ShellNewItem shellNewItem, bool isUp)\n        {\n            int index = this.GetItemIndex(shellNewItem);\n            index += isUp ? -1 : 1;\n            if(index == this.Controls.Count) return;\n            Control ctr = this.Controls[index];\n            if(ctr is ShellNewItem item && item.CanSort)\n            {\n                this.SetItemIndex(shellNewItem, index);\n                this.SaveSorting();\n            }\n        }\n\n        public void SaveSorting()\n        {\n            List<string> extensions = new List<string>();\n            for(int i = 2; i < this.Controls.Count; i++)\n            {\n                if(Controls[i] is ShellNewItem item)\n                {\n                    extensions.Add(item.Extension);\n                }\n            }\n            ShellNewLockItem.UnLock();\n            Registry.SetValue(ShellNewPath, \"Classes\", extensions.ToArray());\n            ShellNewLockItem.Lock();\n        }\n\n        private void AddNewItem()\n        {\n            NewItem newItem = new NewItem();\n            this.AddItem(newItem);\n            newItem.AddNewItem += () =>\n            {\n                using(FileExtensionDialog dlg = new FileExtensionDialog())\n                {\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    string extension = dlg.Extension;\n                    if(extension == \".\") return;\n                    string openMode = FileExtension.GetOpenMode(extension);\n                    if(string.IsNullOrEmpty(openMode))\n                    {\n                        if(AppMessageBox.Show(AppString.Message.NoOpenModeExtension,\n                            MessageBoxButtons.OKCancel) == DialogResult.OK)\n                        {\n                            ExternalProgram.ShowOpenWithDialog(extension);\n                        }\n                        return;\n                    }\n                    foreach(Control ctr in this.Controls)\n                    {\n                        if(ctr is ShellNewItem item)\n                        {\n                            if(item.Extension.Equals(extension, StringComparison.OrdinalIgnoreCase))\n                            {\n                                AppMessageBox.Show(AppString.Message.HasBeenAdded);\n                                return;\n                            }\n                        }\n                    }\n\n                    using(RegistryKey root = Registry.ClassesRoot)\n                    using(RegistryKey exKey = root.OpenSubKey(extension, true))\n                    using(RegistryKey snKey = exKey.CreateSubKey(\"ShellNew\", true))\n                    {\n                        string defaultOpenMode = exKey.GetValue(\"\")?.ToString();\n                        if(string.IsNullOrEmpty(defaultOpenMode)) exKey.SetValue(\"\", openMode);\n\n                        byte[] bytes = GetWebShellNewData(extension);\n                        if(bytes != null) snKey.SetValue(\"Data\", bytes, RegistryValueKind.Binary);\n                        else snKey.SetValue(\"NullFile\", \"\", RegistryValueKind.String);\n\n                        ShellNewItem item = new ShellNewItem(this, snKey.Name);\n                        this.AddItem(item);\n                        item.Focus();\n                        if(item.ItemText.IsNullOrWhiteSpace())\n                        {\n                            item.ItemText = FileExtension.GetExtentionInfo(FileExtension.AssocStr.FriendlyDocName, extension);\n                        }\n                        if(ShellNewLockItem.IsLocked) this.SaveSorting();\n                    }\n                }\n            };\n        }\n\n        private static byte[] GetWebShellNewData(string extension)\n        {\n            string apiUrl = AppConfig.RequestUseGithub ? AppConfig.GithubShellNewApi : AppConfig.GiteeShellNewApi;\n            using(UAWebClient client = new UAWebClient())\n            {\n                XmlDocument doc = client.GetWebJsonToXml(apiUrl);\n                if(doc == null) return null;\n                foreach(XmlNode node in doc.FirstChild.ChildNodes)\n                {\n                    XmlNode nameXN = node.SelectSingleNode(\"name\");\n                    string str = Path.GetExtension(nameXN.InnerText);\n                    if(string.Equals(str, extension, StringComparison.OrdinalIgnoreCase))\n                    {\n                        try\n                        {\n                            string dirUrl = AppConfig.RequestUseGithub ? AppConfig.GithubShellNewRawDir : AppConfig.GiteeShellNewRawDir;\n                            string fileUrl = $\"{dirUrl}/{nameXN.InnerText}\";\n                            return client.DownloadData(fileUrl);\n                        }\n                        catch { return null; }\n                    }\n                }\n                return null;\n            }\n        }\n\n        public sealed class ShellNewLockItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem, ITsiWebSearchItem, ITsiRegPathItem\n        {\n            public ShellNewLockItem(ShellNewList list)\n            {\n                this.Owner = list;\n                this.Image = AppImage.Lock;\n                this.Text = AppString.Other.LockNewMenu;\n                BtnShowMenu = new MenuButton(this);\n                ChkVisible = new VisibleCheckBox(this) { Checked = IsLocked };\n                ToolTipBox.SetToolTip(ChkVisible, AppString.Tip.LockNewMenu);\n                TsiSearch = new WebSearchMenuItem(this);\n                TsiRegLocation = new RegLocationMenuItem(this);\n                this.ContextMenuStrip.Items.AddRange(new ToolStripItem[]\n                    { TsiSearch, new ToolStripSeparator(), TsiRegLocation });\n            }\n\n            public MenuButton BtnShowMenu { get; set; }\n            public WebSearchMenuItem TsiSearch { get; set; }\n            public RegLocationMenuItem TsiRegLocation { get; set; }\n            public VisibleCheckBox ChkVisible { get; set; }\n            public ShellNewList Owner { get; private set; }\n\n            public bool ItemVisible\n            {\n                get => IsLocked;\n                set\n                {\n                    if(value) Owner.SaveSorting();\n                    else UnLock();\n                    foreach(Control ctr in Owner.Controls)\n                    {\n                        if(ctr is ShellNewItem item)\n                        {\n                            item.SetSortabled(value);\n                        }\n                    }\n                }\n            }\n\n            public string SearchText => Text;\n            public string RegPath => ShellNewPath;\n            public string ValueName => \"Classes\";\n\n            public static bool IsLocked\n            {\n                get\n                {\n                    using(RegistryKey key = RegistryEx.GetRegistryKey(ShellNewPath))\n                    {\n                        RegistrySecurity rs = key.GetAccessControl();\n                        foreach(RegistryAccessRule rar in rs.GetAccessRules(true, true, typeof(NTAccount)))\n                        {\n                            if(rar.AccessControlType.ToString().Equals(\"Deny\", StringComparison.OrdinalIgnoreCase))\n                            {\n                                if(rar.IdentityReference.ToString().Equals(\"Everyone\", StringComparison.OrdinalIgnoreCase)) return true;\n                            }\n                        }\n                    }\n                    return false;\n                }\n            }\n\n            public static void Lock()\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey(ShellNewPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.ChangePermissions))\n                {\n                    RegistrySecurity rs = new RegistrySecurity();\n                    RegistryAccessRule rar = new RegistryAccessRule(\"Everyone\", RegistryRights.Delete | RegistryRights.WriteKey, AccessControlType.Deny);\n                    rs.AddAccessRule(rar);\n                    key.SetAccessControl(rs);\n                }\n            }\n\n            public static void UnLock()\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey(ShellNewPath, RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.ChangePermissions))\n                {\n                    RegistrySecurity rs = key.GetAccessControl();\n                    foreach(RegistryAccessRule rar in rs.GetAccessRules(true, true, typeof(NTAccount)))\n                    {\n                        if(rar.AccessControlType.ToString().Equals(\"Deny\", StringComparison.OrdinalIgnoreCase))\n                        {\n                            if(rar.IdentityReference.ToString().Equals(\"Everyone\", StringComparison.OrdinalIgnoreCase))\n                            {\n                                rs.RemoveAccessRule(rar);\n                            }\n                        }\n                    }\n                    key.SetAccessControl(rs);\n                }\n            }\n        }\n\n        public sealed class ShellNewSeparator : MyListItem\n        {\n            public ShellNewSeparator()\n            {\n                this.Text = AppString.Other.Separator;\n                this.HasImage = false;\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellStoreDialog.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ShellStoreDialog : CommonDialog\n    {\n        public string[] SelectedKeyNames { get; private set; }\n        public Func<string, bool> Filter { get; set; }\n        public string ShellPath { get; set; }\n        public bool IsReference { get; set; }\n\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            using(ShellStoreForm frm = new ShellStoreForm(this.ShellPath, this.Filter, this.IsReference))\n            {\n                frm.TopMost = AppConfig.TopMost;\n                bool flag = frm.ShowDialog() == DialogResult.OK;\n                if(flag) this.SelectedKeyNames = frm.SelectedKeyNames;\n                return flag;\n            }\n        }\n\n        public sealed class ShellStoreForm : Form\n        {\n            public string ShellPath { get; private set; }\n            public Func<string, bool> Filter { get; private set; }\n            public string[] SelectedKeyNames { get; private set; }\n\n            public ShellStoreForm(string shellPath, Func<string, bool> filter, bool isReference)\n            {\n                this.SuspendLayout();\n                this.Filter = filter;\n                this.ShellPath = shellPath;\n                this.AcceptButton = btnOK;\n                this.CancelButton = btnCancel;\n                this.Font = SystemFonts.MessageBoxFont;\n                this.SizeGripStyle = SizeGripStyle.Hide;\n                this.ShowIcon = this.ShowInTaskbar = false;\n                this.MinimizeBox = this.MaximizeBox = false;\n                this.StartPosition = FormStartPosition.CenterParent;\n                this.MinimumSize = this.Size = new Size(652, 422).DpiZoom();\n                this.Text = isReference ? AppString.Dialog.CheckReference : AppString.Dialog.CheckCopy;\n                btnOK.Click += (sender, e) => GetSelectedItems();\n                chkSelectAll.Click += (sender, e) =>\n                {\n                    bool flag = chkSelectAll.Checked;\n                    foreach(StoreShellItem item in list.Controls)\n                    {\n                        item.IsSelected = flag;\n                    }\n                };\n                list.Owner = listBox;\n                InitializeComponents();\n                LoadItems(isReference);\n                this.ResumeLayout();\n            }\n\n            readonly MyList list = new MyList();\n            readonly MyListBox listBox = new MyListBox();\n            readonly Panel pnlBorder = new Panel\n            {\n                BackColor = Color.FromArgb(200, 200, 200)\n            };\n            readonly Button btnOK = new Button\n            {\n                Anchor = AnchorStyles.Bottom | AnchorStyles.Right,\n                DialogResult = DialogResult.OK,\n                Text = ResourceString.OK,\n                AutoSize = true\n            };\n            readonly Button btnCancel = new Button\n            {\n                Anchor = AnchorStyles.Bottom | AnchorStyles.Right,\n                DialogResult = DialogResult.Cancel,\n                Text = ResourceString.Cancel,\n                AutoSize = true\n            };\n            readonly CheckBox chkSelectAll = new CheckBox\n            {\n                Anchor = AnchorStyles.Bottom | AnchorStyles.Left,\n                Text = AppString.Dialog.SelectAll,\n                Cursor = Cursors.Hand,\n                AutoSize = true\n            };\n\n            private void InitializeComponents()\n            {\n                this.Controls.AddRange(new Control[] { listBox, pnlBorder, btnOK, btnCancel, chkSelectAll });\n                int a = 20.DpiZoom();\n                listBox.Location = new Point(a, a);\n                pnlBorder.Location = new Point(a - 1, a - 1);\n                chkSelectAll.Top = btnOK.Top = btnCancel.Top = this.ClientSize.Height - btnCancel.Height - a;\n                btnCancel.Left = this.ClientSize.Width - btnCancel.Width - a;\n                btnOK.Left = btnCancel.Left - btnOK.Width - a;\n                chkSelectAll.Left = a;\n                this.OnResize(null);\n            }\n\n            protected override void OnResize(EventArgs e)\n            {\n                base.OnResize(e);\n                listBox.Width = ClientSize.Width - 2 * listBox.Left;\n                listBox.Height = btnOK.Top - 2 * listBox.Top;\n                pnlBorder.Width = listBox.Width + 2;\n                pnlBorder.Height = listBox.Height + 2;\n            }\n\n            private void LoadItems(bool isReference)\n            {\n                using(var shellKey = RegistryEx.GetRegistryKey(ShellPath))\n                {\n                    foreach(string itemName in shellKey.GetSubKeyNames())\n                    {\n                        if(Filter != null && !Filter(itemName)) continue;\n                        string regPath = $@\"{ShellPath}\\{itemName}\";\n                        StoreShellItem item = new StoreShellItem(regPath, isReference);\n                        item.SelectedChanged += () =>\n                        {\n                            foreach(StoreShellItem shellItem in list.Controls)\n                            {\n                                if(!shellItem.IsSelected)\n                                {\n                                    chkSelectAll.Checked = false;\n                                    return;\n                                }\n                            }\n                            chkSelectAll.Checked = true;\n                        };\n                        list.AddItem(item);\n                    }\n                }\n            }\n\n            private void GetSelectedItems()\n            {\n                List<string> names = new List<string>();\n                foreach(StoreShellItem item in list.Controls)\n                    if(item.IsSelected) names.Add(item.KeyName);\n                this.SelectedKeyNames = names.ToArray();\n            }\n        }\n    }\n\n    sealed class StoreShellItem : ShellItem\n    {\n        public StoreShellItem(string regPath, bool isPublic, bool isSelect = true) : base(regPath)\n        {\n            this.IsPublic = isPublic;\n            if(isSelect)\n            {\n                this.ContextMenuStrip = null;\n                this.AddCtr(chkSelected);\n                ChkVisible.Visible = BtnShowMenu.Visible = BtnSubItems.Visible = false;\n                this.MouseClick += (sender, e) => chkSelected.Checked = !chkSelected.Checked;\n                chkSelected.CheckedChanged += (sender, e) => SelectedChanged?.Invoke();\n            }\n            RegTrustedInstaller.TakeRegTreeOwnerShip(regPath);\n        }\n\n        public bool IsPublic { get; set; }\n        public bool IsSelected\n        {\n            get => chkSelected.Checked;\n            set => chkSelected.Checked = value;\n        }\n\n        readonly CheckBox chkSelected = new CheckBox\n        {\n            Cursor = Cursors.Hand,\n            AutoSize = true\n        };\n\n        public Action SelectedChanged;\n\n        public override void DeleteMe()\n        {\n            if(IsPublic && AppMessageBox.Show(AppString.Message.ConfirmDeleteReferenced,\n                MessageBoxButtons.YesNo) != DialogResult.Yes) return;\n            base.DeleteMe();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/ShellSubMenuDialog.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Reflection;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class ShellSubMenuDialog : CommonDialog\n    {\n        public Icon Icon { get; set; }\n        public string Text { get; set; }\n        /// <summary>子菜单的父菜单的注册表路径</summary>\n        public string ParentPath { get; set; }\n        public override void Reset() { }\n\n        protected override bool RunDialog(IntPtr hwndOwner)\n        {\n            bool isPublic = true;\n            string value = Microsoft.Win32.Registry.GetValue(this.ParentPath, \"SubCommands\", null)?.ToString();\n            if(value == null) isPublic = false;\n            else if(value.IsNullOrWhiteSpace())\n            {\n                using(var shellKey = RegistryEx.GetRegistryKey($@\"{ParentPath}\\shell\"))\n                {\n                    if(shellKey != null && shellKey.GetSubKeyNames().Length > 0) isPublic = false;\n                    else\n                    {\n                        string[] modes = new[] { ResourceString.Cancel, AppString.Dialog.Private, AppString.Dialog.Public };\n                        string mode = MessageBoxEx.Show(AppString.Message.SelectSubMenuMode, AppString.General.AppName,\n                            modes, MessageBoxImage.Question, null, modes[1]);\n                        if(mode == modes[2]) isPublic = true;\n                        else if(mode == modes[1]) isPublic = false;\n                        else return false;\n                    }\n                }\n            }\n\n            using(SubItemsForm frm = new SubItemsForm())\n            {\n                frm.Text = this.Text;\n                frm.Icon = this.Icon;\n                frm.TopMost = AppConfig.TopMost;\n\n                if(isPublic)\n                {\n                    frm.Text += $\"({AppString.Dialog.Public})\";\n                    PulicMultiItemsList list = new PulicMultiItemsList();\n                    frm.AddList(list);\n                    list.ParentPath = this.ParentPath;\n                    list.LoadItems();\n                }\n                else\n                {\n                    frm.Text += $\"({AppString.Dialog.Private})\";\n                    PrivateMultiItemsList list = new PrivateMultiItemsList();\n                    frm.AddList(list);\n                    list.ParentPath = this.ParentPath;\n                    list.LoadItems();\n                }\n\n                frm.ShowDialog();\n            }\n            return false;\n        }\n\n        sealed class PulicMultiItemsList : MyList\n        {\n            readonly List<string> SubKeyNames = new List<string>();\n            /// <summary>子菜单的父菜单的注册表路径</summary>\n            public string ParentPath { get; set; }\n            /// <summary>菜单所处环境注册表路径</summary>\n            private string ScenePath => RegistryEx.GetParentPath(RegistryEx.GetParentPath(ParentPath));\n\n            readonly SubNewItem subNewItem = new SubNewItem(true);\n\n            /// <param name=\"parentPath\">子菜单的父菜单的注册表路径</param>\n            public void LoadItems()\n            {\n                this.AddItem(subNewItem);\n                subNewItem.AddNewItem += () => AddNewItem();\n                subNewItem.AddExisting += () => AddReference();\n                subNewItem.AddSeparator += () => AddSeparator();\n\n                string value = Microsoft.Win32.Registry.GetValue(ParentPath, \"SubCommands\", null)?.ToString();\n                Array.ForEach(value.Split(';'), cmd => SubKeyNames.Add(cmd.TrimStart()));\n                SubKeyNames.RemoveAll(string.IsNullOrEmpty);\n\n                using(var shellKey = RegistryEx.GetRegistryKey(ShellItem.CommandStorePath, false, true))\n                {\n                    foreach(string keyName in SubKeyNames)\n                    {\n                        using(var key = shellKey.OpenSubKey(keyName))\n                        {\n                            MyListItem item;\n                            if(key != null) item = new SubShellItem(this, keyName);\n                            else if(keyName == \"|\") item = new SeparatorItem(this);\n                            else item = new InvalidItem(this, keyName);\n                            this.AddItem(item);\n                        }\n                    }\n                }\n            }\n\n            private void AddNewItem()\n            {\n                if(!SubShellTypeItem.CanAddMore(this)) return;\n                using(NewShellDialog dlg = new NewShellDialog())\n                {\n                    dlg.ScenePath = this.ScenePath;\n                    dlg.ShellPath = ShellItem.CommandStorePath;\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    SubKeyNames.Add(dlg.NewItemKeyName);\n                    this.SaveSorting();\n                    this.AddItem(new SubShellItem(this, dlg.NewItemKeyName));\n                }\n            }\n\n            private void AddReference()\n            {\n                if(!SubShellTypeItem.CanAddMore(this)) return;\n                using(ShellStoreDialog dlg = new ShellStoreDialog())\n                {\n                    dlg.IsReference = true;\n                    dlg.ShellPath = ShellItem.CommandStorePath;\n                    dlg.Filter = new Func<string, bool>(itemName => !(AppConfig.HideSysStoreItems\n                        && itemName.StartsWith(\"Windows.\", StringComparison.OrdinalIgnoreCase)));\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    foreach(string keyName in dlg.SelectedKeyNames)\n                    {\n                        if(!SubShellTypeItem.CanAddMore(this)) return;\n                        this.AddItem(new SubShellItem(this, keyName));\n                        this.SubKeyNames.Add(keyName);\n                        this.SaveSorting();\n                    }\n                }\n            }\n\n            private void AddSeparator()\n            {\n                if(this.Controls[this.Controls.Count - 1] is SeparatorItem) return;\n                this.SubKeyNames.Add(\"|\");\n                this.SaveSorting();\n                this.AddItem(new SeparatorItem(this));\n            }\n\n            private void SaveSorting()\n            {\n                Microsoft.Win32.Registry.SetValue(ParentPath, \"SubCommands\", string.Join(\";\", SubKeyNames.ToArray()));\n            }\n\n            private void MoveItem(MyListItem item, bool isUp)\n            {\n                int index = this.GetItemIndex(item);\n                if(isUp)\n                {\n                    if(index > 1)\n                    {\n                        this.SetItemIndex(item, index - 1);\n                        this.SubKeyNames.Reverse(index - 2, 2);\n                    }\n                }\n                else\n                {\n                    if(index < this.Controls.Count - 1)\n                    {\n                        this.SetItemIndex(item, index + 1);\n                        this.SubKeyNames.Reverse(index - 1, 2);\n                    }\n                }\n                this.SaveSorting();\n            }\n\n            private void DeleteItem(MyListItem item)\n            {\n                int index = this.GetItemIndex(item);\n                this.SubKeyNames.RemoveAt(index - 1);\n                if(index == this.Controls.Count - 1) index--;\n                this.Controls.Remove(item);\n                this.Controls[index].Focus();\n                this.SaveSorting();\n                item.Dispose();\n            }\n\n            sealed class SubShellItem : SubShellTypeItem\n            {\n                public SubShellItem(PulicMultiItemsList list, string keyName) : base($@\"{CommandStorePath}\\{keyName}\")\n                {\n                    this.Owner = list;\n                    BtnMoveUp.MouseDown += (sender, e) => Owner.MoveItem(this, true);\n                    BtnMoveDown.MouseDown += (sender, e) => Owner.MoveItem(this, false);\n                    ContextMenuStrip.Items.Remove(TsiDeleteMe);\n                    ContextMenuStrip.Items.Add(TsiDeleteRef);\n                    TsiDeleteRef.Click += (sender, e) => DeleteReference();\n                }\n\n                readonly ToolStripMenuItem TsiDeleteRef = new ToolStripMenuItem(AppString.Menu.DeleteReference);\n                public PulicMultiItemsList Owner { get; private set; }\n\n                private void DeleteReference()\n                {\n                    if(AppMessageBox.Show(AppString.Message.ConfirmDeleteReference, MessageBoxButtons.YesNo) == DialogResult.Yes)\n                    {\n                        Owner.DeleteItem(this);\n                    }\n                }\n            }\n\n            sealed class SeparatorItem : SubSeparatorItem\n            {\n                public SeparatorItem(PulicMultiItemsList list) : base()\n                {\n                    this.Owner = list;\n                    BtnMoveUp.MouseDown += (sender, e) => Owner.MoveItem(this, true);\n                    BtnMoveDown.MouseDown += (sender, e) => Owner.MoveItem(this, false);\n                }\n\n                public PulicMultiItemsList Owner { get; private set; }\n\n                public override void DeleteMe()\n                {\n                    Owner.DeleteItem(this);\n                }\n            }\n\n            sealed class InvalidItem : MyListItem, IBtnDeleteItem, IBtnMoveUpDownItem\n            {\n                public InvalidItem(PulicMultiItemsList list, string keyName)\n                {\n                    this.Owner = list;\n                    this.Text = $\"{AppString.Other.InvalidItem} {keyName}\";\n                    this.Image = AppImage.NotFound.ToTransparent();\n                    BtnDelete = new DeleteButton(this);\n                    BtnMoveDown = new MoveButton(this, false);\n                    BtnMoveUp = new MoveButton(this, true);\n                    BtnMoveUp.MouseDown += (sender, e) => Owner.MoveItem(this, true);\n                    BtnMoveDown.MouseDown += (sender, e) => Owner.MoveItem(this, false);\n                    ToolTipBox.SetToolTip(this, AppString.Tip.InvalidItem);\n                    ToolTipBox.SetToolTip(BtnDelete, AppString.Menu.Delete);\n                }\n\n                public DeleteButton BtnDelete { get; set; }\n                public PulicMultiItemsList Owner { get; private set; }\n                public MoveButton BtnMoveUp { get; set; }\n                public MoveButton BtnMoveDown { get; set; }\n\n                public void DeleteMe()\n                {\n                    Owner.DeleteItem(this);\n                }\n            }\n        }\n\n        sealed class PrivateMultiItemsList : MyList\n        {\n            readonly SubNewItem subNewItem = new SubNewItem(false);\n\n            /// <summary>父菜单的注册表路径</summary>\n            public string ParentPath { get; set; }\n            /// <summary>子菜单的Shell项注册表路径</summary>\n            private string ShellPath { get; set; }\n            /// <summary>父菜单的Shell项注册表路径</summary>\n            private string ParentShellPath => RegistryEx.GetParentPath(ParentPath);\n            /// <summary>菜单所处环境注册表路径</summary>\n            private string ScenePath => RegistryEx.GetParentPath(ParentShellPath);\n            /// <summary>父菜单的项名</summary>\n            private string ParentKeyName => RegistryEx.GetKeyName(ParentPath);\n\n            public void LoadItems()\n            {\n                this.AddItem(subNewItem);\n                subNewItem.AddNewItem += () => AddNewItem();\n                subNewItem.AddSeparator += () => AddSeparator();\n                subNewItem.AddExisting += () => AddFromParentMenu();\n\n                string sckValue = Microsoft.Win32.Registry.GetValue(this.ParentPath, \"ExtendedSubCommandsKey\", null)?.ToString();\n                if(!sckValue.IsNullOrWhiteSpace())\n                {\n                    this.ShellPath = $@\"{RegistryEx.CLASSES_ROOT}\\{sckValue}\\shell\";\n                }\n                else\n                {\n                    this.ShellPath = $@\"{this.ParentPath}\\shell\";\n                }\n                using(var shellKey = RegistryEx.GetRegistryKey(ShellPath))\n                {\n                    if(shellKey == null) return;\n                    RegTrustedInstaller.TakeRegTreeOwnerShip(shellKey.Name);\n                    foreach(string keyName in shellKey.GetSubKeyNames())\n                    {\n                        string regPath = $@\"{ShellPath}\\{keyName}\";\n                        int value = Convert.ToInt32(Microsoft.Win32.Registry.GetValue(regPath, \"CommandFlags\", 0));\n                        if(value % 16 >= 8)\n                        {\n                            this.AddItem(new SeparatorItem(this, regPath));\n                        }\n                        else\n                        {\n                            this.AddItem(new SubShellItem(this, regPath));\n                        }\n                    }\n                }\n            }\n\n            private void AddNewItem()\n            {\n                if(!SubShellTypeItem.CanAddMore(this)) return;\n                using(NewShellDialog dlg = new NewShellDialog\n                {\n                    ScenePath = this.ScenePath,\n                    ShellPath = this.ShellPath\n                })\n                {\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    this.AddItem(new SubShellItem(this, dlg.NewItemRegPath));\n                }\n            }\n\n            private void AddSeparator()\n            {\n                if(this.Controls[this.Controls.Count - 1] is SeparatorItem) return;\n                string regPath;\n                if(this.Controls.Count > 1)\n                {\n                    regPath = GetItemRegPath((MyListItem)Controls[Controls.Count - 1]);\n                }\n                else\n                {\n                    regPath = $@\"{ShellPath}\\Item\";\n                }\n                regPath = ObjectPath.GetNewPathWithIndex(regPath, ObjectPath.PathType.Registry);\n                Microsoft.Win32.Registry.SetValue(regPath, \"CommandFlags\", 0x8);\n                this.AddItem(new SeparatorItem(this, regPath));\n            }\n\n            private void AddFromParentMenu()\n            {\n                if(!SubShellTypeItem.CanAddMore(this)) return;\n                using(ShellStoreDialog dlg = new ShellStoreDialog())\n                {\n                    dlg.IsReference = false;\n                    dlg.ShellPath = this.ParentShellPath;\n                    dlg.Filter = new Func<string, bool>(itemName => !itemName.Equals(this.ParentKeyName, StringComparison.OrdinalIgnoreCase));\n                    if(dlg.ShowDialog() != DialogResult.OK) return;\n                    foreach(string keyName in dlg.SelectedKeyNames)\n                    {\n                        if(!SubShellTypeItem.CanAddMore(this)) return;\n                        string srcPath = $@\"{dlg.ShellPath}\\{keyName}\";\n                        string dstPath = ObjectPath.GetNewPathWithIndex($@\"{ShellPath}\\{keyName}\", ObjectPath.PathType.Registry);\n\n                        RegistryEx.CopyTo(srcPath, dstPath);\n                        this.AddItem(new SubShellItem(this, dstPath));\n                    }\n                }\n            }\n\n            public void MoveItem(MyListItem item, bool isUp)\n            {\n                int index = this.GetItemIndex(item);\n                MyListItem otherItem = null;\n                if(isUp)\n                {\n                    if(index > 1)\n                    {\n                        otherItem = (MyListItem)this.Controls[index - 1];\n                        this.SetItemIndex(item, index - 1);\n                    }\n                }\n                else\n                {\n                    if(index < this.Controls.Count - 1)\n                    {\n                        otherItem = (MyListItem)this.Controls[index + 1];\n                        this.SetItemIndex(item, index + 1);\n                    }\n                }\n                if(otherItem != null)\n                {\n                    string path1 = GetItemRegPath(item);\n                    string path2 = GetItemRegPath(otherItem);\n                    string tempPath = ObjectPath.GetNewPathWithIndex(path1, ObjectPath.PathType.Registry);\n                    RegistryEx.MoveTo(path1, tempPath);\n                    RegistryEx.MoveTo(path2, path1);\n                    RegistryEx.MoveTo(tempPath, path2);\n                    SetItemRegPath(item, path2);\n                    SetItemRegPath(otherItem, path1);\n                }\n            }\n\n            private string GetItemRegPath(MyListItem item)\n            {\n                PropertyInfo pi = item.GetType().GetProperty(\"RegPath\");\n                return pi.GetValue(item, null).ToString();\n            }\n\n            private void SetItemRegPath(MyListItem item, string regPath)\n            {\n                PropertyInfo pi = item.GetType().GetProperty(\"RegPath\");\n                pi.SetValue(item, regPath, null);\n            }\n\n            sealed class SubShellItem : SubShellTypeItem\n            {\n                public SubShellItem(PrivateMultiItemsList list, string regPath) : base(regPath)\n                {\n                    this.Owner = list;\n                    BtnMoveUp.MouseDown += (sender, e) => Owner.MoveItem(this, true);\n                    BtnMoveDown.MouseDown += (sender, e) => Owner.MoveItem(this, false);\n                    SetItemTextValue();\n                }\n\n                public PrivateMultiItemsList Owner { get; private set; }\n\n                private void SetItemTextValue()\n                {\n                    using(var key = RegistryEx.GetRegistryKey(this.RegPath, true))\n                    {\n                        bool hasValue = false;\n                        foreach(string valueName in new[] { \"MUIVerb\", \"\" })\n                        {\n                            if(key.GetValue(valueName) != null)\n                            {\n                                hasValue = true; break;\n                            }\n                        }\n                        if(!hasValue) key.SetValue(\"MUIVerb\", this.ItemText);\n                    }\n\n                }\n            }\n\n            sealed class SeparatorItem : SubSeparatorItem\n            {\n                public SeparatorItem(PrivateMultiItemsList list, string regPath)\n                {\n                    this.Owner = list;\n                    this.RegPath = regPath;\n                    BtnMoveUp.MouseDown += (sender, e) => Owner.MoveItem(this, true);\n                    BtnMoveDown.MouseDown += (sender, e) => Owner.MoveItem(this, false);\n                }\n\n                public PrivateMultiItemsList Owner { get; private set; }\n                public string RegPath { get; private set; }\n\n                public override void DeleteMe()\n                {\n                    RegistryEx.DeleteKeyTree(this.RegPath);\n                    int index = this.Parent.Controls.GetChildIndex(this);\n                    if(index == this.Parent.Controls.Count - 1) index--;\n                    this.Parent.Controls[index].Focus();\n                    this.Parent.Controls.Remove(this);\n                    this.Dispose();\n                }\n            }\n        }\n\n        class SubSeparatorItem : MyListItem, IBtnDeleteItem, IBtnMoveUpDownItem\n        {\n            public SubSeparatorItem()\n            {\n                this.Text = AppString.Other.Separator;\n                this.HasImage = false;\n                BtnDelete = new DeleteButton(this);\n                BtnMoveDown = new MoveButton(this, false);\n                BtnMoveUp = new MoveButton(this, true);\n                ToolTipBox.SetToolTip(BtnDelete, AppString.Menu.Delete);\n            }\n\n            public DeleteButton BtnDelete { get; set; }\n            public MoveButton BtnMoveUp { get; set; }\n            public MoveButton BtnMoveDown { get; set; }\n\n            public virtual void DeleteMe() { }\n        }\n\n        class SubShellTypeItem : ShellItem, IBtnMoveUpDownItem\n        {\n            public SubShellTypeItem(string regPath) : base(regPath)\n            {\n                BtnMoveDown = new MoveButton(this, false);\n                BtnMoveUp = new MoveButton(this, true);\n                this.SetCtrIndex(BtnMoveDown, 1);\n                this.SetCtrIndex(BtnMoveUp, 2);\n            }\n\n            public MoveButton BtnMoveUp { get; set; }\n            public MoveButton BtnMoveDown { get; set; }\n\n            protected override bool IsSubItem => true;\n\n            public static bool CanAddMore(MyList list)\n            {\n                int count = 0;\n                foreach(Control item in list.Controls)\n                {\n                    if(item.GetType().BaseType == typeof(SubShellTypeItem)) count++;\n                }\n                bool flag = count < 16;\n                if(!flag) AppMessageBox.Show(AppString.Message.CannotAddNewItem);\n                return flag;\n            }\n        }\n\n        sealed class SubNewItem : NewItem\n        {\n            public SubNewItem(bool isPublic)\n            {\n                this.AddCtrs(new[] { btnAddExisting, btnAddSeparator });\n                ToolTipBox.SetToolTip(btnAddExisting, isPublic ? AppString.Tip.AddReference : AppString.Tip.AddFromParentMenu);\n                ToolTipBox.SetToolTip(btnAddSeparator, AppString.Tip.AddSeparator);\n                btnAddExisting.MouseDown += (sender, e) => AddExisting?.Invoke();\n                btnAddSeparator.MouseDown += (sender, e) => AddSeparator?.Invoke();\n            }\n\n            readonly PictureButton btnAddExisting = new PictureButton(AppImage.AddExisting);\n            readonly PictureButton btnAddSeparator = new PictureButton(AppImage.AddSeparator);\n\n            public Action AddExisting;\n            public Action AddSeparator;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/SubItemsForm.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class SubItemsForm : Form\n    {\n        public SubItemsForm()\n        {\n            this.SuspendLayout();\n            this.StartPosition = FormStartPosition.CenterParent;\n            this.ShowInTaskbar = this.MaximizeBox = this.MinimizeBox = false;\n            this.MinimumSize = this.Size = new Size(646, 419).DpiZoom();\n            this.Controls.AddRange(new Control[] { listBox, statusBar });\n            statusBar.CanMoveForm();\n            this.AddEscapeButton();\n            this.ResumeLayout();\n        }\n\n        readonly MyListBox listBox = new MyListBox { Dock = DockStyle.Fill };\n        readonly MyStatusBar statusBar = new MyStatusBar();\n\n        public void AddList(MyList myList)\n        {\n            myList.Owner = listBox;\n            myList.HoveredItemChanged += (sender, e) =>\n            {\n                if(!AppConfig.ShowFilePath) return;\n                MyListItem item = myList.HoveredItem;\n                foreach(string prop in new[] { \"ItemFilePath\", \"RegPath\", \"GroupPath\" })\n                {\n                    string path = item.GetType().GetProperty(prop)?.GetValue(item, null)?.ToString();\n                    if(!path.IsNullOrWhiteSpace()) { statusBar.Text = path; return; }\n                }\n                statusBar.Text = item.Text;\n            };\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/SwitchDicList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    class SwitchDicList : MyList\n    {\n        public bool UseUserDic { get; set; }\n\n        public virtual void LoadItems()\n        {\n            this.AddSwitchItem();\n        }\n\n        public void AddSwitchItem()\n        {\n            SwitchDicItem item = new SwitchDicItem { UseUserDic = this.UseUserDic };\n            item.UseDicChanged += () =>\n            {\n                this.UseUserDic = item.UseUserDic;\n                this.ClearItems();\n                this.LoadItems();\n            };\n            this.AddItem(item);\n        }\n    }\n\n    sealed class SwitchDicItem : MyListItem\n    {\n        public SwitchDicItem()\n        {\n            this.Text = AppString.Other.SwitchDictionaries;\n            this.AddCtr(cmbDic);\n            cmbDic.AutosizeDropDownWidth();\n            cmbDic.Font = new Font(this.Font.FontFamily, this.Font.Size + 1F);\n            cmbDic.Items.AddRange(new[] { AppString.Other.WebDictionaries, AppString.Other.UserDictionaries });\n            cmbDic.SelectionChangeCommitted += (sender, e) =>\n            {\n                this.Focus();\n                this.UseUserDic = cmbDic.SelectedIndex == 1;\n            };\n        }\n\n        private bool? useUserDic = null;\n        public bool UseUserDic\n        {\n            get => useUserDic == true;\n            set\n            {\n                if(useUserDic == value) return;\n                bool flag = useUserDic == null;\n                useUserDic = value;\n                this.Image = this.UseUserDic ? AppImage.User : AppImage.Web;\n                cmbDic.SelectedIndex = value ? 1 : 0;\n                if(!flag) UseDicChanged?.Invoke();\n            }\n        }\n\n        public Action UseDicChanged;\n\n        readonly ComboBox cmbDic = new ComboBox\n        {\n            DropDownStyle = ComboBoxStyle.DropDownList,\n            Width = 120.DpiZoom()\n        };\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/UwpModeItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class UwpModeItem : MyListItem, IChkVisibleItem, ITsiRegPathItem, ITsiFilePathItem,\n        IBtnShowMenuItem, ITsiWebSearchItem, ITsiRegExportItem, ITsiRegDeleteItem, ITsiGuidItem\n    {\n        public UwpModeItem(string uwpName, Guid guid)\n        {\n            this.Guid = guid;\n            this.UwpName = uwpName;\n            this.InitializeComponents();\n            this.Visible = UwpHelper.GetPackageName(uwpName) != null;\n            this.Image = GuidInfo.GetImage(guid);\n            this.Text = this.ItemText;\n        }\n\n        public Guid Guid { get; set; }\n        public string UwpName { get; set; }\n\n        public bool ItemVisible\n        {\n            get\n            {\n                foreach(string path in GuidBlockedList.BlockedPaths)\n                {\n                    using(RegistryKey key = RegistryEx.GetRegistryKey(path))\n                    {\n                        if(key == null) continue;\n                        if(key.GetValue(Guid.ToString(\"B\")) != null) return false;\n                    }\n                }\n                return true;\n            }\n            set\n            {\n                foreach(string path in GuidBlockedList.BlockedPaths)\n                {\n                    if(value)\n                    {\n                        RegistryEx.DeleteValue(path, Guid.ToString(\"B\"));\n                    }\n                    else\n                    {\n                        Registry.SetValue(path, Guid.ToString(\"B\"), \"\");\n                    }\n                }\n                ExplorerRestarter.Show();\n            }\n        }\n\n        public string ItemText => GuidInfo.GetText(Guid);\n        public string RegPath => UwpHelper.GetRegPath(UwpName, Guid);\n        public string ItemFilePath => UwpHelper.GetFilePath(UwpName, Guid);\n\n        public string SearchText => Text;\n        public string ValueName => \"DllPath\";\n        public MenuButton BtnShowMenu { get; set; }\n        public VisibleCheckBox ChkVisible { get; set; }\n        public DetailedEditButton BtnDetailedEdit { get; set; }\n        public RegLocationMenuItem TsiRegLocation { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public RegExportMenuItem TsiRegExport { get; set; }\n        public HandleGuidMenuItem TsiHandleGuid { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            BtnDetailedEdit = new DetailedEditButton(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiRegLocation = new RegLocationMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n            TsiRegExport = new RegExportMenuItem(this);\n            TsiHandleGuid = new HandleGuidMenuItem(this);\n\n            this.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiHandleGuid,\n                new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),\n                TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport });\n        }\n\n        public void DeleteMe()\n        {\n            RegistryEx.DeleteKeyTree(this.RegPath);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/WinXGroupItem.cs",
    "content": "﻿using ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class WinXGroupItem : FoldGroupItem, IChkVisibleItem, ITsiDeleteItem, ITsiTextItem\n    {\n        public WinXGroupItem(string groupPath) : base(groupPath, ObjectPath.PathType.Directory)\n        {\n            InitializeComponents();\n        }\n\n        public bool ItemVisible\n        {\n            get => (File.GetAttributes(GroupPath) & FileAttributes.Hidden) != FileAttributes.Hidden;\n            set\n            {\n                FileAttributes attributes = File.GetAttributes(GroupPath);\n                if(value) attributes &= ~FileAttributes.Hidden;\n                else attributes |= FileAttributes.Hidden;\n                File.SetAttributes(GroupPath, attributes);\n                if(Directory.GetFiles(GroupPath).Length > 0) ExplorerRestarter.Show();\n            }\n        }\n\n        public string ItemText\n        {\n            get => Path.GetFileNameWithoutExtension(GroupPath);\n            set\n            {\n                string newPath = $@\"{WinXList.WinXPath}\\{ObjectPath.RemoveIllegalChars(value)}\";\n                Directory.Move(GroupPath, newPath);\n                this.GroupPath = newPath;\n                ExplorerRestarter.Show();\n            }\n        }\n\n        public VisibleCheckBox ChkVisible { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        readonly ToolStripMenuItem TsiRestoreDefault = new ToolStripMenuItem(AppString.Menu.RestoreDefault);\n\n        private string DefaultGroupPath => $@\"{WinXList.DefaultWinXPath}\\{ItemText}\";\n\n        private void InitializeComponents()\n        {\n            ChkVisible = new VisibleCheckBox(this);\n            this.SetCtrIndex(ChkVisible, 1);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            this.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { new ToolStripSeparator(),\n                TsiChangeText, TsiRestoreDefault, new ToolStripSeparator(), TsiDeleteMe });\n            this.ContextMenuStrip.Opening += (sender, e) => TsiRestoreDefault.Enabled = Directory.Exists(DefaultGroupPath);\n            TsiRestoreDefault.Click += (sender, e) => RestoreDefault();\n        }\n\n        private void RestoreDefault()\n        {\n            if(AppMessageBox.Show(AppString.Message.RestoreDefault, MessageBoxButtons.OKCancel) == DialogResult.OK)\n            {\n                File.SetAttributes(GroupPath, FileAttributes.Normal);\n                Directory.Delete(GroupPath, true);\n                Directory.CreateDirectory(GroupPath);\n                File.SetAttributes(GroupPath, File.GetAttributes(DefaultGroupPath));\n                foreach(string srcPath in Directory.GetFiles(DefaultGroupPath))\n                {\n                    string dstPath = $@\"{GroupPath}\\{Path.GetFileName(srcPath)}\";\n                    File.Copy(srcPath, dstPath);\n                }\n                WinXList list = (WinXList)this.Parent;\n                list.ClearItems();\n                list.LoadItems();\n                ExplorerRestarter.Show();\n            }\n        }\n\n        public void DeleteMe()\n        {\n            bool flag = Directory.GetFiles(GroupPath, \"*.lnk\").Length > 0;\n            if(flag && AppMessageBox.Show(AppString.Message.DeleteGroup, MessageBoxButtons.OKCancel) != DialogResult.OK) return;\n            File.SetAttributes(GroupPath, FileAttributes.Normal);\n            Directory.Delete(GroupPath, true);\n            if(flag)\n            {\n                WinXList list = (WinXList)this.Parent;\n                list.ClearItems();\n                list.LoadItems();\n                ExplorerRestarter.Show();\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/WinXItem.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls.Interfaces;\nusing ContextMenuManager.Methods;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class WinXItem : FoldSubItem, IChkVisibleItem, IBtnShowMenuItem, IBtnMoveUpDownItem, ITsiAdministratorItem,\n        ITsiTextItem, ITsiWebSearchItem, ITsiFilePathItem, ITsiDeleteItem, ITsiShortcutCommandItem\n    {\n        public WinXItem(string filePath, FoldGroupItem group)\n        {\n            InitializeComponents();\n            this.FoldGroupItem = group;\n            this.FilePath = filePath;\n            this.Indent();\n        }\n\n        private string filePath;\n        public string FilePath\n        {\n            get => filePath;\n            set\n            {\n                filePath = value;\n                this.ShellLink = new ShellLink(value);\n                this.Text = this.ItemText;\n                this.Image = this.ItemImage;\n            }\n        }\n\n        public string ItemText\n        {\n            get\n            {\n                string name = ShellLink.Description?.Trim();\n                if(name.IsNullOrWhiteSpace()) name = DesktopIni.GetLocalizedFileNames(FilePath, true);\n                if(name == string.Empty) name = Path.GetFileNameWithoutExtension(FilePath);\n                return name;\n            }\n            set\n            {\n                ShellLink.Description = value;\n                ShellLink.Save();\n                DesktopIni.SetLocalizedFileNames(FilePath, value);\n                this.Text = ResourceString.GetDirectString(value);\n                ExplorerRestarter.Show();\n            }\n        }\n\n        public bool ItemVisible\n        {\n            get => (File.GetAttributes(FilePath) & FileAttributes.Hidden) != FileAttributes.Hidden;\n            set\n            {\n                FileAttributes attributes = File.GetAttributes(FilePath);\n                if(value) attributes &= ~FileAttributes.Hidden;\n                else attributes |= FileAttributes.Hidden;\n                File.SetAttributes(FilePath, attributes);\n                ExplorerRestarter.Show();\n            }\n        }\n\n        public Icon ItemIcon\n        {\n            get\n            {\n                ShellLink.ICONLOCATION iconLocation = ShellLink.IconLocation;\n                string iconPath = iconLocation.IconPath;\n                int iconIndex = iconLocation.IconIndex;\n                if(string.IsNullOrEmpty(iconPath)) iconPath = FilePath;\n                Icon icon = ResourceIcon.GetIcon(iconPath, iconIndex);\n                if(icon == null)\n                {\n                    string path = ItemFilePath;\n                    if(File.Exists(path)) icon = ResourceIcon.GetExtensionIcon(path);\n                    else if(Directory.Exists(path)) icon = ResourceIcon.GetFolderIcon(path);\n                }\n                return icon;\n            }\n        }\n\n        public string ItemFilePath\n        {\n            get\n            {\n                string path = ShellLink.TargetPath;\n                if(!File.Exists(path) && !Directory.Exists(path)) path = FilePath;\n                return path;\n            }\n        }\n\n        public ShellLink ShellLink { get; private set; }\n        public string SearchText => $\"{AppString.SideBar.WinX} {Text}\";\n        private string FileName => Path.GetFileName(FilePath);\n        private Image ItemImage => ItemIcon?.ToBitmap() ?? AppImage.NotFound;\n\n        public VisibleCheckBox ChkVisible { get; set; }\n        public MenuButton BtnShowMenu { get; set; }\n        public ChangeTextMenuItem TsiChangeText { get; set; }\n        public WebSearchMenuItem TsiSearch { get; set; }\n        public FilePropertiesMenuItem TsiFileProperties { get; set; }\n        public FileLocationMenuItem TsiFileLocation { get; set; }\n        public ShortcutCommandMenuItem TsiChangeCommand { get; set; }\n        public RunAsAdministratorItem TsiAdministrator { get; set; }\n        public DeleteMeMenuItem TsiDeleteMe { get; set; }\n        public MoveButton BtnMoveUp { get; set; }\n        public MoveButton BtnMoveDown { get; set; }\n\n        readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);\n        readonly ToolStripMenuItem TsiChangeGroup = new ToolStripMenuItem(AppString.Menu.ChangeGroup);\n\n        private void InitializeComponents()\n        {\n            BtnShowMenu = new MenuButton(this);\n            ChkVisible = new VisibleCheckBox(this);\n            BtnMoveDown = new MoveButton(this, false);\n            BtnMoveUp = new MoveButton(this, true);\n            TsiChangeText = new ChangeTextMenuItem(this);\n            TsiChangeCommand = new ShortcutCommandMenuItem(this);\n            TsiAdministrator = new RunAsAdministratorItem(this);\n            TsiSearch = new WebSearchMenuItem(this);\n            TsiFileLocation = new FileLocationMenuItem(this);\n            TsiFileProperties = new FilePropertiesMenuItem(this);\n            TsiDeleteMe = new DeleteMeMenuItem(this);\n\n            ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiChangeText, new ToolStripSeparator(),\n                TsiChangeGroup, new ToolStripSeparator(), TsiAdministrator, new ToolStripSeparator(),\n                TsiDetails, new ToolStripSeparator(), TsiDeleteMe });\n\n            TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch,\n                new ToolStripSeparator(), TsiChangeCommand, TsiFileProperties, TsiFileLocation });\n\n            TsiChangeGroup.Click += (sender, e) => ChangeGroup();\n            BtnMoveDown.MouseDown += (sender, e) => MoveItem(false);\n            BtnMoveUp.MouseDown += (sender, e) => MoveItem(true);\n            TsiChangeCommand.Click += (sender, e) =>\n            {\n                if(TsiChangeCommand.ChangeCommand(ShellLink))\n                {\n                    Image = this.ItemImage;\n                    WinXHasher.HashLnk(FilePath);\n                    ExplorerRestarter.Show();\n                }\n            };\n        }\n\n        private void ChangeGroup()\n        {\n            using(SelectDialog dlg = new SelectDialog())\n            {\n                dlg.Title = AppString.Dialog.SelectGroup;\n                dlg.Items = WinXList.GetGroupNames();\n                dlg.Selected = this.FoldGroupItem.Text;\n                if(dlg.ShowDialog() != DialogResult.OK) return;\n                if(dlg.Selected == this.FoldGroupItem.Text) return;\n                string dirPath = $@\"{WinXList.WinXPath}\\{dlg.Selected}\";\n                int count = Directory.GetFiles(dirPath, \"*.lnk\").Length;\n                string num = (count + 1).ToString().PadLeft(2, '0');\n                string partName = this.FileName;\n                int index = partName.IndexOf(\" - \");\n                if(index > 0) partName = partName.Substring(index + 3);\n                string lnkPath = $@\"{dirPath}\\{num} - {partName}\";\n                lnkPath = ObjectPath.GetNewPathWithIndex(lnkPath, ObjectPath.PathType.File);\n                string text = DesktopIni.GetLocalizedFileNames(FilePath);\n                DesktopIni.DeleteLocalizedFileNames(FilePath);\n                if(text != string.Empty) DesktopIni.SetLocalizedFileNames(lnkPath, text);\n                File.Move(FilePath, lnkPath);\n                this.FilePath = lnkPath;\n                WinXList list = (WinXList)this.Parent;\n                list.Controls.Remove(this);\n                for(int i = 0; i < list.Controls.Count; i++)\n                {\n                    if(list.Controls[i] is WinXGroupItem groupItem && groupItem.Text == dlg.Selected)\n                    {\n                        list.Controls.Add(this);\n                        list.SetItemIndex(this, i + 1);\n                        this.Visible = !groupItem.IsFold;\n                        this.FoldGroupItem = groupItem;\n                        break;\n                    }\n                }\n                ExplorerRestarter.Show();\n            }\n        }\n\n        private void MoveItem(bool isUp)\n        {\n            WinXList list = (WinXList)this.Parent;\n            int index = list.Controls.GetChildIndex(this);\n            if(index == list.Controls.Count - 1) return;\n            index += isUp ? -1 : 1;\n            Control ctr = list.Controls[index];\n            if(ctr is WinXGroupItem) return;\n            WinXItem item = (WinXItem)ctr;\n            string name1 = DesktopIni.GetLocalizedFileNames(this.FilePath);\n            string name2 = DesktopIni.GetLocalizedFileNames(item.FilePath);\n            DesktopIni.DeleteLocalizedFileNames(this.FilePath);\n            DesktopIni.DeleteLocalizedFileNames(item.FilePath);\n            string fileName1 = $@\"{item.FileName.Substring(0, 2)}{this.FileName.Substring(2)}\";\n            string fileName2 = $@\"{this.FileName.Substring(0, 2)}{item.FileName.Substring(2)}\";\n            string dirPath = Path.GetDirectoryName(this.FilePath);\n            string path1 = $@\"{dirPath}\\{fileName1}\";\n            string path2 = $@\"{dirPath}\\{fileName2}\";\n            path1 = ObjectPath.GetNewPathWithIndex(path1, ObjectPath.PathType.File);\n            path2 = ObjectPath.GetNewPathWithIndex(path2, ObjectPath.PathType.File);\n            File.Move(this.FilePath, path1);\n            File.Move(item.FilePath, path2);\n            if(name1 != string.Empty) DesktopIni.SetLocalizedFileNames(path1, name1);\n            if(name1 != string.Empty) DesktopIni.SetLocalizedFileNames(path2, name2);\n            this.FilePath = path1;\n            item.FilePath = path2;\n            list.SetItemIndex(this, index);\n            ExplorerRestarter.Show();\n        }\n\n        public void DeleteMe()\n        {\n            File.Delete(FilePath);\n            DesktopIni.DeleteLocalizedFileNames(FilePath);\n            ExplorerRestarter.Show();\n            this.ShellLink.Dispose();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Controls/WinXList.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Text;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Controls\n{\n    sealed class WinXList : MyList\n    {\n        public static readonly string WinXPath = Environment.ExpandEnvironmentVariables(@\"%LocalAppData%\\Microsoft\\Windows\\WinX\");\n        public static readonly string DefaultWinXPath = Environment.ExpandEnvironmentVariables(@\"%SystemDrive%\\Users\\Default\\AppData\\Local\\Microsoft\\Windows\\WinX\");\n\n        public void LoadItems()\n        {\n            if(WinOsVersion.Current >= WinOsVersion.Win8)\n            {\n                this.AddNewItem();\n                this.LoadWinXItems();\n            }\n        }\n\n        private void LoadWinXItems()\n        {\n            string[] dirPaths = Directory.GetDirectories(WinXPath);\n            Array.Reverse(dirPaths);\n            bool sorted = false;\n            foreach(string dirPath in dirPaths)\n            {\n                WinXGroupItem groupItem = new WinXGroupItem(dirPath);\n                this.AddItem(groupItem);\n                string[] lnkPaths;\n                if(AppConfig.WinXSortable)\n                {\n                    lnkPaths = GetSortedPaths(dirPath, out bool flag);\n                    if(flag) sorted = true;\n                }\n                else\n                {\n                    lnkPaths = Directory.GetFiles(dirPath, \"*.lnk\");\n                    Array.Reverse(lnkPaths);\n                }\n                foreach(string path in lnkPaths)\n                {\n                    WinXItem winXItem = new WinXItem(path, groupItem);\n                    winXItem.BtnMoveDown.Visible = winXItem.BtnMoveUp.Visible = AppConfig.WinXSortable;\n                    this.AddItem(winXItem);\n                }\n            }\n            if(sorted)\n            {\n                ExplorerRestarter.Show();\n                AppMessageBox.Show(AppString.Message.WinXSorted);\n            }\n        }\n\n        private void AddNewItem()\n        {\n            NewItem newItem = new NewItem();\n            this.AddItem(newItem);\n            PictureButton btnCreateDir = new PictureButton(AppImage.NewFolder);\n            ToolTipBox.SetToolTip(btnCreateDir, AppString.Tip.CreateGroup);\n            newItem.AddCtr(btnCreateDir);\n            btnCreateDir.MouseDown += (sender, e) => CreateNewGroup();\n            newItem.AddNewItem += () =>\n            {\n                using(NewLnkFileDialog dlg1 = new NewLnkFileDialog())\n                {\n                    if(dlg1.ShowDialog() != DialogResult.OK) return;\n                    using(SelectDialog dlg2 = new SelectDialog())\n                    {\n                        dlg2.Title = AppString.Dialog.SelectGroup;\n                        dlg2.Items = GetGroupNames();\n                        if(dlg2.ShowDialog() != DialogResult.OK) return;\n                        string dirName = dlg2.Selected;\n                        string dirPath = $@\"{WinXPath}\\{dirName}\";\n                        string itemText = dlg1.ItemText;\n                        string targetPath = dlg1.ItemFilePath;\n                        string arguments = dlg1.Arguments;\n                        string workDir = Path.GetDirectoryName(targetPath);\n                        string extension = Path.GetExtension(targetPath).ToLower();\n                        string fileName = Path.GetFileNameWithoutExtension(targetPath);\n                        int count = Directory.GetFiles(dirPath, \"*.lnk\").Length;\n                        string index = (count + 1).ToString().PadLeft(2, '0');\n                        string lnkName = $\"{index} - {fileName}.lnk\";\n                        string lnkPath = $@\"{dirPath}\\{lnkName}\";\n                        using(ShellLink shellLink = new ShellLink(lnkPath))\n                        {\n                            if(extension == \".lnk\")\n                            {\n                                File.Copy(targetPath, lnkPath);\n                                shellLink.Load();\n                            }\n                            else\n                            {\n                                shellLink.TargetPath = targetPath;\n                                shellLink.Arguments = arguments;\n                                shellLink.WorkingDirectory = workDir;\n                            }\n                            shellLink.Description = itemText;\n                            shellLink.Save();\n                        }\n                        DesktopIni.SetLocalizedFileNames(lnkPath, itemText);\n                        foreach(MyListItem ctr in this.Controls)\n                        {\n                            if(ctr is WinXGroupItem groupItem && groupItem.Text == dirName)\n                            {\n                                WinXItem item = new WinXItem(lnkPath, groupItem) { Visible = !groupItem.IsFold };\n                                item.BtnMoveDown.Visible = item.BtnMoveUp.Visible = AppConfig.WinXSortable;\n                                this.InsertItem(item, this.GetItemIndex(groupItem) + 1);\n                                break;\n                            }\n                        }\n                        WinXHasher.HashLnk(lnkPath);\n                        ExplorerRestarter.Show();\n                    }\n                }\n            };\n        }\n\n        private void CreateNewGroup()\n        {\n            string dirPath = ObjectPath.GetNewPathWithIndex($@\"{WinXPath}\\Group\", ObjectPath.PathType.Directory, 1);\n            Directory.CreateDirectory(dirPath);\n            string iniPath = $@\"{dirPath}\\desktop.ini\";\n            File.WriteAllText(iniPath, string.Empty, Encoding.Unicode);\n            File.SetAttributes(dirPath, File.GetAttributes(dirPath) | FileAttributes.ReadOnly);\n            File.SetAttributes(iniPath, File.GetAttributes(iniPath) | FileAttributes.Hidden | FileAttributes.System);\n            this.InsertItem(new WinXGroupItem(dirPath), 1);\n        }\n\n        public static string[] GetGroupNames()\n        {\n            List<string> items = new List<string>();\n            DirectoryInfo winxDi = new DirectoryInfo(WinXPath);\n            foreach(DirectoryInfo di in winxDi.GetDirectories()) items.Add(di.Name);\n            items.Reverse();\n            return items.ToArray();\n        }\n\n        private static string[] GetSortedPaths(string groupPath, out bool sorted)\n        {\n            sorted = false;\n            List<string> sortedPaths = new List<string>();\n            string[] paths = Directory.GetFiles(groupPath, \"*.lnk\");\n            for(int i = paths.Length - 1; i >= 0; i--)\n            {\n                string srcPath = paths[i];\n                string name = Path.GetFileName(srcPath);\n                int index = name.IndexOf(\" - \");\n                if(index >= 2 && int.TryParse(name.Substring(0, index), out int num) && num == i + 1)\n                {\n                    sortedPaths.Add(srcPath); continue;\n                }\n                if(index >= 0) name = name.Substring(index + 3);\n                string dstPath = $@\"{groupPath}\\{(i + 1).ToString().PadLeft(2, '0')} - {name}\";\n                dstPath = ObjectPath.GetNewPathWithIndex(dstPath, ObjectPath.PathType.File);\n\n                string value;\n                using(ShellLink srcLnk = new ShellLink(srcPath))\n                {\n                    value = srcLnk.Description?.Trim();\n                }\n                if(string.IsNullOrEmpty(value)) value = DesktopIni.GetLocalizedFileNames(srcPath);\n                if(string.IsNullOrEmpty(value)) value = Path.GetFileNameWithoutExtension(name);\n                DesktopIni.DeleteLocalizedFileNames(srcPath);\n                DesktopIni.SetLocalizedFileNames(dstPath, value);\n                File.Move(srcPath, dstPath);\n                using(ShellLink dstLnk = new ShellLink(dstPath))\n                {\n                    dstLnk.Description = value;\n                    dstLnk.Save();\n                }\n                sortedPaths.Add(dstPath);\n                sorted = true;\n            }\n            return sortedPaths.ToArray();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/MainForm.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing ContextMenuManager.Controls;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager\n{\n    sealed class MainForm : MyMainForm\n    {\n        public MainForm()\n        {\n            this.TopMost = AppConfig.TopMost;\n            this.Size = AppConfig.MainFormSize;\n            this.Text = AppString.General.AppName;\n            this.Controls.Add(explorerRestarter);\n            ToolBar.AddButtons(ToolBarButtons);\n            MainBody.Controls.AddRange(MainControls);\n            ToolBarButtons[3].CanBeSelected = false;\n            ToolBarButtons[3].MouseDown += (sender, e) => RefreshApp();\n            ToolBar.SelectedButtonChanged += (sender, e) => SwitchTab();\n            SideBar.HoverIndexChanged += (sender, e) => ShowItemInfo();\n            SideBar.SelectIndexChanged += (sender, e) => SwitchItem();\n            this.Shown += (sender, e) => FirstRunDownloadLanguage();\n            this.FormClosing += (sender, e) => CloseMainForm();\n            HoveredToShowItemPath();\n            DragDropToAnalysis();\n            AddContextMenus();\n            ResizeSideBar();\n            JumpItem(0, 0);\n        }\n\n        readonly MyToolBarButton[] ToolBarButtons =\n        {\n            new MyToolBarButton(AppImage.Home, AppString.ToolBar.Home),\n            new MyToolBarButton(AppImage.Type, AppString.ToolBar.Type),\n            new MyToolBarButton(AppImage.Star, AppString.ToolBar.Rule),\n            new MyToolBarButton(AppImage.Refresh, AppString.ToolBar.Refresh),\n            new MyToolBarButton(AppImage.About, AppString.ToolBar.About)\n        };\n\n        private Control[] MainControls => new Control[]\n        {\n            shellList, shellNewList, sendToList, openWithList, winXList,\n            enhanceMenusList, detailedEditList, guidBlockedList, iEList,\n            appSettingBox, languagesBox, dictionariesBox, aboutMeBox, donateBox\n        };\n\n        readonly ShellList shellList = new ShellList();\n        readonly ShellNewList shellNewList = new ShellNewList();\n        readonly SendToList sendToList = new SendToList();\n        readonly OpenWithList openWithList = new OpenWithList();\n        readonly WinXList winXList = new WinXList();\n\n        readonly EnhanceMenusList enhanceMenusList = new EnhanceMenusList();\n        readonly DetailedEditList detailedEditList = new DetailedEditList();\n        readonly GuidBlockedList guidBlockedList = new GuidBlockedList();\n        readonly IEList iEList = new IEList();\n\n        readonly AppSettingBox appSettingBox = new AppSettingBox();\n        readonly LanguagesBox languagesBox = new LanguagesBox();\n        readonly DictionariesBox dictionariesBox = new DictionariesBox();\n        readonly ReadOnlyRichTextBox aboutMeBox = new ReadOnlyRichTextBox();\n        readonly DonateBox donateBox = new DonateBox();\n        readonly ExplorerRestarter explorerRestarter = new ExplorerRestarter();\n\n        static readonly string[] GeneralItems =\n        {\n            AppString.SideBar.File,\n            AppString.SideBar.Folder,\n            AppString.SideBar.Directory,\n            AppString.SideBar.Background,\n            AppString.SideBar.Desktop,\n            AppString.SideBar.Drive,\n            AppString.SideBar.AllObjects,\n            AppString.SideBar.Computer,\n            AppString.SideBar.RecycleBin,\n            AppString.SideBar.Library,\n            null,\n            AppString.SideBar.New,\n            AppString.SideBar.SendTo,\n            AppString.SideBar.OpenWith,\n            null,\n            AppString.SideBar.WinX\n        };\n        static readonly string[] GeneralItemInfos =\n        {\n            AppString.StatusBar.File,\n            AppString.StatusBar.Folder,\n            AppString.StatusBar.Directory,\n            AppString.StatusBar.Background,\n            AppString.StatusBar.Desktop,\n            AppString.StatusBar.Drive,\n            AppString.StatusBar.AllObjects,\n            AppString.StatusBar.Computer,\n            AppString.StatusBar.RecycleBin,\n            AppString.StatusBar.Library,\n            null,\n            AppString.StatusBar.New,\n            AppString.StatusBar.SendTo,\n            AppString.StatusBar.OpenWith,\n            null,\n            AppString.StatusBar.WinX\n        };\n\n        static readonly string[] TypeItems =\n        {\n            AppString.SideBar.LnkFile,\n            AppString.SideBar.UwpLnk,\n            AppString.SideBar.ExeFile,\n            null,\n            AppString.SideBar.CustomExtension,\n            AppString.SideBar.PerceivedType,\n            AppString.SideBar.DirectoryType,\n            null,\n            AppString.SideBar.UnknownType,\n            AppString.SideBar.MenuAnalysis\n        };\n        static readonly string[] TypeItemInfos =\n        {\n            AppString.StatusBar.LnkFile,\n            AppString.StatusBar.UwpLnk,\n            AppString.StatusBar.ExeFile,\n            null,\n            AppString.StatusBar.CustomExtension,\n            AppString.StatusBar.PerceivedType,\n            AppString.StatusBar.DirectoryType,\n            null,\n            AppString.StatusBar.UnknownType,\n            AppString.StatusBar.MenuAnalysis\n        };\n\n        static readonly string[] OtherRuleItems =\n        {\n            AppString.SideBar.EnhanceMenu,\n            AppString.SideBar.DetailedEdit,\n            null,\n            AppString.SideBar.DragDrop,\n            AppString.SideBar.PublicReferences,\n            AppString.SideBar.CustomRegPath,\n            null,\n            AppString.SideBar.GuidBlocked,\n            AppString.SideBar.IEMenu\n        };\n        static readonly string[] OtherRuleItemInfos =\n        {\n            AppString.StatusBar.EnhanceMenu,\n            AppString.StatusBar.DetailedEdit,\n            null,\n            AppString.StatusBar.DragDrop,\n            AppString.StatusBar.PublicReferences,\n            AppString.StatusBar.CustomRegPath,\n            null,\n            AppString.StatusBar.GuidBlocked,\n            AppString.StatusBar.IEMenu\n        };\n\n        static readonly string[] AboutItems =\n        {\n            AppString.SideBar.AppSetting,\n            AppString.SideBar.AppLanguage,\n            AppString.SideBar.Dictionaries,\n            AppString.SideBar.AboutApp,\n            AppString.SideBar.Donate\n        };\n\n        static readonly string[] SettingItems =\n        {\n            AppString.Other.TopMost,\n            null,\n            AppString.Other.ShowFilePath,\n            AppString.Other.HideDisabledItems,\n            null,\n            AppString.Other.OpenMoreRegedit,\n            AppString.Other.OpenMoreExplorer,\n        };\n\n        static readonly ShellList.Scenes[] GeneralShellScenes =\n        {\n            ShellList.Scenes.File,\n            ShellList.Scenes.Folder,\n            ShellList.Scenes.Directory,\n            ShellList.Scenes.Background,\n            ShellList.Scenes.Desktop,\n            ShellList.Scenes.Drive,\n            ShellList.Scenes.AllObjects,\n            ShellList.Scenes.Computer,\n            ShellList.Scenes.RecycleBin,\n            ShellList.Scenes.Library\n        };\n\n        static readonly ShellList.Scenes?[] TypeShellScenes =\n        {\n            ShellList.Scenes.LnkFile,\n            ShellList.Scenes.UwpLnk,\n            ShellList.Scenes.ExeFile,\n            null,\n            ShellList.Scenes.CustomExtension,\n            ShellList.Scenes.PerceivedType,\n            ShellList.Scenes.DirectoryType,\n            null,\n            ShellList.Scenes.UnknownType,\n            ShellList.Scenes.MenuAnalysis\n        };\n\n        readonly int[] lastItemIndex = new int[5];\n\n        public void JumpItem(int toolBarIndex, int sideBarIndex)\n        {\n            bool flag1 = ToolBar.SelectedIndex == toolBarIndex;\n            bool flag2 = SideBar.SelectedIndex == sideBarIndex;\n            lastItemIndex[toolBarIndex] = sideBarIndex;\n            ToolBar.SelectedIndex = toolBarIndex;\n            if(flag1 || flag2)\n            {\n                SideBar.SelectedIndex = sideBarIndex;\n                SwitchItem();\n            }\n        }\n\n        private void RefreshApp()\n        {\n            this.Cursor = Cursors.WaitCursor;\n            ObjectPath.FilePathDic.Clear();\n            AppConfig.ReloadConfig();\n            GuidInfo.ReloadDics();\n            XmlDicHelper.ReloadDics();\n            this.SwitchItem();\n            this.Cursor = Cursors.Default;\n        }\n\n        private void SwitchTab()\n        {\n            switch(ToolBar.SelectedIndex)\n            {\n                case 0:\n                    SideBar.ItemNames = GeneralItems; break;\n                case 1:\n                    SideBar.ItemNames = TypeItems; break;\n                case 2:\n                    SideBar.ItemNames = OtherRuleItems; break;\n                case 4:\n                    SideBar.ItemNames = AboutItems; break;\n            }\n            SideBar.SelectedIndex = lastItemIndex[ToolBar.SelectedIndex];\n        }\n\n        private void SwitchItem()\n        {\n            foreach(Control ctr in MainControls)\n            {\n                ctr.Visible = false;\n                if(ctr is MyList list) list.ClearItems();\n            }\n            if(SideBar.SelectedIndex == -1) return;\n            switch(ToolBar.SelectedIndex)\n            {\n                case 0:\n                    SwitchGeneralItem(); break;\n                case 1:\n                    SwitchTypeItem(); break;\n                case 2:\n                    SwitchOtherRuleItem(); break;\n                case 4:\n                    SwitchAboutItem(); break;\n            }\n            lastItemIndex[ToolBar.SelectedIndex] = SideBar.SelectedIndex;\n            this.SuspendMainBodyWhenMove = MainControls.ToList().Any(ctr => ctr.Controls.Count > 50);\n        }\n\n        private void ShowItemInfo()\n        {\n            if(SideBar.HoveredIndex >= 0)\n            {\n                int i = SideBar.HoveredIndex;\n                switch(ToolBar.SelectedIndex)\n                {\n                    case 0:\n                        StatusBar.Text = GeneralItemInfos[i]; return;\n                    case 1:\n                        StatusBar.Text = TypeItemInfos[i]; return;\n                    case 2:\n                        StatusBar.Text = OtherRuleItemInfos[i]; return;\n                }\n            }\n            StatusBar.Text = MyStatusBar.DefaultText;\n        }\n\n        private void HoveredToShowItemPath()\n        {\n            foreach(Control ctr in MainBody.Controls)\n            {\n                if(ctr is MyList list && list != appSettingBox)\n                {\n                    list.HoveredItemChanged += (sender, e) =>\n                    {\n                        if(!AppConfig.ShowFilePath) return;\n                        MyListItem item = list.HoveredItem;\n                        foreach(string prop in new[] { \"ItemFilePath\", \"RegPath\", \"GroupPath\", \"SelectedPath\" })\n                        {\n                            string path = item.GetType().GetProperty(prop)?.GetValue(item, null)?.ToString();\n                            if(!path.IsNullOrWhiteSpace()) { StatusBar.Text = path; return; }\n                        }\n                        StatusBar.Text = item.Text;\n                    };\n                }\n            }\n        }\n\n        private void DragDropToAnalysis()\n        {\n            var droper = new ElevatedFileDroper(this);\n            droper.DragDrop += (sender, e) =>\n            {\n                ShellList.CurrentFileObjectPath = droper.DropFilePaths[0];\n                JumpItem(1, 9);\n            };\n        }\n\n        private void SwitchGeneralItem()\n        {\n            switch(SideBar.SelectedIndex)\n            {\n                case 11:\n                    shellNewList.LoadItems(); shellNewList.Visible = true; break;\n                case 12:\n                    sendToList.LoadItems(); sendToList.Visible = true; break;\n                case 13:\n                    openWithList.LoadItems(); openWithList.Visible = true; break;\n                case 15:\n                    winXList.LoadItems(); winXList.Visible = true; break;\n                default:\n                    shellList.Scene = GeneralShellScenes[SideBar.SelectedIndex];\n                    shellList.LoadItems(); shellList.Visible = true; break;\n            }\n        }\n\n        private void SwitchTypeItem()\n        {\n            shellList.Scene = (ShellList.Scenes)TypeShellScenes[SideBar.SelectedIndex];\n            shellList.LoadItems();\n            shellList.Visible = true;\n        }\n\n        private void SwitchOtherRuleItem()\n        {\n            switch(SideBar.SelectedIndex)\n            {\n                case 0:\n                    enhanceMenusList.ScenePath = null; enhanceMenusList.LoadItems(); enhanceMenusList.Visible = true; break;\n                case 1:\n                    detailedEditList.GroupGuid = Guid.Empty; detailedEditList.LoadItems(); detailedEditList.Visible = true; break;\n                case 3:\n                    shellList.Scene = ShellList.Scenes.DragDrop; shellList.LoadItems(); shellList.Visible = true; break;\n                case 4:\n                    shellList.Scene = ShellList.Scenes.CommandStore; shellList.LoadItems(); shellList.Visible = true; break;\n                case 5:\n                    shellList.Scene = ShellList.Scenes.CustomRegPath; shellList.LoadItems(); shellList.Visible = true; break;\n                case 7:\n                    guidBlockedList.LoadItems(); guidBlockedList.Visible = true; break;\n                case 8:\n                    iEList.LoadItems(); iEList.Visible = true; break;\n            }\n        }\n\n        private void SwitchAboutItem()\n        {\n            switch(SideBar.SelectedIndex)\n            {\n                case 0:\n                    appSettingBox.LoadItems(); appSettingBox.Visible = true;\n                    break;\n                case 1:\n                    languagesBox.LoadLanguages(); languagesBox.Visible = true;\n                    break;\n                case 2:\n                    dictionariesBox.LoadText(); dictionariesBox.Visible = true;\n                    break;\n                case 3:\n                    if(aboutMeBox.TextLength == 0) aboutMeBox.LoadIni(AppString.Other.AboutApp);\n                    aboutMeBox.Visible = true; break;\n                case 4:\n                    donateBox.Visible = true; break;\n            }\n        }\n\n        private void ResizeSideBar()\n        {\n            SideBar.Width = 0;\n            string[] strs = GeneralItems.Concat(TypeItems).Concat(OtherRuleItems).Concat(AboutItems).ToArray();\n            Array.ForEach(strs, str => SideBar.Width = Math.Max(SideBar.Width, SideBar.GetItemWidth(str)));\n        }\n\n        private void AddContextMenus()\n        {\n            var dic = new Dictionary<MyToolBarButton, string[]>\n            {\n                { ToolBarButtons[0], GeneralItems },\n                { ToolBarButtons[1], TypeItems },\n                { ToolBarButtons[2], OtherRuleItems },\n                { ToolBarButtons[4], SettingItems }\n            };\n\n            foreach(var item in dic)\n            {\n                ContextMenuStrip cms = new ContextMenuStrip();\n                cms.MouseEnter += (sender, e) =>\n                {\n                    if(item.Key != ToolBar.SelectedButton) item.Key.Opacity = 0.2F;\n                };\n                cms.Closed += (sender, e) =>\n                {\n                    if(item.Key != ToolBar.SelectedButton) item.Key.Opacity = 0;\n                };\n                item.Key.MouseDown += (sender, e) =>\n                {\n                    if(e.Button != MouseButtons.Right) return;\n                    if(sender == ToolBar.SelectedButton) return;\n                    cms.Show(item.Key, e.Location);\n                };\n                for(int i = 0; i < item.Value.Length; i++)\n                {\n                    if(item.Value[i] == null) cms.Items.Add(new ToolStripSeparator());\n                    else\n                    {\n                        ToolStripMenuItem tsi = new ToolStripMenuItem(item.Value[i]);\n                        cms.Items.Add(tsi);\n                        int toolBarIndex = ToolBar.Controls.GetChildIndex(item.Key);\n                        int index = i;\n                        if(toolBarIndex != 4)\n                        {\n                            tsi.Click += (sender, e) => JumpItem(toolBarIndex, index);\n                            cms.Opening += (sender, e) => tsi.Checked = lastItemIndex[toolBarIndex] == index;\n                        }\n                        else\n                        {\n                            tsi.Click += (sender, e) =>\n                            {\n                                switch(index)\n                                {\n                                    case 0:\n                                        AppConfig.TopMost = this.TopMost = !tsi.Checked; break;\n                                    case 2:\n                                        AppConfig.ShowFilePath = !tsi.Checked; break;\n                                    case 3:\n                                        AppConfig.HideDisabledItems = !tsi.Checked; SwitchItem(); break;\n                                    case 5:\n                                        AppConfig.OpenMoreRegedit = !tsi.Checked; break;\n                                    case 6:\n                                        AppConfig.OpenMoreExplorer = !tsi.Checked; break;\n                                }\n                            };\n                            cms.Opening += (sender, e) =>\n                            {\n                                switch(index)\n                                {\n                                    case 0:\n                                        tsi.Checked = this.TopMost; break;\n                                    case 2:\n                                        tsi.Checked = AppConfig.ShowFilePath; break;\n                                    case 3:\n                                        tsi.Checked = AppConfig.HideDisabledItems; break;\n                                    case 5:\n                                        tsi.Checked = AppConfig.OpenMoreRegedit; break;\n                                    case 6:\n                                        tsi.Checked = AppConfig.OpenMoreExplorer; break;\n                                }\n                            };\n                        }\n                    }\n                }\n            }\n        }\n\n        private void FirstRunDownloadLanguage()\n        {\n            if(AppConfig.IsFirstRun && CultureInfo.CurrentUICulture.Name != \"zh-CN\")\n            {\n                if(AppMessageBox.Show(\"It is detected that you may be running this program for the first time,\\n\" +\n                    \"and your system display language is not simplified Chinese (zh-CN),\\n\" +\n                    \"do you need to download another language?\",\n                    MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)\n                {\n                    JumpItem(4, 1);\n                    languagesBox.ShowLanguageDialog();\n                }\n            }\n        }\n\n        private void CloseMainForm()\n        {\n            if(explorerRestarter.Visible && AppMessageBox.Show(explorerRestarter.Text,\n                MessageBoxButtons.OKCancel) == DialogResult.OK) ExternalProgram.RestartExplorer();\n            this.Opacity = 0;\n            this.WindowState = FormWindowState.Normal;\n            explorerRestarter.Visible = false;\n            AppConfig.MainFormSize = this.Size;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/AppConfig.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Methods\n{\n    static class AppConfig\n    {\n        static AppConfig()\n        {\n            CreateDirectory();\n            ReloadConfig();\n            LoadLanguage();\n        }\n\n        public const string GithubLatest = \"https://github.com/BluePointLilac/ContextMenuManager/releases/latest\";\n        public const string GithubLatestApi = \"https://api.github.com/repos/BluePointLilac/ContextMenuManager/releases/latest\";\n        public const string GithubLangsApi = \"https://api.github.com/repos/BluePointLilac/ContextMenuManager/contents/languages\";\n        public const string GithubLangsRawDir = \"https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/languages\";\n        public const string GithubShellNewApi = \"https://api.github.com/repos/BluePointLilac/ContextMenuManager/contents/ContextMenuManager/Properties/Resources/ShellNew\";\n        public const string GithubShellNewRawDir = \"https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/ContextMenuManager/Properties/Resources/ShellNew\";\n        public const string GithubTexts = \"https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/ContextMenuManager/Properties/Resources/Texts\";\n        public const string GithubDonateRaw = \"https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/Donate.md\";\n        public const string GithubDonate = \"https://github.com/BluePointLilac/ContextMenuManager/blob/master/Donate.md\";\n\n        public const string GiteeReleases = \"https://gitee.com/BluePointLilac/ContextMenuManager/releases\";\n        public const string GiteeLatestApi = \"https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/releases/latest\";\n        public const string GiteeLangsApi = \"https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/contents/languages\";\n        public const string GiteeLangsRawDir = \"https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/languages\";\n        public const string GiteeShellNewApi = \"https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/contents/ContextMenuManager/Properties/Resources/ShellNew\";\n        public const string GiteeShellNewRawDir = \"https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/ContextMenuManager/Properties/Resources/ShellNew\";\n        public const string GiteeTexts = \"https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/ContextMenuManager/Properties/Resources/Texts\";\n        public const string GiteeDonateRaw = \"https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/Donate.md\";\n        public const string GiteeDonate = \"https://gitee.com/BluePointLilac/ContextMenuManager/blob/master/Donate.md\";\n\n        public static readonly string AppConfigDir = $@\"{Application.StartupPath}\\Config\";\n        public static readonly string AppDataDir = Environment.ExpandEnvironmentVariables(@\"%AppData%\\ContextMenuManager\");\n        public static readonly string AppDataConfigDir = $@\"{AppDataDir}\\Config\";\n        public static readonly string ConfigDir = Directory.Exists(AppConfigDir) ? AppConfigDir : AppDataConfigDir;\n        public static readonly bool SaveToAppDir = ConfigDir == AppConfigDir;\n        public static readonly bool IsFirstRun = !Directory.Exists(ConfigDir);\n        public static string ConfigIni = $@\"{ConfigDir}\\Config.ini\";\n        public static string BackupDir = $@\"{ConfigDir}\\Backup\";\n        public static string LangsDir = $@\"{ConfigDir}\\Languages\";\n        public static string ProgramsDir = $@\"{ConfigDir}\\Programs\";\n        public static string DicsDir = $@\"{ConfigDir}\\Dictionaries\";\n        public static string WebDicsDir = $@\"{DicsDir}\\Web\";\n        public static string UserDicsDir = $@\"{DicsDir}\\User\";\n\n        public static string WebGuidInfosDic = $@\"{WebDicsDir}\\{GUIDINFOSDICINI}\";\n        public static string WebDetailedEditDic = $@\"{WebDicsDir}\\{DETAILEDEDITDICXML}\";\n        public static string WebEnhanceMenusDic = $@\"{WebDicsDir}\\{ENHANCEMENUSICXML}\";\n        public static string WebUwpModeItemsDic = $@\"{WebDicsDir}\\{UWPMODEITEMSDICXML}\";\n\n        public static string UserGuidInfosDic = $@\"{UserDicsDir}\\{GUIDINFOSDICINI}\";\n        public static string UserDetailedEditDic = $@\"{UserDicsDir}\\{DETAILEDEDITDICXML}\";\n        public static string UserEnhanceMenusDic = $@\"{UserDicsDir}\\{ENHANCEMENUSICXML}\";\n        public static string UserUwpModeItemsDic = $@\"{UserDicsDir}\\{UWPMODEITEMSDICXML}\";\n\n        public const string ZH_CNINI = \"zh-CN.ini\";\n        public const string GUIDINFOSDICINI = \"GuidInfosDic.ini\";\n        public const string DETAILEDEDITDICXML = \"DetailedEditDic.xml\";\n        public const string ENHANCEMENUSICXML = \"EnhanceMenusDic.xml\";\n        public const string UWPMODEITEMSDICXML = \"UwpModeItemsDic.xml\";\n\n        public static readonly Dictionary<string, string> EngineUrlsDic = new Dictionary<string, string>\n        {\n            { \"Bing\", \"https://www.bing.com/search?q=%s\" },\n            { \"Baidu\", \"https://www.baidu.com/s?wd=%s\" },\n            { \"Google\", \"https://www.google.com/search?q=%s\" },\n            { \"Yandex\", \"https://yandex.com/search/?text=%s\" },\n            { \"DuckDuckGo\", \"https://duckduckgo.com/?q=%s\" },\n            { \"Sogou\", \"https://www.sogou.com/web?query=%s\" },\n            { \"360\", \"https://www.so.com/s?q=%s\" },\n        };\n\n        private static readonly IniReader ConfigReader = new IniReader(ConfigIni);\n        private static readonly IniWriter ConfigWriter = new IniWriter(ConfigIni);\n\n        private static string GetGeneralValue(string key)\n        {\n            return ConfigReader.GetValue(\"General\", key);\n        }\n\n        private static void SetGeneralValue(string key, object value)\n        {\n            ConfigWriter.SetValue(\"General\", key, value);\n            ReloadConfig();\n        }\n\n        private static string GetWindowValue(string key)\n        {\n            return ConfigReader.GetValue(\"Window\", key);\n        }\n\n        private static void SetWindowValue(string key, object value)\n        {\n            ConfigWriter.SetValue(\"Window\", key, value);\n            ReloadConfig();\n        }\n\n        public static void ReloadConfig()\n        {\n            ConfigReader.LoadFile(ConfigIni);\n        }\n\n        private static void CreateDirectory()\n        {\n            foreach(string dirPath in new[] { AppDataDir, ConfigDir, ProgramsDir, BackupDir, LangsDir, DicsDir, WebDicsDir, UserDicsDir })\n            {\n                Directory.CreateDirectory(dirPath);\n                Application.ApplicationExit += (sender, e) =>\n                {\n                    if(Directory.Exists(dirPath) && Directory.GetFileSystemEntries(dirPath).Length == 0)\n                    {\n                        Directory.Delete(dirPath);\n                    }\n                };\n            }\n        }\n\n        private static void LoadLanguage()\n        {\n            language = GetGeneralValue(\"Language\");\n            if(language.ToLower() == \"default\")\n            {\n                LanguageIniPath = \"\";\n                return;\n            }\n            if(language == \"\") language = CultureInfo.CurrentUICulture.Name;\n            LanguageIniPath = $@\"{LangsDir}\\{language}.ini\";\n            if(!File.Exists(LanguageIniPath))\n            {\n                LanguageIniPath = \"\";\n                Language = \"\";\n            }\n        }\n\n        public static string LanguageIniPath { get; private set; }\n\n        private static string language;\n        public static string Language\n        {\n            get => language;\n            set => SetGeneralValue(\"Language\", value);\n        }\n\n        public static bool AutoBackup\n        {\n            get => GetGeneralValue(\"AutoBackup\") != \"0\";\n            set => SetGeneralValue(\"AutoBackup\", value ? 1 : 0);\n        }\n\n        public static DateTime LastCheckUpdateTime\n        {\n            get\n            {\n                try\n                {\n                    string time = GetGeneralValue(\"LastCheckUpdateTime\");\n                    //二进制数据时间不会受系统时间格式影响\n                    return DateTime.FromBinary(Convert.ToInt64(time));\n                }\n                catch\n                {\n                    return DateTime.MinValue;\n                    //返回文件上次修改时间\n                    //return new FileInfo(Application.ExecutablePath).LastWriteTime;\n                }\n            }\n            set => SetGeneralValue(\"LastCheckUpdateTime\", value.ToBinary());\n        }\n\n        public static bool ProtectOpenItem\n        {\n            get => GetGeneralValue(\"ProtectOpenItem\") != \"0\";\n            set => SetGeneralValue(\"ProtectOpenItem\", value ? 1 : 0);\n        }\n\n        public static string EngineUrl\n        {\n            get\n            {\n                string url = GetGeneralValue(\"EngineUrl\");\n                if(string.IsNullOrEmpty(url)) url = EngineUrlsDic.Values.ToArray()[0];\n                return url;\n            }\n            set => SetGeneralValue(\"EngineUrl\", value);\n        }\n\n        public static bool ShowFilePath\n        {\n            get => GetGeneralValue(\"ShowFilePath\") == \"1\";\n            set => SetGeneralValue(\"ShowFilePath\", value ? 1 : 0);\n        }\n\n        public static bool WinXSortable\n        {\n            get => GetGeneralValue(\"WinXSortable\") == \"1\";\n            set => SetGeneralValue(\"WinXSortable\", value ? 1 : 0);\n        }\n\n        public static bool OpenMoreRegedit\n        {\n            get => GetGeneralValue(\"OpenMoreRegedit\") == \"1\";\n            set => SetGeneralValue(\"OpenMoreRegedit\", value ? 1 : 0);\n        }\n\n        public static bool OpenMoreExplorer\n        {\n            get => GetGeneralValue(\"OpenMoreExplorer\") == \"1\";\n            set => SetGeneralValue(\"OpenMoreExplorer\", value ? 1 : 0);\n        }\n\n        public static bool HideDisabledItems\n        {\n            get => GetGeneralValue(\"HideDisabledItems\") == \"1\";\n            set => SetGeneralValue(\"HideDisabledItems\", value ? 1 : 0);\n        }\n\n        public static bool HideSysStoreItems\n        {\n            get => GetGeneralValue(\"HideSysStoreItems\") != \"0\";\n            set => SetGeneralValue(\"HideSysStoreItems\", value ? 1 : 0);\n        }\n\n        public static bool RequestUseGithub\n        {\n            get\n            {\n                string value = GetGeneralValue(\"RequestUseGithub\");\n                if(!string.IsNullOrEmpty(value)) return value == \"1\";\n                if(CultureInfo.CurrentCulture.Name == \"zh-CN\") return false;\n                return true;\n            }\n            set => SetGeneralValue(\"RequestUseGithub\", value ? 1 : 0);\n        }\n\n        public static int UpdateFrequency\n        {\n            get\n            {\n                string value = GetGeneralValue(\"UpdateFrequency\");\n                if(int.TryParse(value, out int day))\n                {\n                    if(day == -1 || day == 7 || day == 90) return day;\n                }\n                return 30;\n            }\n            set => SetGeneralValue(\"UpdateFrequency\", value);\n        }\n\n        public static bool TopMost\n        {\n            get => GetWindowValue(\"TopMost\") == \"1\";\n            set => SetWindowValue(\"TopMost\", value ? 1 : 0);\n        }\n\n        public static Size MainFormSize\n        {\n            get\n            {\n                string str = GetWindowValue(\"MainFormSize\");\n                int index = str.IndexOf(',');\n                if(index == -1) return Size.Empty;\n                if(int.TryParse(str.Substring(0, index), out int x))\n                    if(int.TryParse(str.Substring(index + 1), out int y))\n                        return new Size(x, y);\n                return Size.Empty;\n            }\n            set => SetWindowValue(\"MainFormSize\", value.Width + \",\" + value.Height);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/AppImage.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Properties;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Methods\n{\n    static class AppImage\n    {\n        private static readonly double Scale = HighDpi.DpiScale / 1.5;\n        ///<summary>主页</summary>\n        public static readonly Image Home = Resources.Home.ResizeImage(Scale);\n        ///<summary>文件类型</summary>\n        public static readonly Image Type = Resources.Type.ResizeImage(Scale);\n        ///<summary>五角星</summary>\n        public static readonly Image Star = Resources.Star.ResizeImage(Scale);\n        ///<summary>刷新</summary>\n        public static readonly Image Refresh = Resources.Refresh.ResizeImage(Scale);\n        ///<summary>关于问号</summary>\n        public static readonly Image About = Resources.About.ResizeImage(Scale);\n        ///<summary>设置按钮</summary>\n        public static readonly Image Setting = Resources.Setting.ResizeImage(Scale);\n        ///<summary>编辑子项</summary>\n        public static readonly Image SubItems = Resources.SubItems.ResizeImage(Scale);\n        ///<summary>删除</summary>\n        public static readonly Image Delete = Resources.Delete.ResizeImage(Scale);\n        ///<summary>添加</summary>\n        public static readonly Image AddNewItem = Resources.Add.ResizeImage(Scale);\n        ///<summary>添加已有项目</summary>\n        public static readonly Image AddExisting = Resources.AddExisting.ResizeImage(Scale);\n        ///<summary>添加分割线</summary>\n        public static readonly Image AddSeparator = Resources.AddSeparator.ResizeImage(Scale);\n        ///<summary>添加增强菜单</summary>\n        public static readonly Image Enhance = Resources.Enhance.ResizeImage(Scale);\n        ///<summary>打开</summary>\n        public static readonly Image Open = Resources.Open.ResizeImage(Scale);\n        ///<summary>下载</summary>\n        public static readonly Image DownLoad = Resources.DownLoad.ResizeImage(Scale);\n        ///<summary>翻译</summary>\n        public static readonly Image Translate = Resources.Translate.ResizeImage(Scale);\n        ///<summary>检查更新</summary>\n        public static readonly Image CheckUpdate = Resources.CheckUpdate.ResizeImage(Scale);\n        ///<summary>上</summary>\n        public static readonly Image Up = Resources.Up.ResizeImage(Scale);\n        ///<summary>下</summary>\n        public static readonly Image Down = Up.RotateImage(RotateFlipType.Rotate180FlipNone);\n        ///<summary>新建项目</summary>\n        public static readonly Image NewItem = Resources.NewItem.ResizeImage(Scale);\n        ///<summary>新建文件夹</summary>\n        public static readonly Image NewFolder = Resources.NewFolder.ResizeImage(Scale);\n        ///<summary>自定义</summary>\n        public static readonly Image Custom = Resources.Custom.ResizeImage(Scale);\n        ///<summary>选择</summary>\n        public static readonly Image Select = Resources.Select.ResizeImage(Scale);\n        ///<summary>跳转</summary>\n        public static readonly Image Jump = Resources.Jump.ResizeImage(Scale);\n        ///<summary>Microsoft Store</summary>\n        public static readonly Image MicrosoftStore = Resources.MicrosoftStore.ResizeImage(Scale);\n        ///<summary>用户</summary>\n        public static readonly Image User = Resources.User.ResizeImage(Scale);\n        ///<summary>网络</summary>\n        public static readonly Image Web = Resources.Web.ResizeImage(Scale);\n        ///<summary>系统文件</summary>\n        public static readonly Image SystemFile = GetIconImage(\"imageres.dll\", -67);\n        ///<summary>资源不存在</summary>\n        public static readonly Image NotFound = GetIconImage(\"imageres.dll\", -2);\n        ///<summary>管理员小盾牌</summary>\n        public static readonly Image Shield = GetIconImage(\"imageres.dll\", -78);\n        ///<summary>资源管理器</summary>\n        public static readonly Image Explorer = GetIconImage(\"explorer.exe\", 0);\n        ///<summary>重启Explorer</summary>\n        public static readonly Image RestartExplorer = GetIconImage(\"shell32.dll\", 238);\n        ///<summary>网络驱动器</summary>\n        public static readonly Image NetworkDrive = GetIconImage(\"imageres.dll\", -33);\n        ///<summary>发送到</summary>\n        public static readonly Image SendTo = GetIconImage(\"imageres.dll\", -185);\n        ///<summary>回收站</summary>\n        public static readonly Image RecycleBin = GetIconImage(\"imageres.dll\", -55);\n        ///<summary>磁盘</summary>\n        public static readonly Image Drive = GetIconImage(\"imageres.dll\", -30);\n        ///<summary>文件</summary>\n        public static readonly Image File = GetIconImage(\"imageres.dll\", -19);\n        ///<summary>文件夹</summary>\n        public static readonly Image Folder = GetIconImage(\"imageres.dll\", -3);\n        ///<summary>目录</summary>\n        public static readonly Image Directory = GetIconImage(\"imageres.dll\", -162);\n        ///<summary>所有对象</summary>\n        public static readonly Image AllObjects = GetIconImage(\"imageres.dll\", -117);\n        ///<summary>锁定</summary>\n        public static readonly Image Lock = GetIconImage(\"imageres.dll\", -59);\n        ///<summary>快捷方式图标</summary>\n        public static readonly Image LnkFile = GetIconImage(\"shell32.dll\", -16769);\n\n        private static Image GetIconImage(string dllName, int iconIndex)\n        {\n            using(Icon icon = ResourceIcon.GetIcon(dllName, iconIndex)) return icon?.ToBitmap();\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/AppMessageBox.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager.Methods\n{\n    public static class AppMessageBox\n    {\n        public static DialogResult Show(string text, MessageBoxButtons buttons = MessageBoxButtons.OK,\n            MessageBoxIcon icon = MessageBoxIcon.Warning, string caption = null)\n        {\n            return MessageBoxEx.Show(text, caption ?? AppString.General.AppName, buttons, icon);\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/AppString.cs",
    "content": "using BluePointLilac.Methods;\nusing System;\nusing System.Reflection;\nusing System.Text;\n\nnamespace ContextMenuManager.Methods\n{\n    static class AppString\n    {\n        private static readonly IniReader UserLangReader = new IniReader(AppConfig.LanguageIniPath);\n        public static readonly IniReader DefLangReader = new IniReader(new StringBuilder(Properties.Resources.AppLanguageDic));\n\n        private static string GetValue(string section, string key)\n        {\n            string value = UserLangReader.GetValue(section, key);\n            if(string.IsNullOrEmpty(value)) value = DefLangReader.GetValue(section, key);\n            return value.Replace(\"\\\\r\", \"\\r\").Replace(\"\\\\n\", \"\\n\");\n        }\n\n        /// <summary>加载语言</summary>\n        public static void LoadStrings()\n        {\n            foreach(Type type in typeof(AppString).GetNestedTypes())\n            {\n                foreach(PropertyInfo pi in type.GetProperties())\n                {\n                    pi.SetValue(type, GetValue(type.Name, pi.Name), null);\n                }\n            }\n        }\n\n        /// <summary>常规</summary>\n        public static class General\n        {\n            public static string AppName { get; set; }\n        }\n\n        /// <summary>工具栏</summary>\n        public static class ToolBar\n        {\n            public static string Home { get; set; }\n            public static string Type { get; set; }\n            public static string Rule { get; set; }\n            public static string Refresh { get; set; }\n            public static string About { get; set; }\n        }\n\n        /// <summary>侧边栏</summary>\n        public static class SideBar\n        {\n            public static string File { get; set; }\n            public static string Folder { get; set; }\n            public static string Directory { get; set; }\n            public static string Background { get; set; }\n            public static string Desktop { get; set; }\n            public static string Drive { get; set; }\n            public static string AllObjects { get; set; }\n            public static string Computer { get; set; }\n            public static string RecycleBin { get; set; }\n            public static string Library { get; set; }\n            public static string New { get; set; }\n            public static string SendTo { get; set; }\n            public static string OpenWith { get; set; }\n            public static string WinX { get; set; }\n            public static string LnkFile { get; set; }\n            public static string UwpLnk { get; set; }\n            public static string ExeFile { get; set; }\n            public static string UnknownType { get; set; }\n            public static string MenuAnalysis { get; set; }\n            public static string CustomExtension { get; set; }\n            public static string PerceivedType { get; set; }\n            public static string DirectoryType { get; set; }\n            public static string EnhanceMenu { get; set; }\n            public static string DetailedEdit { get; set; }\n            public static string GuidBlocked { get; set; }\n            public static string DragDrop { get; set; }\n            public static string PublicReferences { get; set; }\n            public static string CustomRegPath { get; set; }\n            public static string IEMenu { get; set; }\n            public static string AppSetting { get; set; }\n            public static string AboutApp { get; set; }\n            public static string Dictionaries { get; set; }\n            public static string AppLanguage { get; set; }\n            public static string Donate { get; set; }\n        }\n\n        /// <summary>状态栏</summary>\n        public static class StatusBar\n        {\n            public static string File { get; set; }\n            public static string Folder { get; set; }\n            public static string Directory { get; set; }\n            public static string Background { get; set; }\n            public static string Desktop { get; set; }\n            public static string Drive { get; set; }\n            public static string AllObjects { get; set; }\n            public static string Computer { get; set; }\n            public static string RecycleBin { get; set; }\n            public static string Library { get; set; }\n            public static string New { get; set; }\n            public static string SendTo { get; set; }\n            public static string OpenWith { get; set; }\n            public static string WinX { get; set; }\n            public static string LnkFile { get; set; }\n            public static string UwpLnk { get; set; }\n            public static string ExeFile { get; set; }\n            public static string UnknownType { get; set; }\n            public static string MenuAnalysis { get; set; }\n            public static string CustomExtension { get; set; }\n            public static string PerceivedType { get; set; }\n            public static string DirectoryType { get; set; }\n            public static string EnhanceMenu { get; set; }\n            public static string DetailedEdit { get; set; }\n            public static string GuidBlocked { get; set; }\n            public static string DragDrop { get; set; }\n            public static string PublicReferences { get; set; }\n            public static string CustomRegPath { get; set; }\n            public static string IEMenu { get; set; }\n        }\n\n        /// <summary>程序内右键菜单</summary>\n        public static class Menu\n        {\n            public static string ChangeText { get; set; }\n            public static string ItemIcon { get; set; }\n            public static string ChangeIcon { get; set; }\n            public static string AddIcon { get; set; }\n            public static string DeleteIcon { get; set; }\n            public static string ShieldIcon { get; set; }\n            public static string ItemPosition { get; set; }\n            public static string SetDefault { get; set; }\n            public static string SetTop { get; set; }\n            public static string SetBottom { get; set; }\n            public static string OtherAttributes { get; set; }\n            public static string OnlyWithShift { get; set; }\n            public static string OnlyInExplorer { get; set; }\n            public static string NoWorkingDirectory { get; set; }\n            public static string NeverDefault { get; set; }\n            public static string ShowAsDisabledIfHidden { get; set; }\n            public static string Details { get; set; }\n            public static string WebSearch { get; set; }\n            public static string ChangeCommand { get; set; }\n            public static string RunAsAdministrator { get; set; }\n            public static string FileProperties { get; set; }\n            public static string FileLocation { get; set; }\n            public static string RegistryLocation { get; set; }\n            public static string ExportRegistry { get; set; }\n            public static string Delete { get; set; }\n            public static string DeleteReference { get; set; }\n            public static string HandleGuid { get; set; }\n            public static string CopyGuid { get; set; }\n            public static string BlockGuid { get; set; }\n            public static string AddGuidDic { get; set; }\n            public static string ClsidLocation { get; set; }\n            public static string InitialData { get; set; }\n            public static string BeforeSeparator { get; set; }\n            public static string ChangeGroup { get; set; }\n            public static string RestoreDefault { get; set; }\n            public static string Edit { get; set; }\n            public static string Save { get; set; }\n            public static string FoldAll { get; set; }\n            public static string UnfoldAll { get; set; }\n        }\n\n        /// <summary>对话框子窗口</summary>\n        public static class Dialog\n        {\n            public static string Browse { get; set; }\n            public static string Program { get; set; }\n            public static string AllFiles { get; set; }\n            public static string RegistryFile { get; set; }\n            public static string ItemText { get; set; }\n            public static string ItemCommand { get; set; }\n            public static string CommandArguments { get; set; }\n            public static string SingleMenu { get; set; }\n            public static string MultiMenu { get; set; }\n            public static string Public { get; set; }\n            public static string Private { get; set; }\n            public static string SelectAll { get; set; }\n            public static string InputGuid { get; set; }\n            public static string AddGuidDic { get; set; }\n            public static string DeleteGuidDic { get; set; }\n            public static string NoPerceivedType { get; set; }\n            public static string TextFile { get; set; }\n            public static string DocumentFile { get; set; }\n            public static string ImageFile { get; set; }\n            public static string VideoFile { get; set; }\n            public static string AudioFile { get; set; }\n            public static string CompressedFile { get; set; }\n            public static string SystemFile { get; set; }\n            public static string DocumentDirectory { get; set; }\n            public static string ImageDirectory { get; set; }\n            public static string VideoDirectory { get; set; }\n            public static string AudioDirectory { get; set; }\n            public static string EditSubItems { get; set; }\n            public static string DetailedEdit { get; set; }\n            public static string CheckReference { get; set; }\n            public static string CheckCopy { get; set; }\n            public static string SelectExtension { get; set; }\n            public static string SelectPerceivedType { get; set; }\n            public static string SelectDirectoryType { get; set; }\n            public static string SelectNewItemType { get; set; }\n            public static string SelectGroup { get; set; }\n            public static string SelectObjectType { get; set; }\n            public static string SelectDropEffect { get; set; }\n            public static string DefaultDropEffect { get; set; }\n            public static string CopyDropEffect { get; set; }\n            public static string MoveDropEffect { get; set; }\n            public static string CreateLinkDropEffect { get; set; }\n            public static string DownloadLanguages { get; set; }\n            public static string TranslateTool { get; set; }\n            public static string DefaultText { get; set; }\n            public static string OldTranslation { get; set; }\n            public static string NewTranslation { get; set; }\n            public static string DonateInfo { get; set; }\n        }\n\n        /// <summary>消息</summary>\n        public static class Message\n        {\n            public static string TextCannotBeEmpty { get; set; }\n            public static string CommandCannotBeEmpty { get; set; }\n            public static string StringParsingFailed { get; set; }\n            public static string TextLengthCannotExceed80 { get; set; }\n            public static string ConfirmDeletePermanently { get; set; }\n            public static string DeleteButCanRestore { get; set; }\n            public static string ConfirmDeleteReference { get; set; }\n            public static string ConfirmDelete { get; set; }\n            public static string ConfirmDeleteReferenced { get; set; }\n            public static string CannotAddNewItem { get; set; }\n            public static string VistaUnsupportedMulti { get; set; }\n            public static string CannotHideSubItem { get; set; }\n            public static string UnsupportedFilename { get; set; }\n            public static string NoOpenModeExtension { get; set; }\n            public static string CannotChangePath { get; set; }\n            public static string CopiedToClipboard { get; set; }\n            public static string MalformedGuid { get; set; }\n            public static string HasBeenAdded { get; set; }\n            public static string EditInitialData { get; set; }\n            public static string PromptIsOpenItem { get; set; }\n            public static string SelectRegPath { get; set; }\n            public static string RestartApp { get; set; }\n            public static string UpdateInfo { get; set; }\n            public static string UpdateSucceeded { get; set; }\n            public static string DicUpdateSucceeded { get; set; }\n            public static string FileNotExists { get; set; }\n            public static string FolderNotExists { get; set; }\n            public static string VersionIsLatest { get; set; }\n            public static string AuthorityProtection { get; set; }\n            public static string WinXSorted { get; set; }\n            public static string RestoreDefault { get; set; }\n            public static string DeleteGroup { get; set; }\n            public static string WebDataReadFailed { get; set; }\n            public static string OpenWebUrl { get; set; }\n            public static string SelectSubMenuMode { get; set; }\n        }\n\n        /// <summary>提示文本</summary>\n        public static class Tip\n        {\n            public static string RestartExplorer { get; set; }\n            public static string CustomFolder { get; set; }\n            public static string SendToDrive { get; set; }\n            public static string BuildSendtoMenu { get; set; }\n            public static string EditSubItems { get; set; }\n            public static string InvalidItem { get; set; }\n            public static string AddSeparator { get; set; }\n            public static string AddReference { get; set; }\n            public static string AddFromPublic { get; set; }\n            public static string AddFromParentMenu { get; set; }\n            public static string DeleteGuidDic { get; set; }\n            public static string LockNewMenu { get; set; }\n            public static string ConfigPath { get; set; }\n            public static string CommandFiles { get; set; }\n            public static string CreateGroup { get; set; }\n            public static string DropOrSelectObject { get; set; }\n            public static string ImmediatelyCheck { get; set; }\n        }\n\n        /// <summary>其他文本</summary>\n        public static class Other\n        {\n            public static string CustomFolder { get; set; }\n            public static string BuildSendtoMenu { get; set; }\n            public static string NewItem { get; set; }\n            public static string AddGuidBlockedItem { get; set; }\n            public static string CurrentExtension { get; set; }\n            public static string CurrentPerceivedType { get; set; }\n            public static string CurrentDirectoryType { get; set; }\n            public static string CurrentFilePath { get; set; }\n            public static string CurrentRegPath { get; set; }\n            public static string SelectRegPath { get; set; }\n            public static string InvalidItem { get; set; }\n            public static string Separator { get; set; }\n            public static string LockNewMenu { get; set; }\n            public static string RestartExplorer { get; set; }\n            public static string WebDictionaries { get; set; }\n            public static string SwitchDictionaries { get; set; }\n            public static string UserDictionaries { get; set; }\n            public static string DictionaryDescription { get; set; }\n            public static string GuidInfosDictionary { get; set; }\n            public static string UwpMode { get; set; }\n            public static string Translators { get; set; }\n            public static string AboutApp { get; set; }\n            public static string Dictionaries { get; set; }\n            public static string Donate { get; set; }\n            public static string DonationList { get; set; }\n            public static string ConfigPath { get; set; }\n            public static string AppDataDir { get; set; }\n            public static string AppDir { get; set; }\n            public static string AutoBackup { get; set; }\n            public static string SetUpdateFrequency { get; set; }\n            public static string OnceAWeek { get; set; }\n            public static string OnceAMonth { get; set; }\n            public static string OnceASeason { get; set; }\n            public static string NeverCheck { get; set; }\n            public static string SetRequestRepo { get; set; }\n            public static string ProtectOpenItem { get; set; }\n            public static string WebSearchEngine { get; set; }\n            public static string CustomEngine { get; set; }\n            public static string SetCustomEngine { get; set; }\n            public static string WinXSortable { get; set; }\n            public static string ShowFilePath { get; set; }\n            public static string OpenMoreRegedit { get; set; }\n            public static string OpenMoreExplorer { get; set; }\n            public static string HideDisabledItems { get; set; }\n            public static string HideSysStoreItems { get; set; }\n            public static string SetPerceivedType { get; set; }\n            public static string SetDefaultDropEffect { get; set; }\n            public static string TopMost { get; set; }\n        }\n    }\n}\n"
  },
  {
    "path": "ContextMenuManager/Methods/DesktopIni.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing System.IO;\n\nnamespace ContextMenuManager.Methods\n{\n    static class DesktopIni\n    {\n        private const string LocalizedFileNames = \"LocalizedFileNames\";\n\n        public static string GetDesktopIniPath(string filePath) => $@\"{Path.GetDirectoryName(filePath)}\\desktop.ini\";\n\n        public static void DeleteLocalizedFileNames(string filePath)\n        {\n            IniWriter writer = new IniWriter(GetDesktopIniPath(filePath));\n            string fileName = Path.GetFileName(filePath);\n            writer.DeleteKey(LocalizedFileNames, fileName);\n        }\n\n        public static void SetLocalizedFileNames(string filePath, string name)\n        {\n            IniWriter writer = new IniWriter(GetDesktopIniPath(filePath));\n            string fileName = Path.GetFileName(filePath);\n            writer.SetValue(LocalizedFileNames, fileName, name);\n        }\n\n        public static string GetLocalizedFileNames(string filePath, bool translate = false)\n        {\n            IniWriter writer = new IniWriter(GetDesktopIniPath(filePath));\n            string fileName = Path.GetFileName(filePath);\n            string name = writer.GetValue(LocalizedFileNames, fileName);\n            if(translate) name = ResourceString.GetDirectString(name);\n            return name;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/GuidInfo.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\n\nnamespace ContextMenuManager.Methods\n{\n    static class GuidInfo\n    {\n        public static readonly string[] ClsidPaths =\n        {\n            @\"HKEY_CLASSES_ROOT\\CLSID\",\n            @\"HKEY_CLASSES_ROOT\\WOW6432Node\\CLSID\",\n            @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Classes\\CLSID\",\n        };\n\n        public struct IconLocation\n        {\n            public string IconPath { get; set; }\n            public int IconIndex { get; set; }\n            public string Tostring() => $\"{IconPath},{IconIndex}\";\n        }\n\n        private static readonly IniWriter UserDic = new IniWriter(AppConfig.UserGuidInfosDic);\n        private static readonly IniReader WebDic = new IniReader(AppConfig.WebGuidInfosDic);\n        private static readonly IniReader AppDic = new IniReader(new StringBuilder(Properties.Resources.GuidInfosDic));\n        private static readonly Dictionary<Guid, IconLocation> IconLocationDic = new Dictionary<Guid, IconLocation>();\n        private static readonly Dictionary<Guid, string> ItemTextDic = new Dictionary<Guid, string>();\n        private static readonly Dictionary<Guid, Image> ItemImageDic = new Dictionary<Guid, Image>();\n        private static readonly Dictionary<Guid, string> FilePathDic = new Dictionary<Guid, string>();\n        private static readonly Dictionary<Guid, string> ClsidPathDic = new Dictionary<Guid, string>();\n        private static readonly Dictionary<Guid, string> UwpNameDic = new Dictionary<Guid, string>();\n\n        /// <summary>重新加载字典</summary>\n        public static void ReloadDics()\n        {\n            WebDic.LoadFile(AppConfig.WebGuidInfosDic);\n            IconLocationDic.Clear();\n            ItemTextDic.Clear();\n            ItemImageDic.Clear();\n            FilePathDic.Clear();\n            ClsidPathDic.Clear();\n            UwpNameDic.Clear();\n        }\n\n        public static void RemoveDic(Guid guid)\n        {\n            IconLocationDic.Remove(guid);\n            ItemTextDic.Remove(guid);\n            ItemImageDic.Remove(guid);\n            FilePathDic.Remove(guid);\n            ClsidPathDic.Remove(guid);\n            UwpNameDic.Remove(guid);\n        }\n\n        private static bool TryGetValue(Guid guid, string key, out string value)\n        {\n            //用户自定义字典优先\n            string section = guid.ToString();\n            value = UserDic.GetValue(section, key);\n            if(value != string.Empty) return true;\n            if(WebDic.TryGetValue(section, key, out value)) return true;\n            if(AppDic.TryGetValue(section, key, out value)) return true;\n            return false;\n        }\n\n        public static string GetFilePath(Guid guid)\n        {\n            string filePath = null;\n            if(guid.Equals(Guid.Empty)) return filePath;\n            if(FilePathDic.ContainsKey(guid)) filePath = FilePathDic[guid];\n            else\n            {\n                string uwpName = GetUwpName(guid);\n                if(!string.IsNullOrEmpty(uwpName))\n                {\n                    filePath = UwpHelper.GetFilePath(uwpName, guid);\n                }\n                else\n                {\n                    foreach(string clsidPath in ClsidPaths)\n                    {\n                        using(RegistryKey guidKey = RegistryEx.GetRegistryKey($@\"{clsidPath}\\{guid:B}\"))\n                        {\n                            if(guidKey == null) continue;\n                            foreach(string keyName in new[] { \"InprocServer32\", \"LocalServer32\" })\n                            {\n                                using(RegistryKey key = guidKey.OpenSubKey(keyName))\n                                {\n                                    if(key == null) continue;\n                                    string value1 = key.GetValue(\"CodeBase\")?.ToString().Replace(\"file:///\", \"\").Replace('/', '\\\\');\n                                    if(File.Exists(value1))\n                                    {\n                                        filePath = value1; break;\n                                    }\n                                    string value2 = key.GetValue(\"\")?.ToString();\n                                    value2 = ObjectPath.ExtractFilePath(value2);\n                                    if(File.Exists(value2))\n                                    {\n                                        filePath = value2; break;\n                                    }\n                                }\n                            }\n                            if(File.Exists(filePath))\n                            {\n                                if(ClsidPathDic.ContainsKey(guid)) ClsidPathDic[guid] = guidKey.Name;\n                                else ClsidPathDic.Add(guid, guidKey.Name);\n                                break;\n                            }\n                        }\n                    }\n                }\n                FilePathDic.Add(guid, filePath);\n            }\n            return filePath;\n        }\n\n        public static string GetClsidPath(Guid guid)\n        {\n            if(ClsidPathDic.ContainsKey(guid)) return ClsidPathDic[guid];\n            foreach(string path in ClsidPaths)\n            {\n                using(RegistryKey key = RegistryEx.GetRegistryKey($@\"{path}\\{guid:B}\"))\n                {\n                    if(key != null) return key.Name;\n                }\n            }\n            return null;\n        }\n\n        public static string GetText(Guid guid)\n        {\n            string itemText = null;\n            if(guid.Equals(Guid.Empty)) return itemText;\n            if(ItemTextDic.ContainsKey(guid)) itemText = ItemTextDic[guid];\n            else\n            {\n                if(TryGetValue(guid, \"ResText\", out itemText))\n                {\n                    itemText = GetAbsStr(guid, itemText, true);\n                    itemText = ResourceString.GetDirectString(itemText);\n                }\n                if(itemText.IsNullOrWhiteSpace())\n                {\n                    string uiText = CultureInfo.CurrentUICulture.Name + \"-Text\";\n                    TryGetValue(guid, uiText, out itemText);\n                    if(itemText.IsNullOrWhiteSpace())\n                    {\n                        TryGetValue(guid, \"Text\", out itemText);\n                        itemText = ResourceString.GetDirectString(itemText);\n                    }\n                }\n                if(itemText.IsNullOrWhiteSpace())\n                {\n                    foreach(string clsidPath in ClsidPaths)\n                    {\n                        foreach(string value in new[] { \"LocalizedString\", \"InfoTip\", \"\" })\n                        {\n                            itemText = Registry.GetValue($@\"{clsidPath}\\{guid:B}\", value, null)?.ToString();\n                            itemText = ResourceString.GetDirectString(itemText);\n                            if(!itemText.IsNullOrWhiteSpace()) break;\n                        }\n                        if(!itemText.IsNullOrWhiteSpace()) break;\n                    }\n                }\n                if(itemText.IsNullOrWhiteSpace())\n                {\n                    string filePath = GetFilePath(guid);\n                    if(File.Exists(filePath))\n                    {\n                        itemText = FileVersionInfo.GetVersionInfo(filePath).FileDescription;\n                        if(itemText.IsNullOrWhiteSpace())\n                        {\n                            itemText = Path.GetFileName(filePath);\n                        }\n                    }\n                    else itemText = null;\n                }\n                ItemTextDic.Add(guid, itemText);\n            }\n            return itemText;\n        }\n\n        public static Image GetImage(Guid guid)\n        {\n            if(ItemImageDic.TryGetValue(guid, out Image image)) return image;\n            IconLocation location = GetIconLocation(guid);\n            string iconPath = location.IconPath;\n            int iconIndex = location.IconIndex;\n            if(iconPath == null && iconIndex == 0) image = AppImage.SystemFile;\n            else if(Path.GetFileName(iconPath).ToLower() == \"shell32.dll\" && iconIndex == 0) image = AppImage.SystemFile;\n            else image = ResourceIcon.GetIcon(iconPath, iconIndex)?.ToBitmap() ?? AppImage.SystemFile;\n            ItemImageDic.Add(guid, image);\n            return image;\n        }\n\n        public static IconLocation GetIconLocation(Guid guid)\n        {\n            IconLocation location = new IconLocation();\n            if(guid.Equals(Guid.Empty)) return location;\n            if(IconLocationDic.ContainsKey(guid)) location = IconLocationDic[guid];\n            else\n            {\n                if(TryGetValue(guid, \"Icon\", out string value))\n                {\n                    value = GetAbsStr(guid, value, false);\n                    int index = value.LastIndexOf(',');\n                    if(int.TryParse(value.Substring(index + 1), out int iconIndex))\n                    {\n                        location.IconPath = value.Substring(0, index);\n                        location.IconIndex = iconIndex;\n                    }\n                    else location.IconPath = value;\n                }\n                else location.IconPath = GetFilePath(guid);\n                IconLocationDic.Add(guid, location);\n            }\n            return location;\n        }\n\n        public static string GetUwpName(Guid guid)\n        {\n            string uwpName = null;\n            if(guid.Equals(Guid.Empty)) return uwpName;\n            if(UwpNameDic.ContainsKey(guid)) uwpName = UwpNameDic[guid];\n            else\n            {\n                TryGetValue(guid, \"UwpName\", out uwpName);\n                UwpNameDic.Add(guid, uwpName);\n            }\n            return uwpName;\n        }\n\n        private static string GetAbsStr(Guid guid, string relStr, bool isName)\n        {\n            string absStr = relStr;\n            if(isName)\n            {\n                if(!absStr.StartsWith(\"@\")) return absStr;\n                else absStr = absStr.Substring(1);\n                if(absStr.StartsWith(\"{*?ms-resource://\") && absStr.EndsWith(\"}\"))\n                {\n                    absStr = \"@{\" + UwpHelper.GetPackageName(GetUwpName(guid)) + absStr.Substring(2);\n                    return absStr;\n                }\n            }\n\n            string filePath = GetFilePath(guid);\n            if(filePath == null) return relStr;\n            string dirPath = Path.GetDirectoryName(filePath);\n            if(absStr.StartsWith(\"*\"))\n            {\n                absStr = filePath + absStr.Substring(1);\n            }\n            else if(absStr.StartsWith(\".\\\\\"))\n            {\n                absStr = dirPath + absStr.Substring(1);\n            }\n            else if(absStr.StartsWith(\"..\\\\\"))\n            {\n                do\n                {\n                    dirPath = Path.GetDirectoryName(dirPath);\n                    absStr = absStr.Substring(3);\n                } while(absStr.StartsWith(\"..\\\\\"));\n                absStr = dirPath + \"\\\\\" + absStr;\n            }\n            if(isName) absStr = \"@\" + absStr;\n            return absStr;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/ObjectPath.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.IO;\nusing System.Linq;\n\nnamespace ContextMenuManager.Methods\n{\n    static class ObjectPath\n    {\n        /// <summary>路径类型</summary>\n        public enum PathType { File, Directory, Registry }\n        private const string RegAppPath = @\"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\";\n        private const string ShellExecuteCommand = \"mshta vbscript:createobject(\\\"shell.application\\\").shellexecute(\\\"\";\n\n        private static readonly char[] IllegalChars = { '/', '*', '?', '\\\"', '<', '>', '|' };\n        private static readonly List<string> IgnoreCommandParts = new List<string> { \"\", \"%1\", \"%v\" };\n\n        /// <summary>根据文件名获取完整的文件路径</summary>\n        /// <remarks>fileName为Win+R、注册表等可直接使用的文件名</remarks>\n        /// <param name=\"fileName\">文件名</param>\n        /// <returns>成功提取返回true, fullPath为现有文件路径; 否则返回false, fullPath为null</returns>\n        public static bool GetFullFilePath(string fileName, out string fullPath)\n        {\n            fullPath = null;\n            if(fileName.IsNullOrWhiteSpace()) return false;\n\n            foreach(string name in new[] { fileName, $\"{fileName}.exe\" })\n            {\n                //右键菜单仅支持%SystemRoot%\\System32和%SystemRoot%两个环境变量，不考虑其他系统环境变量和用户环境变量，和Win+R命令有区别\n                foreach(string dir in new[] { \"\", @\"%SystemRoot%\\System32\\\", @\"%SystemRoot%\\\" })\n                {\n                    if(dir != \"\" && (name.Contains('\\\\') || name.Contains(':'))) return false;\n                    fullPath = Environment.ExpandEnvironmentVariables($@\"{dir}{name}\");\n                    if(File.Exists(fullPath)) return true;\n                }\n\n                fullPath = Registry.GetValue($@\"{RegAppPath}\\{name}\", \"\", null)?.ToString();\n                if(File.Exists(fullPath)) return true;\n            }\n            fullPath = null;\n            return false;\n        }\n\n\n        public static readonly Dictionary<string, string> FilePathDic = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);\n        /// <summary>从包含现有文件路径的命令语句中提取文件路径</summary>\n        /// <param name=\"command\">命令语句</param>\n        /// <returns>成功提取返回现有文件路径，否则返回值为null</returns>\n        public static string ExtractFilePath(string command)\n        {\n            if(command.IsNullOrWhiteSpace()) return null;\n            if(FilePathDic.ContainsKey(command)) return FilePathDic[command];\n            else\n            {\n                string filePath = null;\n                string partCmd = Environment.ExpandEnvironmentVariables(command).Replace(@\"\\\\\", @\"\\\");\n                if(partCmd.StartsWith(ShellExecuteCommand, StringComparison.OrdinalIgnoreCase))\n                {\n                    partCmd = partCmd.Substring(ShellExecuteCommand.Length);\n                    string[] arr = partCmd.Split(new[] { \"\\\",\\\"\" }, StringSplitOptions.None);\n                    if(arr.Length > 0)\n                    {\n                        string fileName = arr[0];\n                        if(GetFullFilePath(fileName, out filePath))\n                        {\n                            FilePathDic.Add(command, filePath);\n                            return filePath;\n                        }\n                        if(arr.Length > 1)\n                        {\n                            string arguments = arr[1];\n                            filePath = ExtractFilePath(arguments);\n                            if(filePath != null) return filePath;\n                        }\n                    }\n                }\n\n                string[] strs = Array.FindAll(partCmd.Split(IllegalChars), str\n                    => IgnoreCommandParts.Any(part => !part.Equals(str.Trim()))).Reverse().ToArray();\n\n                foreach(string str1 in strs)\n                {\n                    string str2 = str1;\n                    int index = -1;\n                    do\n                    {\n                        List<string> paths = new List<string>();\n                        string path1 = str2.Substring(index + 1);\n                        paths.Add(path1);\n                        if(index > 0)\n                        {\n                            string path2 = str2.Substring(0, index);\n                            paths.Add(path2);\n                        }\n                        int count = paths.Count;\n                        for(int i = 0; i < count; i++)\n                        {\n                            foreach(char c in new[] { ',', '-' })\n                            {\n                                if(paths[i].Contains(c)) paths.AddRange(paths[i].Split(c));\n                            }\n                        }\n                        foreach(string path in paths)\n                        {\n                            if(GetFullFilePath(path, out filePath))\n                            {\n                                FilePathDic.Add(command, filePath);\n                                return filePath;\n                            }\n                        }\n                        str2 = path1;\n                        index = str2.IndexOf(' ');\n                    }\n                    while(index != -1);\n                }\n                FilePathDic.Add(command, null);\n                return null;\n            }\n        }\n\n        /// <summary>移除文件或文件夹名称中的非法字符</summary>\n        /// <param name=\"fileName\">文件或文件夹名称</param>\n        /// <returns>返回移除非法字符后的文件或文件夹名称</returns>\n        public static string RemoveIllegalChars(string fileName)\n        {\n            Array.ForEach(IllegalChars, c => fileName = fileName.Replace(c.ToString(), \"\"));\n            return fileName.Replace(\"\\\\\", \"\").Replace(\":\", \"\");\n        }\n\n        /// <summary>判断文件或文件夹或注册表项是否存在</summary>\n        /// <param name=\"path\">文件或文件夹或注册表项路径</param>\n        /// <param name=\"type\">路径类型</param>\n        /// <returns>目标路径存在返回true，否则返回false</returns>\n        public static bool ObjectPathExist(string path, PathType type)\n        {\n            switch(type)\n            {\n                case PathType.File:\n                    return File.Exists(path);\n                case PathType.Directory:\n                    return Directory.Exists(path);\n                case PathType.Registry:\n                    return RegistryEx.GetRegistryKey(path) != null;\n                default:\n                    return false;\n            }\n        }\n\n        /// <summary>获取带序号的新路径</summary>\n        /// <param name=\"oldPath\">目标路径</param>\n        /// <param name=\"type\">路径类型</param>\n        /// <returns>如果目标路径不存在则返回目标路径，否则返回带序号的新路径</returns>\n        public static string GetNewPathWithIndex(string oldPath, PathType type, int startIndex = -1)\n        {\n            string newPath;\n            string dirPath = type == PathType.Registry ? RegistryEx.GetParentPath(oldPath) : Path.GetDirectoryName(oldPath);\n            string name = type == PathType.Registry ? RegistryEx.GetKeyName(oldPath) : Path.GetFileNameWithoutExtension(oldPath);\n            string extension = type == PathType.Registry ? \"\" : Path.GetExtension(oldPath);\n\n            do\n            {\n                newPath = $@\"{dirPath}\\{name}\";\n                if(startIndex > -1) newPath += startIndex;\n                newPath += extension;\n                startIndex++;\n            } while(ObjectPathExist(newPath, type));\n            return newPath;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/Updater.cs",
    "content": "﻿using BluePointLilac.Controls;\nusing BluePointLilac.Methods;\nusing System;\nusing System.IO;\nusing System.Windows.Forms;\nusing System.Xml;\n\nnamespace ContextMenuManager.Methods\n{\n    sealed class Updater\n    {\n        /// <summary>定期检查更新</summary>\n        public static void PeriodicUpdate()\n        {\n            int day = AppConfig.UpdateFrequency;\n            if(day == -1) return;//自动检测更新频率为-1则从不自动检查更新\n            //如果上次检测更新时间加上时间间隔早于或等于今天以前就进行更新操作\n            DateTime time = AppConfig.LastCheckUpdateTime.AddDays(day);\n            //time = DateTime.Today;//测试用\n            if(time <= DateTime.Today) new Action<bool>(Update).BeginInvoke(false, null, null);\n        }\n\n        /// <summary>更新程序以及程序字典</summary>\n        /// <param name=\"isManual\">是否为手动点击更新</param>\n        public static void Update(bool isManual)\n        {\n            AppConfig.LastCheckUpdateTime = DateTime.Today;\n            UpdateText(isManual);\n            UpdateApp(isManual);\n        }\n\n        /// <summary>更新程序</summary>\n        /// <param name=\"isManual\">是否为手动点击更新</param>\n        private static void UpdateApp(bool isManual)\n        {\n            using(UAWebClient client = new UAWebClient())\n            {\n                string url = AppConfig.RequestUseGithub ? AppConfig.GithubLatestApi : AppConfig.GiteeLatestApi;\n                XmlDocument doc = client.GetWebJsonToXml(url);\n                if(doc == null)\n                {\n                    if(isManual)\n                    {\n                        if(AppMessageBox.Show(AppString.Message.WebDataReadFailed + \"\\r\\n\"\n                            + AppString.Message.OpenWebUrl, MessageBoxButtons.OKCancel) != DialogResult.OK) return;\n                        url = AppConfig.RequestUseGithub ? AppConfig.GithubLatest : AppConfig.GiteeReleases;\n                        ExternalProgram.OpenWebUrl(url);\n                    }\n                    return;\n                }\n                XmlNode root = doc.FirstChild;\n                XmlNode tagNameXN = root.SelectSingleNode(\"tag_name\");\n                Version webVer = new Version(tagNameXN.InnerText);\n                Version appVer = new Version(Application.ProductVersion);\n#if DEBUG\n            appVer = new Version(0, 0, 0, 0);//测试用\n#endif\n                if(appVer >= webVer)\n                {\n                    if(isManual) AppMessageBox.Show(AppString.Message.VersionIsLatest,\n                        MessageBoxButtons.OK, MessageBoxIcon.Information);\n                }\n                else\n                {\n                    XmlNode bodyXN = root.SelectSingleNode(\"body\");\n                    string info = AppString.Message.UpdateInfo.Replace(\"%v1\", appVer.ToString()).Replace(\"%v2\", webVer.ToString());\n                    info += \"\\r\\n\\r\\n\" + MachinedInfo(bodyXN.InnerText);\n                    if(MessageBox.Show(info, AppString.General.AppName, \n                        MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)\n                    {\n                        string netVer = Environment.Version > new Version(4, 0) ? \"4.0\" : \"3.5\";\n                        XmlNode assetsXN = root.SelectSingleNode(\"assets\");\n                        foreach(XmlNode itemXN in assetsXN.SelectNodes(\"item\"))\n                        {\n                            XmlNode nameXN = itemXN.SelectSingleNode(\"name\");\n                            if(nameXN != null && nameXN.InnerText.Contains(netVer))\n                            {\n                                XmlNode urlXN = itemXN.SelectSingleNode(\"browser_download_url\");\n                                using(DownloadDialog dlg = new DownloadDialog())\n                                {\n                                    dlg.Url = urlXN?.InnerText;\n                                    dlg.FilePath = $@\"{AppConfig.AppDataDir}\\{webVer}.exe\";\n                                    dlg.Text = AppString.General.AppName;\n                                    if(dlg.ShowDialog() == DialogResult.OK)\n                                    {\n                                        AppMessageBox.Show(AppString.Message.UpdateSucceeded,\n                                            MessageBoxButtons.OK, MessageBoxIcon.Information);\n                                        SingleInstance.Restart(null, dlg.FilePath);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        /// <summary>更新程序字典</summary>\n        /// <param name=\"isManual\">是否为手动点击更新</param>\n        private static void UpdateText(bool isManual)\n        {\n            string dirUrl;\n            string[] filePaths;\n            void WriteFiles(string dirName, out string succeeded, out string failed)\n            {\n                succeeded = failed = \"\";\n                foreach(string filePath in filePaths)\n                {\n                    using(UAWebClient client = new UAWebClient())\n                    {\n                        string fileUrl = $\"{dirUrl}/{Path.GetFileName(filePath)}\";\n                        var func = new Func<string, string, bool>(client.WebStringToFile);\n                        bool flag = func.EndInvoke(func.BeginInvoke(filePath, fileUrl, null, null));\n                        string item = \"\\r\\n ● \" + Path.GetFileName(filePath);\n                        if(flag) succeeded += item;\n                        else failed += item;\n                    }\n                }\n                dirName = \"\\r\\n\\r\\n\" + dirName + \":\";\n                if(succeeded != \"\") succeeded = dirName + succeeded;\n                if(failed != \"\") failed = dirName + failed;\n            }\n\n            dirUrl = AppConfig.RequestUseGithub ? AppConfig.GithubTexts : AppConfig.GiteeTexts;\n            filePaths = new[]\n            {\n                AppConfig.WebGuidInfosDic, AppConfig.WebEnhanceMenusDic,\n                AppConfig.WebDetailedEditDic, AppConfig.WebUwpModeItemsDic\n            };\n            WriteFiles(\"Dictionaries\", out string succeeded1, out string failed1);\n\n            dirUrl = AppConfig.RequestUseGithub ? AppConfig.GithubLangsRawDir : AppConfig.GiteeLangsRawDir;\n            filePaths = Directory.GetFiles(AppConfig.LangsDir, \"*.ini\");\n            WriteFiles(\"Languages\", out string succeeded2, out string failed2);\n\n            if(isManual)\n            {\n                string failed = failed1 + failed2;\n                string succeeded = succeeded1 + succeeded2;\n                if(failed != \"\") AppMessageBox.Show(AppString.Message.WebDataReadFailed + failed);\n                if(succeeded != \"\") AppMessageBox.Show(AppString.Message.DicUpdateSucceeded + succeeded,\n                    MessageBoxButtons.OK, MessageBoxIcon.Information);\n            }\n        }\n\n        /// <summary>加工处理更新信息，去掉标题头</summary>\n        private static string MachinedInfo(string info)\n        {\n            string str = string.Empty;\n            string[] lines = info.Split(new[] { \"\\r\\n\", \"\\n\" }, StringSplitOptions.None);\n            for(int m = 0; m < lines.Length; m++)\n            {\n                string line = lines[m];\n                for(int n = 1; n <= 6; n++)\n                {\n                    if(line.StartsWith(new string('#', n) + ' '))\n                    {\n                        line = line.Substring(n + 1);\n                        break;\n                    }\n                }\n                str += line + \"\\r\\n\";\n            }\n            return str;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/UwpHelper.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.IO;\n\nnamespace ContextMenuManager.Methods\n{\n    static class UwpHelper\n    {\n        private const string PackageRegPath = @\"HKEY_CLASSES_ROOT\\PackagedCom\\Package\";\n        private const string PackagesRegPath = @\"HKEY_CLASSES_ROOT\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\AppModel\\PackageRepository\\Packages\";\n\n        public static string GetPackageName(string uwpName)\n        {\n            if(string.IsNullOrEmpty(uwpName)) return null;\n            using(RegistryKey packageKey = RegistryEx.GetRegistryKey(PackageRegPath))\n            {\n                if(packageKey == null) return null;\n                foreach(string packageName in packageKey.GetSubKeyNames())\n                {\n                    if(packageName.StartsWith(uwpName, StringComparison.OrdinalIgnoreCase))\n                    {\n                        return packageName;\n                    }\n                }\n            }\n            return null;\n        }\n\n        public static string GetRegPath(string uwpName, Guid guid)\n        {\n            string packageName = GetPackageName(uwpName);\n            if(packageName == null) return null;\n            else return $@\"{PackageRegPath}\\{packageName}\\Class\\{guid:B}\";\n        }\n\n        public static string GetFilePath(string uwpName, Guid guid)\n        {\n            string regPath = GetRegPath(uwpName, guid);\n            if(regPath == null) return null;\n            string packageName = GetPackageName(uwpName);\n            using(RegistryKey pKey = RegistryEx.GetRegistryKey($@\"{PackagesRegPath}\\{packageName}\"))\n            {\n                if(pKey == null) return null;\n                string dirPath = pKey.GetValue(\"Path\")?.ToString();\n                string dllPath = Registry.GetValue(regPath, \"DllPath\", null)?.ToString();\n                string filePath = $@\"{dirPath}\\{dllPath}\";\n                if(File.Exists(filePath)) return filePath;\n                string[] names = pKey.GetSubKeyNames();\n                if(names.Length == 1)\n                {\n                    filePath = \"shell:AppsFolder\\\\\" + names[0];\n                    return filePath;\n                }\n                if(Directory.Exists(dirPath)) return dirPath;\n                return null;\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/WinXHasher.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing System.Runtime.InteropServices.ComTypes;\nusing System.Security;\nusing System.Text;\nusing ComTypes = System.Runtime.InteropServices.ComTypes;\n\nnamespace ContextMenuManager.Methods\n{\n    /// 代码用途：添加WinX菜单项目\n    /// 参考代码1：https://github.com/riverar/hashlnk/blob/master/hashlnk.cpp (Rafael Rivera)\n    /// 参考代码2：https://github.com/xmoer/HashLnk/blob/main/HashLnk.cs (坑晨)\n    static class WinXHasher\n    {\n        [DllImport(\"shlwapi.dll\", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]\n        private static extern int HashData(\n            [In][MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 1)] byte[] pbData, int cbData,\n            [Out][MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U1, SizeParamIndex = 3)] byte[] pbHash, int cbHash);\n\n        [DllImport(\"shell32.dll\", CharSet = CharSet.Unicode, PreserveSig = false)]\n        private static extern uint SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath,\n        IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv);\n\n        [DllImport(\"propsys.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n        private static extern int PSGetPropertyKeyFromName([In][MarshalAs(UnmanagedType.LPWStr)] string pszCanonicalName, out PropertyKey propkey);\n\n        [ComImport]\n        [Guid(\"886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99\")]\n        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n        interface IPropertyStore\n        {\n            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]\n            void GetCount([Out] out uint cProps);\n\n            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]\n            void GetAt([In] uint iProp, out PropertyKey pkey);\n\n            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]\n            void GetValue([In] ref PropertyKey key, out PropVariant pv);\n\n            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]\n            void SetValue([In] ref PropertyKey key, [In] ref PropVariant pv);\n\n            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]\n            void Commit();\n        }\n\n        [ComImport]\n        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n        [Guid(\"43826d1e-e718-42ee-bc55-a1e261c37bfe\")]\n        interface IShellItem\n        {\n            void BindToHandler(IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppv);\n            void GetParent(out IShellItem ppsi);\n            void GetDisplayName(uint sigdnName, out IntPtr ppszName);\n            void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);\n            void Compare(IShellItem psi, uint hint, out int piOrder);\n        }\n\n        [ComImport]\n        [SuppressUnmanagedCodeSecurity]\n        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]\n        [Guid(\"7e9fb0d3-919f-4307-ab2e-9b1860310c93\")]\n        interface IShellItem2 : IShellItem\n        {\n            [return: MarshalAs(UnmanagedType.Interface)]\n            object BindToHandler(IBindCtx pbc, [In] ref Guid bhid, [In] ref Guid riid);\n\n            IShellItem GetParent();\n\n            [return: MarshalAs(UnmanagedType.LPWStr)]\n            string GetDisplayName(uint sigdnName);\n\n            uint GetAttributes(uint sfgaoMask);\n\n            int Compare(IShellItem psi, uint hint);\n\n            [return: MarshalAs(UnmanagedType.Interface)]\n            IPropertyStore GetPropertyStore(GPS flags, [In] ref Guid riid);\n\n            [return: MarshalAs(UnmanagedType.Interface)]\n            object GetPropertyStoreWithCreateObject(GPS flags, [MarshalAs(UnmanagedType.IUnknown)] object punkCreateObject, [In] ref Guid riid);\n\n            [return: MarshalAs(UnmanagedType.Interface)]\n            object GetPropertyStoreForKeys(IntPtr rgKeys, uint cKeys, GPS flags, [In] ref Guid riid);\n\n            [return: MarshalAs(UnmanagedType.Interface)]\n            object GetPropertyDescriptionList(IntPtr keyType, [In] ref Guid riid);\n\n            void Update(IBindCtx pbc);\n\n            [SecurityCritical]\n            void GetProperty(IntPtr key, [In][Out] PropVariant pv);\n\n            Guid GetCLSID(IntPtr key);\n\n            ComTypes.FILETIME GetFileTime(IntPtr key);\n\n            int GetInt32(IntPtr key);\n\n            [return: MarshalAs(UnmanagedType.LPWStr)]\n            string GetString(PropertyKey key);\n\n            uint GetUInt32(IntPtr key);\n\n            ulong GetUInt64(IntPtr key);\n\n            [return: MarshalAs(UnmanagedType.Bool)]\n            bool GetBool(IntPtr key);\n        }\n\n        [StructLayout(LayoutKind.Sequential, Pack = 4)]\n        struct PropertyKey\n        {\n            public Guid GUID;\n            public int PID;\n        }\n\n        [StructLayout(LayoutKind.Explicit, Pack = 1)]\n        struct PropVariant\n        {\n            [FieldOffset(0)] public VarEnum VarType;\n            [FieldOffset(2)] public ushort wReserved1;\n            [FieldOffset(4)] public ushort wReserved2;\n            [FieldOffset(6)] public ushort wReserved3;\n            [FieldOffset(8)] public byte bVal;\n            [FieldOffset(8)] public sbyte cVal;\n            [FieldOffset(8)] public ushort uiVal;\n            [FieldOffset(8)] public short iVal;\n            [FieldOffset(8)] public uint uintVal;\n            [FieldOffset(8)] public int intVal;\n            [FieldOffset(8)] public ulong ulVal;\n            [FieldOffset(8)] public long lVal;\n            [FieldOffset(8)] public float fltVal;\n            [FieldOffset(8)] public double dblVal;\n            [FieldOffset(8)] public short boolVal;\n            [FieldOffset(8)] public IntPtr pclsidVal;\n            [FieldOffset(8)] public IntPtr pszVal;\n            [FieldOffset(8)] public IntPtr pwszVal;\n            [FieldOffset(8)] public IntPtr punkVal;\n            [FieldOffset(8)] public IntPtr ca;\n            [FieldOffset(8)] public ComTypes.FILETIME filetime;\n\n        }\n\n        [Flags]\n        enum GPS\n        {\n            DEFAULT = 0x00000000,\n            HANDLERPROPERTIESONLY = 0x00000001,\n            READWRITE = 0x00000002,\n            TEMPORARY = 0x00000004,\n            FASTPROPERTIESONLY = 0x00000008,\n            OPENSLOWITEM = 0x00000010,\n            DELAYCREATION = 0x00000020,\n            BESTEFFORT = 0x00000040,\n            NO_OPLOCK = 0x00000080,\n            MASK_VALID = 0x000000FF\n        }\n\n        public static void HashLnk(string lnkPath)\n        {\n            SHCreateItemFromParsingName(lnkPath, null, typeof(IShellItem2).GUID, out IShellItem item);\n            IShellItem2 item2 = (IShellItem2)item;\n            PSGetPropertyKeyFromName(\"System.Link.TargetParsingPath\", out PropertyKey pk);\n            //shellPKey = PKEY_Link_TargetParsingPath\n            //formatID = B9B4B3FC-2B51-4A42-B5D8-324146AFCF25, propID = 2\n            string targetPath;\n            try { targetPath = item2.GetString(pk); }\n            catch { targetPath = null; }\n\n            PSGetPropertyKeyFromName(\"System.Link.Arguments\", out pk);\n            //shellPKey = PKEY_Link_Arguments\n            //formatID = 436F2667-14E2-4FEB-B30A-146C53B5B674, propID = 100\n            string arguments;\n            try { arguments = item2.GetString(pk); }\n            catch { arguments = null; }\n\n            string blob = GetGeneralizePath(targetPath) + arguments;\n            blob += \"do not prehash links.  this should only be done by the user.\";//特殊但必须存在的字符串\n            blob = blob.ToLower();\n            byte[] inBytes = Encoding.Unicode.GetBytes(blob);\n            int byteCount = inBytes.Length;\n            byte[] outBytes = new byte[byteCount];\n            HashData(inBytes, byteCount, outBytes, byteCount);\n            uint hash = BitConverter.ToUInt32(outBytes, 0);\n\n            Guid guid = typeof(IPropertyStore).GUID;\n            IPropertyStore store = item2.GetPropertyStore(GPS.READWRITE, ref guid);\n            PSGetPropertyKeyFromName(\"System.Winx.Hash\", out pk);\n            //shellPKey = PKEY_WINX_HASH\n            //formatID = FB8D2D7B-90D1-4E34-BF60-6EAC09922BBF, propID = 2\n            PropVariant pv = new PropVariant { VarType = VarEnum.VT_UI4, ulVal = hash };\n            store.SetValue(ref pk, ref pv);\n            store.Commit();\n\n            Marshal.ReleaseComObject(store);\n            Marshal.ReleaseComObject(item);\n        }\n\n        private static readonly Dictionary<string, string> GeneralizePathDic = new Dictionary<string, string>\n        {\n            { \"%ProgramFiles%\", \"{905e63b6-c1bf-494e-b29c-65b732d3d21a}\" },\n            { \"%SystemRoot%\\\\System32\", \"{1ac14e77-02e7-4e5d-b744-2eb1ae5198b7}\" },\n            { \"%SystemRoot%\", \"{f38bf404-1d43-42f2-9305-67de0b28fc23}\" }\n        };\n\n        private static string GetGeneralizePath(string filePath)\n        {\n            if(string.IsNullOrEmpty(filePath)) return filePath;\n            foreach(var kv in GeneralizePathDic)\n            {\n                string dirPath = Environment.ExpandEnvironmentVariables(kv.Key);\n                if(filePath.StartsWith(dirPath + \"\\\\\", StringComparison.OrdinalIgnoreCase))\n                {\n                    filePath = filePath.Replace(dirPath, kv.Value); break;\n                }\n            }\n            return filePath;\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Methods/XmlDicHelper.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing Microsoft.Win32;\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO;\nusing System.Text;\nusing System.Xml;\n\nnamespace ContextMenuManager.Methods\n{\n    static class XmlDicHelper\n    {\n        public static readonly List<XmlDocument> EnhanceMenusDic = new List<XmlDocument>();\n        public static readonly List<XmlDocument> DetailedEditDic = new List<XmlDocument>();\n        public static readonly List<XmlDocument> UwpModeItemsDic = new List<XmlDocument>();\n        public static readonly Dictionary<string, bool> EnhanceMenuPathDic\n            = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);\n        public static readonly Dictionary<Guid, bool> DetailedEditGuidDic = new Dictionary<Guid, bool>();\n\n        /// <summary>重新加载字典</summary>\n        public static void ReloadDics()\n        {\n            XmlDocument LoadXml(string xmlPath)\n            {\n                if(!File.Exists(xmlPath)) return null;\n                try\n                {\n                    XmlDocument doc = new XmlDocument();\n                    Encoding encoding = EncodingType.GetType(xmlPath);\n                    string xml = File.ReadAllText(xmlPath, encoding).Trim();\n                    doc.LoadXml(xml);\n                    return doc;\n                }\n                catch(Exception e)\n                {\n                    AppMessageBox.Show(e.Message + \"\\n\" + xmlPath);\n                    return null;\n                }\n            }\n\n            void LoadDic(List<XmlDocument> dic, string webPath, string userPath, string defaultContent)\n            {\n                if(!File.Exists(webPath)) File.WriteAllText(webPath, defaultContent, Encoding.Unicode);\n                dic.Clear();\n                dic.Add(LoadXml(webPath));\n                dic.Add(LoadXml(userPath));\n            }\n\n            LoadDic(UwpModeItemsDic, AppConfig.WebUwpModeItemsDic,\n                AppConfig.UserUwpModeItemsDic, Properties.Resources.UwpModeItemsDic);\n            LoadDic(EnhanceMenusDic, AppConfig.WebEnhanceMenusDic,\n                AppConfig.UserEnhanceMenusDic, Properties.Resources.EnhanceMenusDic);\n            LoadDic(DetailedEditDic, AppConfig.WebDetailedEditDic,\n                AppConfig.UserDetailedEditDic, Properties.Resources.DetailedEditDic);\n\n            EnhanceMenuPathDic.Clear();\n            for(int i = 0; i < 2; i++)\n            {\n                XmlDocument doc = EnhanceMenusDic[i];\n                if(doc?.DocumentElement == null) continue;\n                foreach(XmlNode pathXN in doc.SelectNodes(\"Data/Group/RegPath\"))\n                {\n                    if(EnhanceMenuPathDic.ContainsKey(pathXN.InnerText)) continue;\n                    EnhanceMenuPathDic.Add(pathXN.InnerText, i == 1);\n                }\n            }\n\n            DetailedEditGuidDic.Clear();\n            for(int i = 0; i < 2; i++)\n            {\n                XmlDocument doc = DetailedEditDic[i];\n                if(doc?.DocumentElement == null) continue;\n                foreach(XmlNode guidXN in doc.SelectNodes(\"Data/Group/Guid\"))\n                {\n                    if(GuidEx.TryParse(guidXN.InnerText, out Guid guid))\n                    {\n                        if(DetailedEditGuidDic.ContainsKey(guid)) continue;\n                        DetailedEditGuidDic.Add(guid, i == 1);\n                    }\n                }\n            }\n        }\n\n        public static bool JudgeOSVersion(XmlNode itemXN)\n        {\n            //return true;//测试用\n            bool JudgeOne(XmlNode osXN)\n            {\n                Version ver = new Version(osXN.InnerText);\n                Version osVer = Environment.OSVersion.Version;\n                int compare = osVer.CompareTo(ver);\n                string symbol = ((XmlElement)osXN).GetAttribute(\"Compare\");\n                switch(symbol)\n                {\n                    case \">\":\n                        return compare > 0;\n                    case \"<\":\n                        return compare < 0;\n                    case \"=\":\n                        return compare == 0;\n                    case \">=\":\n                        return compare >= 0;\n                    case \"<=\":\n                        return compare <= 0;\n                    default:\n                        return true;\n                }\n            }\n\n            foreach(XmlNode osXN in itemXN.SelectNodes(\"OSVersion\"))\n            {\n                if(!JudgeOne(osXN)) return false;\n            }\n            return true;\n        }\n\n        public static bool FileExists(XmlNode itemXN)\n        {\n            //return true;//测试用\n            foreach(XmlNode feXN in itemXN.SelectNodes(\"FileExists\"))\n            {\n                string path = Environment.ExpandEnvironmentVariables(feXN.InnerText);\n                if(!File.Exists(path)) return false;\n            }\n            return true;\n        }\n\n        public static bool JudgeCulture(XmlNode itemXN)\n        {\n            //return true;//测试用\n            string culture = itemXN.SelectSingleNode(\"Culture\")?.InnerText;\n            if(string.IsNullOrEmpty(culture)) return true;\n            if(culture.Equals(AppConfig.Language, StringComparison.OrdinalIgnoreCase)) return true;\n            if(culture.Equals(CultureInfo.CurrentUICulture.Name, StringComparison.OrdinalIgnoreCase)) return true;\n            return false;\n        }\n\n        public static byte[] ConvertToBinary(string value)\n        {\n            try\n            {\n                string[] strs = value.Split(' ');\n                byte[] bs = new byte[strs.Length];\n                for(int i = 0; i < strs.Length; i++)\n                {\n                    bs[i] = Convert.ToByte(strs[i], 16);\n                }\n                return bs;\n            }\n            catch { return null; }\n        }\n\n        public static RegistryValueKind GetValueKind(string type, RegistryValueKind defaultKind)\n        {\n            switch(type.ToUpper())\n            {\n                case \"REG_SZ\":\n                    return RegistryValueKind.String;\n                case \"REG_BINARY\":\n                    return RegistryValueKind.Binary;\n                case \"REG_DWORD\":\n                    return RegistryValueKind.DWord;\n                case \"REG_QWORD\":\n                    return RegistryValueKind.QWord;\n                case \"REG_MULTI_SZ\":\n                    return RegistryValueKind.MultiString;\n                case \"REG_EXPAND_SZ\":\n                    return RegistryValueKind.ExpandString;\n                default:\n                    return defaultKind;\n            }\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Program.cs",
    "content": "﻿using BluePointLilac.Methods;\nusing ContextMenuManager.Methods;\nusing System;\nusing System.Windows.Forms;\n\nnamespace ContextMenuManager\n{\n    //兼容.Net3.5和.Net4.0，兼容Vista - Win11\n    static class Program\n    {\n        [STAThread]\n        static void Main()\n        {\n            Application.EnableVisualStyles();\n            Application.SetCompatibleTextRenderingDefault(false);\n            if(SingleInstance.IsRunning()) return;\n            AppString.LoadStrings();\n            Updater.PeriodicUpdate();\n            XmlDicHelper.ReloadDics();\n            Application.Run(new MainForm());\n        }\n    }\n}"
  },
  {
    "path": "ContextMenuManager/Properties/App.manifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\">\n  <assemblyIdentity version=\"1.0.0.0\" name=\"MyApplication.app\"/>\n  <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v2\">\n    <security>\n      <requestedPrivileges xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n        <requestedExecutionLevel level=\"requireAdministrator\" uiAccess=\"false\"/>\n      </requestedPrivileges>\n      <applicationRequestMinimum>\n        <defaultAssemblyRequest permissionSetReference=\"Custom\" />\n        <PermissionSet class=\"System.Security.PermissionSet\" version=\"1\" ID=\"Custom\" SameSite=\"site\"/>\n      </applicationRequestMinimum>\n    </security>\n  </trustInfo>\n  <compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n    <application>\n      <supportedOS Id=\"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}\"/>\n    </application>\n  </compatibility>\n  <application xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n    <windowsSettings>\n      <dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware>\n    </windowsSettings>\n  </application>\n</assembly>"
  },
  {
    "path": "ContextMenuManager/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.InteropServices;\n\n[assembly: AssemblyTitle(\"Windows右键管理\")]\n[assembly: AssemblyDescription(\"Windows右键管理\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"蓝点lilac\")]\n[assembly: AssemblyProduct(\"Windows右键管理\")]\n[assembly: AssemblyCopyright(\"Copyright @ 2020-2021 蓝点lilac\")]\n[assembly: AssemblyTrademark(\"蓝点lilac\")]\n[assembly: AssemblyCulture(\"\")]\n[assembly: ComVisible(false)]\n[assembly: Guid(\"35190ec1-2515-488d-a2e9-825d6ff67aa2\")]\n[assembly: AssemblyVersion(\"3.3.3.1\")]\n[assembly: AssemblyFileVersion(\"3.3.3.1\")]"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.c",
    "content": "#include <stdio.h>\n \nint main()\n{\n    return 0;\n}"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.html",
    "content": "<!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",
    "content": "{\\rtf1}"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/ShellNew/0.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/AppLanguageDic.ini",
    "content": "﻿;此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典。\n;可帮助作者为此程序提供翻译并提交到Github，以下内容中等号右侧内容替换为翻译文本。\n;General - Translator 为翻译贡献者，General - Language 为语言名称，如en-US 美国英语，\n;General - TranslatorUrl 为翻译贡献者的URL地址(能用Win+R命令打开的URL链接即可)\n;翻译说明：暂时不翻译的值保留为空即可，字典内赋值换行使用\\r\\n或\\n进行转义。\n;翻译贡献者和为多人时请使用\\r\\n或\\n对 Translator 的值和对应的 TranslatorUrl 值换行，\n;没有URL地址赋值为null，使贡献者与链接一一对应，如 Translator = Bob \\r\\n Join \\r\\n Andi, \n;TranslatorUrl = https://github.com/BluePointLilac \\r\\n null \\r\\n https://gitee.com/BluePointLilac\n\n[General]\nAppName = Windows右键管理\nLanguage = zh-CN 简体中文\nTranslator = 蓝点lilac\nTranslatorUrl = tencent://message/?uin=1617859183\n\n[ToolBar]\nHome = 主页\nType = 文件类型\nRule = 其他规则\nRefresh = 刷新\nAbout = 关于\n\n[SideBar]\nFile = 文件\nFolder = 文件夹\nDirectory = 目录\nBackground = 目录背景\nDesktop = 桌面背景\nDrive = 磁盘分区\nAllObjects = 所有对象\nComputer = 此电脑\nRecycleBin = 回收站\nLibrary = 库\nNew = 新建菜单\nSendTo = 发送到\nOpenWith = 打开方式\nWinX = Win+X\n\nLnkFile = lnk文件\nUwpLnk = uwp lnk\nExeFile = exe文件\nCustomExtension = 自选格式\nPerceivedType = 感知类型\nDirectoryType = 目录类型\nUnknownType = 未知格式\nMenuAnalysis = 菜单分析\n\nEnhanceMenu = 增强菜单\nDetailedEdit = 详细编辑\nDragDrop = 右键拖拽\nPublicReferences = 公共引用\nCustomRegPath = 自选路径\nGuidBlocked = GUID 锁\nIEMenu = IE浏览器\n\nAppSetting = 程序设置\nAppLanguage = 程序语言\nCheckUpdate = 检测更新\nDictionaries = 程序字典\nAboutApp = 关于程序\nDonate = 捐赠作者\n\n[StatusBar]\nFile = 所有类型文件的右键菜单\nFolder = 所有文件夹的右键菜单\nDirectory = 所有文件目录的右键菜单\nBackground = 所有目录背景和桌面背景的右键菜单\nDesktop = 桌面背景右键菜单\nDrive = 所有磁盘驱动器的右键菜单\nAllObjects = 所有文件系统对象(包括文件、文件夹)的右键菜单\nComputer = 此电脑图标的右键菜单\nRecycleBin = 回收站图标的右键菜单\nLibrary = 所有库和库目录背景的右键菜单\nNew = 所有目录背景和桌面背景的右键 \"新建\" 的菜单项目\nSendTo = 所有文件系统对象的右键 \"发送到\" 的菜单项目\nOpenWith = 所有文件右键 \"打开方式\" 的菜单项目\nWinX = Win8~Win10 \"开始\" 按钮的右键 Win+X 菜单项目\n\nLnkFile = 所有LNK快捷方式的右键菜单\nUwpLnk = Win8~Win10 UWP应用快捷方式的右键菜单\nExeFile = 所有EXE可执行文件的右键菜单\nCustomExtension = 自定义指定格式文件的右键菜单\nPerceivedType = 自定义指定文件感知类型的右键菜单\nDirectoryType = 自定义指定目录感知类型的右键菜单\nUnknownType = 所有未关联打开方式的格式文件的右键菜单\nMenuAnalysis = 分析指定文件对象所有的右键菜单所在位置\n\nEnhanceMenu = 添加一些强大便捷的菜单项\nDetailedEdit = 系统和其他程序内部部分菜单详细设置规则\nDragDrop = 右键拖拽文件时的菜单项目\nPublicReferences = 编辑用户添加的公共引用的Shell类型子菜单项目\nCustomRegPath = 编辑自定义注册表路径的右键菜单项目\nGuidBlocked = 适用于隐藏部分顽固的依赖GUID的ShellEx类型项目\nIEMenu = Internet Explorer 网页的右键菜单\n\n[Menu]\nChangeText = 更改文本\nItemIcon = 菜单图标\nChangeIcon = 更改图标\nShieldIcon = 盾牌图标\nAddIcon = 添加图标\nDeleteIcon = 删除图标\nItemPosition = 菜单位置\nSetDefault = 默认\nSetTop = 置顶\nSetBottom = 置底\nOtherAttributes = 其他属性\nOnlyWithShift = 仅在按住 Shift 键后显示\nOnlyInExplorer = 仅在 Explorer 窗口显示\nNoWorkingDirectory = 不使用右键所处目录信息\nNeverDefault = 从不用作左键默认执行命令\nShowAsDisabledIfHidden = 被禁用时灰色显示不隐藏\nDetails = 详细信息\nWebSearch = 网页搜索\nChangeCommand = 更改命令\nRunAsAdministrator = 提升权限\nFileProperties = 文件属性\nFileLocation = 文件位置\nRegistryLocation = 注册表位置\nExportRegistry = 导出注册表\nDelete = 删除此项\nDeleteReference = 删除引用\nHandleGuid = 处理GUID\nCopyGuid = 复制GUID\nBlockGuid = 锁定GUID\nClsidLocation = CLSID路径\nAddGuidDic = 添加字典\nInitialData = 编辑文件初始数据\nBeforeSeparator = 显示在分割线上方\nChangeGroup = 更换分组\nRestoreDefault = 还原默认\nEdit = 编辑\nSave = 保存\nFoldAll = 全部折叠\nUnfoldAll = 全部展开\n\n[Dialog]\nBrowse = 浏览\nProgram = 程序\nAllFiles = 所有文件\nRegistryFile = 注册表文件\nItemText = 菜单文本\nItemCommand = 菜单命令\nCommandArguments = 命令参数\nSingleMenu = 一级\nMultiMenu = 多级\nPublic = 公有\nPrivate = 私有\nSelectAll = 全选\nInputGuid = 输入Guid\nAddGuidDic = 添加Guid本地字典\nDeleteGuidDic = 删除\nNoPerceivedType = 无感知\nTextFile = 文本文件\nDocumentFile = 文档文件\nImageFile = 图像文件\nVideoFile = 视频文件\nAudioFile = 音频文件\nCompressedFile = 压缩文件\nSystemFile = 系统文件\nDocumentDirectory = 文档目录\nImageDirectory = 图像目录\nVideoDirectory = 视频目录\nAudioDirectory = 音频目录\nEditSubItems = 编辑 \"%s\" 的子菜单项目\nDetailedEdit = 详细编辑 \"%s\" 菜单项目\nCheckReference = 请勾选你想要引用的菜单项目\nCheckCopy = 请勾选你想要复制的菜单项目\nSelectExtension = 请选择一个文件扩展名\nSelectPerceivedType = 请选择一个文件感知类型\nSelectDirectoryType = 请选择一个目录感知类型\nSelectGroup = 请选择保存分组\nSelectNewItemType = 请选择新建菜单类型\nSelectObjectType = 请选择要分析的对象类型\nSelectDropEffect = 请选择拖拽文件默认命令\nDefaultDropEffect = 默认(同盘移动、异盘复制)\nCopyDropEffect = 复制(Ctrl)\nMoveDropEffect = 移动(Shift)\nCreateLinkDropEffect = 创建快捷方式(Alt)\nDownloadLanguages = 下载语言文件\nTranslateTool = 翻译工具\nDefaultText = 默认文本\nOldTranslation = 旧译文\nNewTranslation = 新译文\nDonateInfo = 此名单不定期更新，上次更新：%date \\r\\n\\r\\n累计金额：%money 元，累计人次：%count 人次\n\n[Message]\nTextCannotBeEmpty = 菜单文本不能为空！\nCommandCannotBeEmpty = 菜单命令不能为空！\nStringParsingFailed = 本地化字符串解析失败！\nTextLengthCannotExceed80 = 菜单文本过长，长度不允许超过80！\nConfirmDeletePermanently = 确认是否永久删除此项？\\r\\n此操作无法还原，请谨慎操作！\nDeleteButCanRestore = 确认删除此菜单的注册表项目？\\r\\n由于启用了自动备份(默认启用)，\\r\\n删除后可在备份文件夹中还原。\nConfirmDeleteReference = 确认是否移除对该项目的引用？\nConfirmDelete = 确认是否删除该项？\nConfirmDeleteReferenced = 确认是否删除此项？\\r\\n所有引用此项的项目都会失效，请谨慎操作！\nCannotAddNewItem = 系统限制子菜单数目最多为16，\\r\\n无法添加更多的子菜单项目！\nVistaUnsupportedMulti = Vista系统不支持多级菜单！\nCannotHideSubItem = 你的系统版本太低，不支持隐藏子级菜单！\nUnsupportedFilename = 不支持的文件名，\\r\\n可能已经存在相同文件名的菜单项目！\nNoOpenModeExtension = 此扩展名没有关联默认打开方式，\\r\\n请先为此类型文件关联打开方式！\nCannotChangePath = 不允许更改文件路径！\nCopiedToClipboard = 已复制到剪切板:\nMalformedGuid = 格式不正确的Guid\nHasBeenAdded = 此项目已被添加！\nSelectSubMenuMode = 该多级菜单子项目数为0，你有两个选择:\\r\\n①该多级菜单的所有子菜单项目私有(推荐)，\\r\\n②该多级菜单可与其他多级菜单引用相同子项，\\r\\n请做出你的选择......\nEditInitialData = 此程序现仅支持编辑纯文本文件的初始数据，\\r\\n其他类型文件请自行编辑注册表\"Data\"键值，\\r\\n请确认是否继续你的操作？\nPromptIsOpenItem = 该项为文件或文件夹的\"打开\"菜单，\\n盲目操作可能会导致无法打开文件或文件夹，\\n请确认是否继续你的操作？(不建议)\nSelectRegPath = 操作步骤：\\r\\n① 打开注册表编辑器(自动)\\r\\n② 导航到目标注册表路径\\r\\n③ 关闭注册表编辑器窗口\\n请确认是否继续？\nRestartApp = 程序将会重新启动！\nFileNotExists = 文件不存在！\nFolderNotExists = 文件夹不存在！\nUpdateInfo = 【检测更新】\\r\\n当前版本：%v1\\r\\n最新版本：%v2\\r\\n是否立即下载更新？\nUpdateSucceeded = 程序更新成功！\nDicUpdateSucceeded = 字典和语言文件更新成功!\nVersionIsLatest = 当前版本为最新版！\nWebDataReadFailed = 网络数据读取失败!\nOpenWebUrl = 是否打开相关网页?\nAuthorityProtection = 此菜单注册表项目可能受安全软件保护，\\r\\n无法对其进行禁用删除和其他个性化修改。\nWinXSorted = 为优化排序功能已对部分项目重新编号，\\r\\n需要重启文件资源管理器应用效果\nRestoreDefault = 确认还原为默认菜单项目？\nDeleteGroup = 确认永久删除此组及组内所有菜单项目？\n\n[Tip]\nRestartExplorer = 重启Explorer会使桌面闪烁片刻，正常现象无需担心，\\r\\n或者你也可以稍后重启或注销计算机使你的操作生效\nCustomFolder = 禁用此项将会同时禁用文件系统\\r\\n对象属性面板中的自定义选项卡\nSendToDrive = 仅当插入可移动磁盘时有作用，\\r\\n显示该可移动磁盘的所有分区\nBuildSendtoMenu = 禁用此项将加快主菜单弹出速度\\r\\n但会延缓发送到子菜单弹出速度\nInvalidItem = 无效菜单项目将导致此项以下的\\r\\n所有菜单项目不可见(建议删除)\nEditSubItems = 编辑子菜单项目\nAddReference = 从公共引用项目中添加引用\nAddFromPublic = 从公共引用中复制菜单项目\nAddFromParentMenu = 从母菜单中复制项目\nAddSeparator = 添加分隔线\nDeleteGuidDic = 删除用户自行添加的该项的本地Guid字典\nLockNewMenu = 启用后可阻止第三方程序增加项目\\r\\n且可对现有项目排序(关闭后复原)\nDropOrSelectObject = 请拖拽或通过按钮选择文件或目录\nConfigPath = 更改配置和数据文件保存路径后，\\r\\n会导致部分已启用增强菜单失效，\\r\\n可在增强菜单中重新启用一遍\nCommandFiles = 此命令依赖配置文件，移动配置文件位置\\r\\n会导致此菜单项失效，重新启用一遍即可\nCreateGroup = 新建一个分组\nImmediatelyCheck = 立即检查\n\n[Other]\nCustomFolder = 自定义文件夹(&F)...\nBuildSendtoMenu = 快速构建发送到子菜单\nNewItem = 新建一个菜单项目\nAddGuidBlockedItem = 添加GUID锁定项目\nLockNewMenu = 锁定新建菜单并启用排序功能\nInvalidItem = 无效菜单项目:\nSeparator = >>>>>> 分割线 <<<<<<\nSelectRegPath = 请选择注册表项\nCurrentExtension = 你当前选择的文件扩展名为 %s\nCurrentPerceivedType = 你当前选择的文件感知类型为 %s\nCurrentDirectoryType = 你当前选择的目录感知类型为 %s\nCurrentFilePath = 你当前选择的文件对象路径为\nCurrentRegPath = 你当前选择的注册表路径为\nWinXSortable = 启用 WinX 菜单排序功能\nShowFilePath = 状态栏实时显示文件路径\nOpenMoreRegedit = 注册表编辑器窗口多开\nOpenMoreExplorer = 文件资源管理器窗口多开\nRestartExplorer = 当前部分操作需要重启文件资源管理器生效\nSwitchDictionaries = 切换字典\nWebDictionaries = 网络字典\nUserDictionaries = 用户字典\nDictionaryDescription = 字典说明\nGuidInfosDictionary = GUID信息\nUwpMode = UWP模块\nTranslators = 翻译贡献者\nDonationList = 捐赠名单\nConfigPath = 配置和数据文件保存位置\nAppDataDir = AppData 目录\nAppDir = 程序所在目录\nAutoBackup = 删除菜单时自动备份注册表\nSetUpdateFrequency = 设置程序自动检查更新频率\nOnceAWeek = 每周一次\nOnceAMonth = 每月一次\nOnceASeason = 每季一次\nNeverCheck = 从不检查\nSetRequestRepo = 设置网络数据访问存储库站点\nProtectOpenItem = 保护名称为 \"打开\" 的菜单项目\nWebSearchEngine = 设置网页搜索使用的搜索引擎\nCustomEngine = 自定义\nSetCustomEngine = 设置搜索引擎 (以 %s 代替搜索关键词)\nHideDisabledItems = 隐藏已禁用的菜单项目\nHideSysStoreItems = 隐藏公共引用中的系统菜单\nSetPerceivedType = 设置扩展名为 %s 的文件感知类型为\nSetDefaultDropEffect = 设置文件对象默认拖拽命令为\nTopMost = 使窗口始终在屏幕最上方\n\nAboutApp = [兼容性能]\\r\\n 1 = 适用于Win10、8.1、8、7、Vista \\r\\n 2 = 适用于 64bit、32bit CPU 操作系统\\r\\n 3 = 适配高分屏，最佳缩放比为150%\\r\\n\\r\\n[代码开源]\\r\\n 1 = 代码语言：C Sharp，Winform 程序，MIT 开源协议\\r\\n 2 = Github 仓库：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee 仓库：https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[温馨提示]\\r\\n 1 = 程序需要对大量的注册表项和文件进行读写删改操作，这些行为比较敏感，\\r\\n 可能会被Windows Defender等误报为病毒，如发生此情况请自行添加进白名单。\\r\\n\\r\\n 2 = 一些特殊菜单项可能会受到其他因素影响导致不会直接显示在右键菜单中，\\r\\n    但是按照程序使用的通用规则在此程序中仍会显示为启用状态，这是正常的现象。\\r\\n\\r\\n 3 = 每个右键管理程序禁用菜单方法可能不同，建议不要同时使用多个右键菜单管理程序，\\r\\n 大部分程序使用简单暴力的备份-删除法，此程序尽可能使用了系统提供的键值进行隐藏，\\r\\n 通过其他程序禁用的菜单项目，请先使用对应程序还原，不然可能无法在此程序中看到它。\\r\\n\\r\\n 4 = 此程序不用于清理未卸载干净的程序，但可帮助你定位菜单项相关注册表和文件位置，\\r\\n 你可根据相关内容进行你的操作，如果你是一个电脑小白，建议只碰启用\\禁用开关。\n\nDictionaries = [字典说明]\\r\\n 此程序拥有几个字典文件，每份字典又有用户字典(User目录)和网络字典(Web目录)\\r\\n 如果想为此程序添加字典可右键保存文件至User目录，并按照文件内说明进行添加\\r\\n 你可以将你的字典发送到我的邮箱或者提交合并到Github为此项目做出你的贡献\\n 右侧选项卡中为原始字典内容，你可以切换选项卡进行查看和右键编辑、保存操作\\r\\n\\r\\n[字典内容]\\r\\n 1 = 程序显示文本语言字典 (Languages目录)\\r\\n 2 = ShellEx菜单项GUID文本图标字典 (GuidInfosDic.ini)\\r\\n 3 = 系统和其他程序内部部分菜单详细设置规则字典 (DetailedEditDic.xml)\\r\\n 4 = 增强菜单项目字典 (EnhanceMenusDic.xml)\\r\\n 5 = UWP新模块字典 (UWPModeItemsDic.xml)\n\nDonate = 此程序完全免费，如果你觉得这个软件对你有所帮助，你可以通过扫描\\r\\n下方二维码(微信、支付宝、腾讯QQ)进行捐赠，金额请随意，谢谢支持！\\r\\n也期待你在Github或者Gitee上为此程序项目点亮Star (这对我很重要！)"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/DetailedEditDic.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--每个程序为一个Group，Text为Group项显示文本，Guid用于判断用户是否安装此程序并决定是否显示该Group，不设置Guid则为常驻菜单，RegPath为程序相关注册表主路径;\n其相关菜单项目设置作为一个Item子元素，Item的Text为该Item项显示文本，Tip为鼠标悬浮在开关上时的提示信息，需要重启资源管理器生效则添加RestartExplorer;\nItem的子元素Rule为相关注册表内容，RegPath省略则默认为Group主路径，以\\开头则为Group主路径的子项路径；\nValueName为相关键名，On为启用键值，Off为禁用键值；不设置On或Off属性时，其值为null，对应注册表键值不存在；\n每个Item可能受多个注册表Rule影响，按照顺序进行键值判定；判定规则：当有多条规则时，前面的规则注册表键值匹配On则为On，匹配Off则为Off，并终止判断，都不匹配时继续往下判断，若所有规则都不匹配则为On\nValueKind为键值类型，默认键值类型ValueKind为REG_DWORD，为默认值时可省略，目前仅支持REG_SZ、REG_DWORD、REG_EXPAND_SZ、REG_BINARY的键值类型-->\n\n<Data>\n  <Group>\n    <!--系统-->\n    <Text Value='@shell32.dll,-8770'/>\n    <Guid>20D04FE0-3AEA-1069-A2D8-08002B30309D</Guid>\n    <RegPath>HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer</RegPath>\n    <Item>\n      <Text Value='右键菜单'/>\n      <Text Value='Context Menu'>\n        <Culture>en-US</Culture>\n      </Text>\n      <RestartExplorer/>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoViewContextMenu' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoViewContextMenu' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='使用经典紧凑右键菜单'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0.14393</OSVersion>\n      <OSVersion Compare='&lt;'>10.0.17763</OSVersion>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\FlightedFeatures' ValueName='ImmersiveContextMenu' On='0'/>\n    </Item>\n    <Item>\n      <Text Value='右键菜单在左侧弹出'/>\n      <Tip Value='更改后需要重新登录账户生效'/>\n      <OSVersion Compare='&gt;='>10.0</OSVersion>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows' ValueName='MenuDropAlignment' On='1'/>\n      <Process FileName='explorer.exe' Arguments='shell:::{80F3F1D5-FECA-45F3-BC32-752C152E456E}'/>\n    </Item>\n    <Item>\n      <Text Value='Shell类型菜单同时操作文件对象数量限制'/>\n      <Tip Value='系统默认值为15，超过15为无限制'/>\n      <IsNumberItem/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer' ValueName='MultipleInvokePromptMinimum' Max='32767' Min='1' Default='15'/>\n    </Item>\n    <Item>\n      <Text Value='创建快捷方式时去除 \"快捷方式\" 后缀'/>\n      <RestartExplorer/>\n      <Rule RegPath='\\NamingTemplates' ValueName='ShortcutNameTemplate' On='%s' ValueKind='REG_SZ'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\NamingTemplates' ValueName='ShortcutNameTemplate' On='%s' ValueKind='REG_SZ'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer' ValueName='Link' On='00 00 00 00' ValueKind='REG_BINARY'/>\n    </Item>\n    <Item>\n      <Text Value='文件(夹) 复制粘贴去除 \"副本\" 后缀'/>\n      <Rule RegPath='\\NamingTemplates' ValueName='CopyNameTemplate' On='%s' ValueKind='REG_SZ'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\NamingTemplates' ValueName='CopyNameTemplate' On='%s' ValueKind='REG_SZ'/>\n    </Item>\n    <Item>\n      <Text Value='文件(夹) 加密 解密'/>\n      <Tip Value='当前账户加密后的文件需解密后才能在其他账户中打开'/>\n      <Rule RegPath='\\Advanced' ValueName='EncryptionContextMenu' On='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced' ValueName='EncryptionContextMenu' On='1'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='任务栏'/>\n    <Text Value='TaskBar'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Guid>90aa3a4e-1cba-4233-b8bb-535773d48449</Guid>\n    <RegPath>HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer</RegPath>\n    <Item>\n      <Text Value='右键菜单'/>\n      <RestartExplorer/>\n      <Rule ValueName='NoTrayContextMenu' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoTrayContextMenu' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='任务栏设置 锁定任务栏'/>\n      <RestartExplorer/>\n      <Rule ValueName='TaskbarLockAll' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='TaskbarLockAll' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='工具栏'/>\n      <Tip Value='禁用后已启用工具栏将被禁用, 请谨慎操作'/>\n      <RestartExplorer/>\n      <Rule ValueName='NoToolbarsOnTaskbar' Off='1'/>\n      <Rule ValueName='NoCloseDragDropBands' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoToolbarsOnTaskbar' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoCloseDragDropBands' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='固定到任务栏'/>\n      <Tip Value='禁用时已固定图标会被隐藏，重新启用会重现&#x000A;文件右键菜单“固定到任务栏”会同时消失&#x000A;且无法拖拽文件到任务栏进行固定'/>\n      <RestartExplorer/>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' ValueName='TaskbarNoPinnedList' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' ValueName='TaskbarNoPinnedList' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='人脉'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0.16199</OSVersion>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\People' ValueName='PeopleBand' Off='0'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' ValueName='HidePeopleBar' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='资讯和兴趣'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0.19043</OSVersion>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Feeds' ValueName='EnableFeeds' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='Windows lnk 工作区(Win+W)'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0</OSVersion>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\WindowsInkWorkspace' ValueName='AllowWindowsInkWorkspace' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='开始屏幕'/>\n    <Text Value='Start Menu'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Guid>470c0ebd-5d73-4d58-9ced-e91e22e23282</Guid>\n    <RegPath>HKEY_LOCAL_MACHINE\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer</RegPath>\n    <Item>\n      <Text Value='程序右键菜单'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0.17134</OSVersion>\n      <Rule ValueName='DisableContextMenusInStart' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' ValueName='DisableContextMenusInStart' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='卸载'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>6.2</OSVersion>\n      <Rule ValueName='NoUninstallFromStart' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' ValueName='NoUninstallFromStart' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='以其他用户身份运行'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0</OSVersion>\n      <Rule ValueName='ShowRunAsDifferentUserInStart' On='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Policies\\Microsoft\\Windows\\Explorer' ValueName='ShowRunAsDifferentUserInStart' On='1'/>\n    </Item>\n    <Item>\n      <Text Value='磁贴调整大小、布局、固定、卸载'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>6.2</OSVersion>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoChangeStartMenu' Off='1'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer' ValueName='NoChangeStartMenu' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='最近打开文件跳转列表'/>\n      <OSVersion Compare='&gt;='>10.0</OSVersion>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced' ValueName='Start_TrackDocs' Off='0'/>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced' ValueName='Start_TrackDocs' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='最近打开文件跳转列表数量限制'/>\n      <IsNumberItem/>\n      <OSVersion Compare='&gt;='>10.0</OSVersion>\n      <Rule RegPath='HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced' ValueName='JumpListItems_Maximum' Max='60' Min='0' Default='13'/>\n    </Item>\n    <Item>\n      <Text Value='开始按钮右键菜单(Win+X) 命令提示符 替换为 PowerShell'/>\n      <RestartExplorer/>\n      <OSVersion Compare='&gt;='>10.0</OSVersion>\n      <Rule RegPath='HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced' ValueName='DontUsePowerShellOnWinX' Off='1'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='Bandizip'/>\n    <Guid>5b69a6b4-393b-459c-8ebb-214237a9e7ac</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\Bandizip</RegPath>\n    <Item>\n      <Text Value='禁用上下文菜单'/>\n      <Text Value='Disable context menu'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_DoNotUse' On='1' Off='0' ValueKind='REG_DWORD'/>\n    </Item>\n    <Item>\n      <Text Value='层叠上下文菜单'/>\n      <Text Value='Cascaded context menu'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ShowSubmenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='隐藏Bandizip图标'/>\n      <Text Value='Hide Bandizip icon'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_HideIcon' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='预览压缩文件'/>\n      <Text Value='Preview Archive'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_Preview' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='预览文件数量限制'/>\n      <Text Value='Limit preview files to'>\n        <Culture>en-US</Culture>\n      </Text>\n      <IsNumberItem/>\n      <Rule ValueName='shell_PreviewSize' Max='20' Min='1' Default='6'/>\n    </Item>\n    <Item>\n      <Text Value='新建文件夹'/>\n      <Text Value='New Folder'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_CreateNewFolder' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='打开命令提示符'/>\n      <Text Value='Launch Command Window'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_OpenCmd' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压到当前文件夹'/>\n      <Text Value='Extract Here'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ExtractHere' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='自动解压'/>\n      <Text Value='Extract Here (Smart)'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ExtractAuto' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压到...'/>\n      <Text Value='Extract to...'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ExtractSub' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压到当前文件夹并删除原始文件 (智能)'/>\n      <Text Value='Extract Here (Smart) and Delete'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ExtractAuto_Del' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='选择解压路径'/>\n      <Text Value='Extract to another folder...'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ExtractDlg' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='测试压缩文件'/>\n      <Text Value='Test Archive'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_TestArchive' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='用Bandizip打开'/>\n      <Text Value='Open with Bandizip'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_OpenArchive' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='以管理员身份解压'/>\n      <Text Value='Extract as Administrator'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ExtractAsAdmin' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='以管理员身份压缩'/>\n      <Text Value='Compress as Administrator'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ArchivingAsAdmin' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='选中压缩文件时仍显示压缩菜单'/>\n      <Text Value='Show archive context menu even for archive files'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_ShowCompressMenu2Archive' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压后打开文件夹'/>\n      <Text Value='Open the folder after extracting'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='openFolderWhenComplete' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压完成后不要关闭进度窗口'/>\n      <Text Value='Do not close the progress window after extracting'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='doNotCloseExtractDlg' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='压缩完成后不要关闭进度窗口'/>\n      <Text Value='Do not close the progress window after archiving'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='doNotCloseCompressDlg' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='Honeyview'/>\n    <Guid>9b6d38f3-8ef4-48a5-ad30-ffffffffffff</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\Honeyview</RegPath>\n    <Item>\n      <Text Value='在资源管理器中使用上下文菜单'/>\n      <Text Value='Use context menu in Windows Explorer'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_useShellMenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='用 蜂蜜浏览器 转换图片'/>\n      <Text Value='Convert image with Honeyview'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_transformDlg' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='用 蜂蜜浏览器 浏览图片'/>\n      <Text Value='View image with Honeyview'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_showWithHoneyview' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='上下文菜单预览'/>\n      <Text Value='Preview in context menu'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_previewImage' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='显示图片信息'/>\n      <Text Value='Show image info'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_showImageInfo' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='显示软件图标'/>\n      <Text Value='Show Honeyview icon'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='shell_showIcon' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='WinRAR'/>\n    <Guid>b41db860-64e4-11d2-9906-e49fadc173ca</Guid>\n    <Guid>b41db860-8ee4-11d2-9906-e49fadc173ca</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\WinRAR</RegPath>\n    <Item>\n      <Text Value='层叠右键菜单'/>\n      <Text Value='Cascaded context menus'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup' ValueName='CascadedMenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='显示图标'/>\n      <Text Value='Icons in context menus'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup' ValueName='MenuIcons' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压文件(A)...'/>\n      <Text Value='Extract Files...'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='ExtrTo' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压到当前文件夹(X)'/>\n      <Text Value='Extract Here'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='ExtrHere' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压到 [文件夹名\\] (E)'/>\n      <Text Value='Extract to [folder\\]'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='Extr' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压每个压缩文件到单独文件夹(S)'/>\n      <Text Value='Extract each archive to separate folder'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='ExtrSep' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='使用WinRAR打开(用于自解压文件)'/>\n      <Text Value='Open with WinRAR (for SFX archives)'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='OpenSFX' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='使用WinRAR打开(用于常规压缩文件)'/>\n      <Text Value='Open with WinRAR (for usual archives)'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='OpenArc' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='添加到压缩文件(A)...'/>\n      <Text Value='Add to archive...'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='AddTo' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='添加到 [压缩文件名称](T)'/>\n      <Text Value='Add to [archive name]'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='AddArc' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='压缩到 [压缩文件名称] 并发送电子邮件'/>\n      <Text Value='Compress to [archive name] and email'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='EmailArc' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='压缩并发送电子邮件...'/>\n      <Text Value='Compress and email...'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='EmailOpt' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='测试压缩文件(R)'/>\n      <Text Value='Test archive'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='Test' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='转换压缩文件(V)...'/>\n      <Text Value='Convert archive...'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='Convert' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='右键拖放文件显示压缩菜单'/>\n      <Text Value='Display archiving items in Drag and drop context menu'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='DragAdd' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='右键拖放压缩文件显示解压菜单'/>\n      <Text Value='Display extraction items in Drag and drop context menu'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule RegPath='\\Setup\\MenuItems' ValueName='DragExtr' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='7-zip'/>\n    <Guid>23170f69-40c1-278a-1000-000100020000</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\7-zip</RegPath>\n    <Item>\n      <Text Value='层叠右键菜单'/>\n      <Rule RegPath='\\Options' ValueName='CascadedMenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='右键菜单显示图标'/>\n      <Rule RegPath='\\Options' ValueName='MenuIcons' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='排除重复的根文件夹'/>\n      <Rule RegPath='\\Options' ValueName='ElimDupExtract' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='NVIDIA'/>\n    <Guid>3d1975af-48c6-4f8e-a182-be0e08fa86a9</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\NVIDIA Corporation</RegPath>\n    <Item>\n      <Text Value='显示桌面上下文菜单'/>\n      <Rule RegPath='\\Global\\NvCplApi\\Policies' ValueName='ContextUIPolicy' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='用图形处理器运行'/>\n      <Rule RegPath='\\Global\\CoProcManager' ValueName='ShowContextMenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='显示托盘图标'/>\n      <Rule RegPath='\\Global\\CoProcManager' ValueName='ShowTrayIcon' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='ACD看图'/>\n    <Guid>c2396f1e-4ba2-4b7d-857a-f764761c012b</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\acdkantu</RegPath>\n    <Item>\n      <Text Value='显示桌面右键菜单'/>\n      <Rule ValueName='menu' On='1' Off='0' ValueKind='REG_SZ'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='Notepad++'/>\n    <Guid>b298d29a-a6ed-11de-ba8c-a68e55d89593</Guid>\n    <RegPath>HKEY_CLASSES_ROOT\\CLSID\\{b298d29a-a6ed-11de-ba8c-a68e55d89593}</RegPath>\n    <Item>\n      <Text Value='菜单显示文本'/>\n      <IsStringItem/>\n      <Rule RegPath='\\Settings' ValueName='Title'/>\n    </Item>\n    <Item>\n      <Text Value='显示菜单图标'/>\n      <Rule RegPath='\\Settings' ValueName='ShowIcon' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='360zip'/>\n    <Guid>9179176e-b763-3200-8500-bb1b90b3d5de</Guid>\n    <FilePath>%AppData%\\360zip\\360zip_config.ini</FilePath>\n    <IsIniGroup/>\n    <Item>\n      <Text Value='层叠右键菜单'/>\n      <Rule Section='General' KeyName='CascadedMenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='智慧右键菜单'/>\n      <Rule Section='General' KeyName='CoolMenu' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压完成后打开目标文件夹'/>\n      <Rule Section='Profile.Extract.0' KeyName='OpenAfterExtract' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='解压完成后删除源文件'/>\n      <Rule Section='Profile.Extract.0' KeyName='DeleteSource' On='1' Off='0'/>\n    </Item>\n    <Item>\n      <Text Value='一键解压完成后自动关闭360压缩'/>\n      <Rule Section='General' KeyName='WiseExtract' On='1' Off='0'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='WPS云文档'/>\n    <Guid>67f4d210-bfc2-4add-9a2a-c9b9e1f42c4f</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\Kingsoft\\WPSCloud</RegPath>\n    <Item>\n      <Text Value='上传到\"WPS云文档\"'/>\n      <Rule ValueName='uploadFile' On='true' Off='false' ValueKind='REG_SZ'/>\n    </Item>\n    <Item>\n      <Text Value='发送到\"WPS云文档传输助手\"'/>\n      <Rule ValueName='fileTransfer' On='true' Off='false' ValueKind='REG_SZ'/>\n    </Item>\n    <Item>\n      <Text Value='通过\"WPS云文档\"分享和协作'/>\n      <Rule ValueName='shareFile' On='true' Off='false' ValueKind='REG_SZ'/>\n    </Item>\n    <Item>\n      <Text Value='同步桌面所有文件'/>\n      <Rule ValueName='DesktopSync' On='true' Off='false' ValueKind='REG_SZ'/>\n    </Item>\n  </Group>\n\n  <Group>\n    <Text Value='TC4Shell'/>\n    <Guid>00000000-b39d-4cb2-85f6-6e055d3b9a96</Guid>\n    <Guid>9ee0c3ef-c379-4fed-b2a8-651bb61f5c0f</Guid>\n    <Guid>9ee0c3ef-c379-4fed-b2a8-651bb61f5c0e</Guid>\n    <Guid>59624dcd-de34-4e3b-abe4-f40dafa1f2e0</Guid>\n    <RegPath>HKEY_CURRENT_USER\\SOFTWARE\\Dec Software\\TC4Shell</RegPath>\n    <Process Arguments='.\\,RunDll_Preferences'/>\n    <Item>\n      <Text Value='解压到(E)'/>\n      <Text Value='Extract to'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HideExtractMenu' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='解压到历史文件夹'/>\n      <Text Value='Extract to history folder'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HideExtractHistory' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='打开为文件夹'/>\n      <Text Value='Open as folder'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HideOpenAsFolder' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='压缩为(P)'/>\n      <Text Value='Pack to'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HidePackMenu' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='压缩并邮寄'/>\n      <Text Value='Pack to and email'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HidePackSendMenu' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='压缩到历史压缩包'/>\n      <Text Value='Pack to history archive'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HidePackHistory' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='属性对话框哈希选项卡'/>\n      <Text Value='Properties dialog hash tab'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HideHashTab' On='0' Off='1'/>\n    </Item>\n    <Item>\n      <Text Value='属性对话框导航选项卡'/>\n      <Text Value='Properties dialog navigation tab'>\n        <Culture>en-US</Culture>\n      </Text>\n      <Rule ValueName='HideNavTab' On='0' Off='1'/>\n    </Item>\n  </Group>\n</Data>"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/EnhanceMenusDic.xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--此文件为常用右键菜单字典, 可为此字典添加多语言翻译，添加一个Culture子项并设置为en-US、ja-JP等即可\nTip属性为鼠标悬浮在开关上时的提示信息，从每个Item节点开始, 子元素Value表示该项的注册表键值，目前仅支持REG_SZ、REG_DWORD、REG_EXPAND_SZ、REG_BINARY的键值类型，\n子元素SubKey的所有子元素是该项的子项，项名即为元素名; 每一Item项和SubKey的所有子元素的属性Default为该注册表项默认值，不放在Value\\REG_SZ元素里面是为了防止与可能存在的键名为Default的键产生冲突\n由于Shell项太过复杂，程序只根据注册表项名判断存在即启用，故同一场景下不允许有相同KeyName属性的Shell项目，ShellEx项只要Guid符合则为启用-->\n\n<Data>\n  <Group>\n    <Text Value='文件'/>\n    <Text Value='File'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-19</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\*</RegPath>\n    <Shell>\n      <Item KeyName='CopyContent'>\n        <Tip Value='不需打开文件直接复制文件文本内容&#x000A;非Unicode编码文件可能会乱码'/>\n        <Tip Value='You do not need to open the file directly copy the file text content, not Unicode encoding may be garbled'>\n          <Culture>en-US</Culture>\n        </Tip>\n        <Value>\n          <REG_SZ MUIVerb='复制内容到剪切板' Icon='DxpTaskSync.dll,-52'/>\n          <REG_SZ MUIVerb='Copy Content to Clipboard'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute WindowStyle='0'/>\n            <FileName>cmd.exe</FileName>\n            <Arguments>/c clip &lt; \"%1\"</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='TakeOwnerShip'>\n        <Value>\n          <REG_SZ MUIVerb='管理员取得所有权限' HasLUAShield='' NoWorkingDirectory=''/>\n          <REG_SZ MUIVerb='Take Ownership'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>takeown.exe</FileName>\n            <Arguments>/f \"%1\" /a</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='GetHash'>\n        <OSVersion Compare=\"&gt;=\">6.3</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='获取哈希值' Icon='imageres.dll,-5372'/>\n          <REG_SZ MUIVerb='Get Hash'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='open' WindowStyle='3'/>\n            <FileName>powershell.exe</FileName>\n            <Arguments>-noexit write-host '\"%1\"';$args = 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'mactripledes', 'ripemd160'; foreach($arg in $args){get-filehash '\"%1\"' -algorithm $arg | select-object algorithm, hash | format-table -wrap}</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='目录'/>\n    <Text Value='Directory'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-162</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\Directory</RegPath>\n    <Shell>\n      <Item KeyName='TakeOwnerShip'>\n        <Value>\n          <!--不包括回收站-->\n          <REG_SZ MUIVerb='管理员取得所有权限' HasLUAShield='' NoWorkingDirectory=''\n                  AppliesTo='System.ParsingName:&lt;>\"::{645FF040-5081-101B-9F08-00AA002F954E}\"'/>\n          <REG_SZ MUIVerb='Take Ownership'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>takeown.exe</FileName>\n            <Arguments>/f \"%v\" /a /r /d y</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='目录背景'/>\n    <Text Value='Background'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,0</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\Directory\\Background</RegPath>\n    <Shell>\n      <Item KeyName='Windows.NewFolder'>\n        <OSVersion Compare=\"&gt;=\">6.1</OSVersion>\n        <Value>\n          <!--新建文件夹-->\n          <REG_SZ MUIVerb='@shell32.dll,-31236' Icon='shell32.dll,-319' Position='top' CommandStateSync=''\n                  CommandStateHandler='{3756e7f5-e514-4776-a32b-eb24bc1efe7a}' CanonicalName='{E44616AD-6DF1-4B94-85A4-E465AE8A19DB}'/>\n          <REG_DWORD ImpliedSelectionModel='4' InvokeCommandOnSelection='0'/>\n        </Value>\n      </Item>\n      <Item KeyName='OpenNewWindow'>\n        <Value>\n          <!--在新窗口中打开-->\n          <REG_SZ MUIVerb='@windows.storage.dll,-8517'/>\n        </Value>\n        <SubKey>\n          <Command Default='explorer.exe \"%v\"'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='Windows.RecycleBin.Empty'>\n        <OSVersion Compare=\"&gt;=\">6.1</OSVersion>\n        <Value>\n          <!--清空回收站-->\n          <REG_SZ MUIVerb='@shell32.dll,-10564' Icon='imageres.dll,-54' CommandStateHandler='{c9298eef-69dd-4cdd-b153-bdbc38486781}'/>\n        </Value>\n        <SubKey>\n          <Command>\n            <Value>\n              <REG_SZ DelegateExecute='{48527bb3-e8de-450b-8910-8c4099cb8624}'/>\n            </Value>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='SuperHidden'>\n        <Value>\n          <REG_SZ MUIVerb='超级隐藏' SubCommands='' Position='bottom'/>\n          <REG_SZ MUIVerb='Super Hidden'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n          <REG_SZ Icon='imageres.dll,-5314'>\n            <OSVersion Compare=\"&gt;=\">6.2</OSVersion>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <OSVersion Compare=\"&gt;=\">6.2</OSVersion>\n                <Value>\n                  <REG_SZ MUIVerb='显示/隐藏 扩展名' CommandStateSync=''\n                          ExplorerCommandHandler='{4ac6c205-2853-4bf5-b47c-919a42a48a16}'/>\n                  <REG_SZ MUIVerb='Show or Hide File Extensions'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n              </Item0>\n              <Item1>\n                <OSVersion Compare=\"&gt;=\">6.2</OSVersion>\n                <Value>\n                  <REG_SZ MUIVerb='显示/隐藏 隐藏文件' CommandStateSync=''\n                          ExplorerCommandHandler='{f7300245-1f4b-41ba-8948-6fd392064494}'/>\n                  <REG_SZ MUIVerb='Show or Hide Hidden Files'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n              </Item1>\n              <Item0>\n                <OSVersion Compare=\"&lt;\">6.2</OSVersion>\n                <Value>\n                  <REG_SZ MUIVerb='显示/隐藏 扩展名'/>\n                  <REG_SZ MUIVerb='Show or Hide File Extensions'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <FileName>wscript.exe</FileName>\n                    <Arguments>\n                      <CreateFile\n                        FileName='ShowFileExtensions.vbs'\n                        Content='\n                        Dim wsh\n                        On Error Resume Next\n                        Set wsh = CreateObject(\"WScript.Shell\")\n                        path = \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\HideFileExt\"\n                        value = 1\n                        If wsh.RegRead(path) = value Then value = 0\n                        wsh.RegWrite path, value, \"REG_DWORD\"\n                        wsh.SendKeys \"{F5}\"\n                        Set wsh = Nothing'/>\n                    </Arguments>\n                  </Command>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <OSVersion Compare=\"&lt;\">6.2</OSVersion>\n                <Value>\n                  <REG_SZ MUIVerb='显示/隐藏 隐藏文件'/>\n                  <REG_SZ MUIVerb='Show or Hide Hidden Files'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <FileName>wscript.exe</FileName>\n                    <Arguments>\n                      <CreateFile\n                        FileName='ShowHiddenFiles.vbs'\n                        Content='\n                        Dim wsh\n                        On Error Resume Next\n                        Set wsh = CreateObject(\"WScript.Shell\")\n                        path = \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Hidden\"\n                        value = 1\n                        If wsh.RegRead(path) = value Then value = 2\n                        wsh.RegWrite path, value, \"REG_DWORD\"\n                        wsh.SendKeys \"{F5}\"\n                        Set wsh = Nothing'/>\n                    </Arguments>\n                  </Command>\n                </SubKey>\n              </Item1>\n              <Item2>\n                <Value>\n                  <REG_SZ MUIVerb='显示/隐藏 系统隐藏文件'/>\n                  <REG_SZ MUIVerb='Show or Hide Hidden System Files'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <FileName>wscript.exe</FileName>\n                    <Arguments>\n                      <CreateFile\n                        FileName='ShowSuperHidden.vbs'\n                        Content='\n                        Dim wsh\n                        On Error Resume Next\n                        Set wsh = CreateObject(\"WScript.Shell\")\n                        path = \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\ShowSuperHidden\"\n                        value = 1\n                        If wsh.RegRead(path) = value Then value = 0\n                        wsh.RegWrite path, value, \"REG_DWORD\"\n                        wsh.SendKeys \"{F5}\"\n                        Set wsh = Nothing'/>\n                    </Arguments>\n                  </Command>\n                </SubKey>\n              </Item2>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n      <Item KeyName='RunasCmd'>\n        <Value>\n          <!--以管理员身份打开命令提示符-->\n          <REG_SZ MUIVerb='@shell32.dll,-37444' Icon='imageres.dll,-5324' NoWorkingDirectory=''/>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas'/>\n            <FileName>cmd.exe</FileName>\n            <Arguments>/s /k pushd \"%v\"</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='Windows.PowershellAsAdmin'>\n        <Value>\n          <!--以管理员身份打开Powershell-->\n          <REG_SZ MUIVerb='@shell32.dll,-37448' Icon='imageres.dll,-5373' Description='@shell32.dll,-37449' CommandStateSync=''\n                  CanonicalName='{ADB73FFC-1568-4D7D-BCD5-6D11A417AF64}' ExplorerCommandHandler='{BF0AC53F-D51C-419F-92E3-2298E125F004}'/>\n          <REG_DWORD ImpliedSelectionModel='1' ResolveLinksInvokeBehavior='3' ResolveLinksQueryBehavior='0'/>\n        </Value>\n      </Item>\n      <Item KeyName='ExplorerUWP'>\n        <OSVersion Compare=\"&gt;=\">10.0</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='资源管理器 UWP' Icon='explorer.exe,0'/>\n          <REG_SZ MUIVerb='Explorer UWP'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='explorer shell:AppsFolder\\c5e2524a-ea46-4f67-841f-6a9465d9d515_cw5n1h2txyewy!App'/>\n        </SubKey>\n      </Item>\n    </Shell>\n    <ShellEx>\n      <Item>\n        <!--窗口转换程序-->\n        <Text>@shell32.dll,-12715</Text>\n        <Icon>imageres.dll,0</Icon>\n        <KeyName>Flip3D</KeyName>\n        <Guid>3080f90e-d7ad-11d9-bd98-0000947b0257</Guid>\n      </Item>\n    </ShellEx>\n  </Group>\n\n  <Group>\n    <Text Value='桌面背景'/>\n    <Text Value='Desktop Background'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-183</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\DesktopBackground</RegPath>\n    <Shell>\n      <Item KeyName='OpenThisPC'>\n        <Value>\n          <!--此电脑-->\n          <REG_SZ MUIVerb='@shell32.dll,-9216' Icon='imageres.dll,-109'/>\n        </Value>\n        <SubKey>\n          <Command Default='explorer /e,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='OpenControlPanel'>\n        <Value>\n          <!--控制面板-->\n          <REG_SZ MUIVerb='@shell32.dll,-4161' Icon='imageres.dll,-27'/>\n        </Value>\n        <SubKey>\n          <Command Default='control.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='RestartExplorer'>\n        <Value>\n          <REG_SZ MUIVerb='重启资源管理器' Icon='shell32.dll,238'/>\n          <REG_SZ MUIVerb='Restart Explorer'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute WindowStyle='0'/>\n            <FileName>cmd.exe</FileName>\n            <Arguments>/c taskkill /f /im explorer.exe &amp; start explorer.exe</Arguments>\n          </Command>\n          <Command>\n            <ShellExecute WindowStyle='0'/>\n            <FileName>tskill.exe</FileName>\n            <Arguments>explorer</Arguments>\n            <FileExists>%SystemRoot%\\System32\\tskill.exe</FileExists>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='OpenMoreRegedit'>\n        <Value>\n          <REG_SZ MUIVerb='多开注册表编辑器' Icon='regedit.exe,0'/>\n          <REG_SZ MUIVerb='Open Multiple Regedit'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='regedit -m'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='SnippingTool'>\n        <OSVersion Compare=\"&gt;=\">6.1</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='截图工具' Icon='snippingTool.exe,0'/>\n          <REG_SZ MUIVerb='Snipping Tool'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='snippingTool.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='SnipToClipboard'>\n        <Tip Value='截屏后可直接Ctrl+V粘贴图片&#x000A;适用位置:Word、QQ、PS等&#x000A;快捷键:Win+Shift+S'/>\n        <Tip Value='After taking a screenshot, you can directly press Ctrl+V to paste the picture.&#x000A;It is suitable for Word, PS and other programs. The shortcut key is Win+Shift+S'>\n          <Culture>en-US</Culture>\n        </Tip>\n        <OSVersion Compare=\"&gt;=\">10.0</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='截屏到剪贴板' Icon='snippingTool.exe,0'/>\n          <REG_SZ MUIVerb='Snip to Clipboard'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='explorer ms-screenclip:'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='ScreenKeyboard'>\n        <Value>\n          <REG_SZ MUIVerb='屏幕键盘' Icon='osk.exe,0'/>\n          <REG_SZ MUIVerb='Screen Keyboard'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='osk.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='ShutdownOptions'>\n        <Value>\n          <REG_SZ MUIVerb='关机选项' Icon='shell32.dll,-28' SubCommands='' Position='bottom'/>\n          <REG_SZ MUIVerb='Shutdown Options'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='锁定'/>\n                  <REG_SZ MUIVerb='Lock'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='rundll32 user32.dll,LockWorkStation'/>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='注销'/>\n                  <REG_SZ MUIVerb='Log off'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='shutdown -l'/>\n                </SubKey>\n              </Item1>\n              <Item2>\n                <Value>\n                  <REG_SZ MUIVerb='切换账户'/>\n                  <REG_SZ MUIVerb='Switch account'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='tsdiscon'/>\n                </SubKey>\n              </Item2>\n              <Item3>\n                <Value>\n                  <REG_SZ MUIVerb='睡眠'/>\n                  <REG_SZ MUIVerb='Sleep'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='rundll32 powrprof.dll,SetSuspendState Sleep'/>\n                </SubKey>\n              </Item3>\n              <Item4>\n                <Value>\n                  <REG_SZ MUIVerb='休眠'/>\n                  <REG_SZ MUIVerb='Hibernate'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='shutdown -h'/>\n                </SubKey>\n              </Item4>\n              <Item5>\n                <Value>\n                  <REG_SZ MUIVerb='重启'/>\n                  <REG_SZ MUIVerb='Restart'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='shutdown -r -f -t 00'/>\n                </SubKey>\n              </Item5>\n              <Item6>\n                <Value>\n                  <REG_SZ MUIVerb='关机'/>\n                  <REG_SZ MUIVerb='Shutdown'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='shutdown -s -f -t 00'/>\n                </SubKey>\n              </Item6>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n      <Item KeyName='SlideToShutDown'>\n        <OSVersion Compare=\"&gt;=\">6.3</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='滑动关机' Icon='shell32.dll,-28'/>\n          <REG_SZ MUIVerb='Slide to ShutDown'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='SlideToShutDown.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='PowerPlan'>\n        <Value>\n          <REG_SZ MUIVerb='电源计划' Icon='powercpl.dll,0' SubCommands='' Position='bottom'/>\n          <REG_SZ MUIVerb='Power Plan'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='节能'/>\n                  <REG_SZ MUIVerb='Power saver'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute WindowStyle='0'/>\n                    <FileName>powercfg.exe</FileName>\n                    <Arguments>/setactive a1841308-3541-4fab-bc81-f71556f20b4a</Arguments>\n                  </Command>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='平衡'/>\n                  <REG_SZ MUIVerb='Balanced'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute WindowStyle='0'/>\n                    <FileName>powercfg.exe</FileName>\n                    <Arguments>/setactive 381b4222-f694-41f0-9685-ff5bb260df2e</Arguments>\n                  </Command>\n                </SubKey>\n              </Item1>\n              <Item2>\n                <Value>\n                  <REG_SZ MUIVerb='高性能'/>\n                  <REG_SZ MUIVerb='High performance'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute WindowStyle='0'/>\n                    <FileName>powercfg.exe</FileName>\n                    <Arguments>/setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c</Arguments>\n                  </Command>\n                </SubKey>\n              </Item2>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n      <Item KeyName='AppColorMode'>\n        <OSVersion Compare=\"&gt;=\">10.0.17763</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='颜色模式' Icon='themecpl.dll,-1' SubCommands='' Position='bottom'/>\n          <REG_SZ MUIVerb='App Color Mode'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='浅色应用' Icon='imageres.dll,-5411'/>\n                  <REG_SZ MUIVerb='Light Mode'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='Reg Add HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize /v AppsUseLightTheme /t REG_DWORD /d 1 /f'/>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='深色应用' Icon='imageres.dll,-5412'/>\n                  <REG_SZ MUIVerb='Dark Mode'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='Reg Add HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize /v AppsUseLightTheme /t REG_DWORD /d 0 /f'/>\n                </SubKey>\n              </Item1>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n      <Item KeyName='WallPaperLocation'>\n        <Value>\n          <REG_SZ MUIVerb='壁纸位置' Icon='imageres.dll,-5346' Position='bottom'/>\n          <REG_SZ MUIVerb='WallPaper Location'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <FileName>wscript.exe</FileName>\n            <Arguments>\n              <CreateFile\n                FileName='WallPaperLocation.vbs'\n                Content='\n                Dim wsh\n                On Error Resume Next\n                Set wsh = CreateObject(\"WScript.Shell\")\n                path = wsh.RegRead(\"HKCU\\Control Panel\\Desktop\\WallPaper\")\n                wsh.Run(\"explorer /select, \" &amp; path)\n                Set wsh = Nothing'/>\n            </Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='DesktopIcon'>\n        <Value>\n          <REG_SZ MUIVerb='桌面图标设置' Icon='desk.cpl,0'/>\n          <REG_SZ MUIVerb='Desktop Icon Settings'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='control desk.cpl,,0'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='ScreenSaver'>\n        <Value>\n          <REG_SZ MUIVerb='屏幕保护设置' Icon='desk.cpl,0'/>\n          <REG_SZ MUIVerb='Screen saver Settings'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='control desk.cpl,,1'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='WebSearch'>\n        <Value>\n          <REG_SZ MUIVerb='网页搜索' Icon='Windows.Storage.Search.dll,0' SubCommands=''/>\n          <REG_SZ MUIVerb='Web Search'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='Bing'/>\n                </Value>\n                <SubKey>\n                  <Command Default='explorer \"https://www.bing.com\"'/>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='Baidu'/>\n                </Value>\n                <SubKey>\n                  <Command Default='explorer \"https://www.baidu.com\"'/>\n                </SubKey>\n              </Item1>\n              <Item2>\n                <Value>\n                  <REG_SZ MUIVerb='Google'/>\n                </Value>\n                <SubKey>\n                  <Command Default='explorer \"https://www.google.com\"'/>\n                </SubKey>\n              </Item2>\n              <Item3>\n                <Value>\n                  <REG_SZ MUIVerb='Yandex'/>\n                </Value>\n                <SubKey>\n                  <Command Default='explorer \"https://yandex.com\"'/>\n                </SubKey>\n              </Item3>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='磁盘分区'/>\n    <Text Value='Drive'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-30</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\Drive</RegPath>\n    <Shell>\n      <Item KeyName='OptimizeDrives'>\n        <Value>\n          <!--优化驱动器-->\n          <REG_SZ MUIVerb='@dfrgui.exe,-106' Icon='dfrgui.exe,0'/>\n        </Value>\n        <SubKey>\n          <Command Default='dfrgui.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='Windows.CleanUp'>\n        <Value>\n          <!--磁盘清理-->\n          <REG_SZ MUIVerb='@shell32.dll,-22026' Icon='cleanmgr.exe,-104' CommandStateSync=''\n                  ExplorerCommandHandler='{9cca66bb-9c78-4e59-a76f-a5e9990b8aa0}'/>\n          <REG_DWORD ImpliedSelectionModel='0x1'/>\n        </Value>\n      </Item>\n      <Item KeyName='ShowDriveLetters'>\n        <Value>\n          <REG_SZ MUIVerb='显示/隐藏 盘符' Position='bottom'/>\n          <REG_SZ MUIVerb='Show or hide Drive Letters'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <FileName>Wscript.exe</FileName>\n            <Arguments>\n              <CreateFile\n                FileName='ShowDriveLetters.vbs'\n                Content='\n                Dim wsh\n                On Error Resume Next\n                Set wsh = CreateObject(\"WScript.Shell\")\n                path = \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShowDriveLettersFirst\"\n                value = 2\n                If wsh.RegRead(path) = value Then value = 0\n                wsh.RegWrite path, value, \"REG_DWORD\"\n                wsh.SendKeys \"{F5}\"\n                Set wsh = Nothing'/>\n            </Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='ShowVolumeStrips'>\n        <Value>\n          <REG_SZ MUIVerb='显示/隐藏 容量条' Position='bottom'/>\n          <REG_SZ MUIVerb='Show or hide Drive Volume'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas'/>\n            <FileName>Wscript.exe</FileName>\n            <Arguments>\n              <CreateFile\n                FileName='ShowVolumeStrips.vbs'\n                Content='\n                Dim wsh\n                On Error Resume Next\n                Set wsh = CreateObject(\"WScript.Shell\")\n                path = \"HKLM\\SOFTWARE\\Classes\\Drive\\TileInfo\"\n                value = \"prop:*System.PercentFull;System.Computer.DecoratedFreeSpace;System.Volume.FileSystem\"\n                If wsh.RegRead(path) = value Then\n                    value = \"prop:System.FreeSpace;System.Capacity\"\n                End If\n                wsh.RegWrite path, value\n                wsh.SendKeys \"{F5}\"\n                Set wsh = Nothing'/>\n            </Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='所有对象'/>\n    <Text Value='All File system Objects'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-117</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\AllFilesystemObjects</RegPath>\n    <Shell>\n      <Item KeyName='Windows.PermanentDelete'>\n        <OSVersion Compare=\"&gt;=\">6.2</OSVersion>\n        <Value>\n          <!--永久删除-->\n          <REG_SZ MUIVerb='@shell32.dll,-37394' Icon='shell32.dll,-240' Position='bottom' CommandStateSync=''\n                  ExplorerCommandHandler='{E9571AB2-AD92-4ec6-8924-4E5AD33790F5}'/>\n        </Value>\n      </Item>\n      <Item KeyName='CopyAsPath'>\n        <Tip Value='系统原生菜单项需按住Shift显示,&#x000A;此项可以直接显示, 路径不带双引号'/>\n        <Tip Value='The system raw lettuce item needs to hold down Shift display,&#x000A;this item can be displayed directly, path without double quotation marks'>\n          <Culture>en-US</Culture>\n        </Tip>\n        <Value>\n          <!--复制路径-->\n          <REG_SZ MUIVerb='@shell32.dll,-30329' Icon='imageres.dll,-5302'/>\n        </Value>\n        <SubKey>\n          <Command Default='mshta vbscript:clipboarddata.setdata(\"text\",\"%1\")(close)'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='Windows.CopyAsPath'>\n        <OSVersion Compare=\"&gt;=\">6.2</OSVersion>\n        <Tip Value='系统原生菜单项需按住Shift显示,&#x000A;此项可以直接显示, 路径带双引号'/>\n        <Tip Value='The system raw lettuce item needs to hold down Shift display,&#x000A;this item can be displayed directly, path with double quotation marks'>\n          <Culture>en-US</Culture>\n        </Tip>\n        <Value>\n          <!--复制路径-->\n          <REG_SZ MUIVerb='@shell32.dll,-30329' Icon='imageres.dll,-5302' CommandStateHandler='{3B1599F9-E00A-4BBF-AD3E-B3F99FA87779}'\n                  CanonicalName='{707C7BC6-685A-4A4D-A275-3966A5A3EFAA}' CommandStateSync='' VerbHandler='{f3d06e7c-1e45-4a26-847e-f9fcdee59be0}'\n                  VerbName='copyaspath' Description='@shell32.dll,-30336'/>\n          <REG_DWORD InvokeCommandOnSelection='1'/>\n        </Value>\n      </Item>\n      <Item KeyName='Windows.SlideShow'>\n        <Value>\n          <!--幻灯片放映-->\n          <REG_SZ MUIVerb='@shell32.dll,-31287' Icon='imageres.dll,-5347' CommandStateHandler='{880ac964-2e34-4425-8cf2-86ada2c3a019}'\n                  CanonicalName='{73BCE053-3BBC-4AD7-9FE7-7A7C212C98E6}' CommandStateSync='' Description='@shell32.dll,-31288' VerbToInvoke='slideshow'/>\n          <REG_DWORD MediaTypeFlags='5'/>\n        </Value>\n        <SubKey>\n          <Command>\n            <Value>\n              <REG_SZ DelegateExecute='{80c68d96-366b-11dc-9eaa-00161718cf63}'/>\n            </Value>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='HideAttributes'>\n        <Value>\n          <REG_SZ MUIVerb='隐藏属性' SubCommands='' Position='bottom'/>\n          <REG_SZ MUIVerb='File Visibility'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n          <REG_SZ Icon='imageres.dll,-5314'>\n            <OSVersion Compare=\"&gt;=\">6.2</OSVersion>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='显示'/>\n                  <REG_SZ MUIVerb='Normal'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='attrib -s -h \"%1\"'/>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='隐藏'/>\n                  <REG_SZ MUIVerb='Hidden'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='attrib -s +h \"%1\"'/>\n                </SubKey>\n              </Item1>\n              <Item2>\n                <Value>\n                  <REG_SZ MUIVerb='系统隐藏'/>\n                  <REG_SZ MUIVerb='System Hidden'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command Default='attrib +s +h \"%1\"'/>\n                </SubKey>\n              </Item2>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n      <Item KeyName='CreateDesktopShortcut'>\n        <Value>\n          <REG_SZ MUIVerb='创建桌面快捷方式' Icon='imageres.dll,-110' Position='bottom'/>\n          <REG_SZ MUIVerb='Create a Desktop Shortcut'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <FileName>Wscript.exe</FileName>\n            <Arguments Suffix=' \"%1\"'>\n              <CreateFile\n                FileName='CreateDesktopShortcut.vbs'\n                Content='\n                Dim wsh, fso, shortcut\n                Set paths = WScript.Arguments\n                Set wsh = CreateObject(\"WScript.Shell\")\n                Set fso = CreateObject(\"Scripting.FileSystemObject\")\n                desktop = wsh.SpecialFolders(\"Desktop\")\n                For i = 0 To paths.Count - 1\n\t              path = paths(i)\n\t              index1 = InstrRev(path, \"\\\")\n\t              dir = Mid(path, 1, index1 - 1)\n\t              name = Mid(path, index1 + 1)\n\t              index2 = InstrRev(name, \".\")\n\t              If index2 > 0 Then name = Mid(name, 1, index2 - 1)\n\t              lnkPath = \"\"\n\t              j = 1\n\t              Do\n\t                  lnkPath = desktop &amp; \"\\\" &amp; name\n\t                  If j > 1 Then lnkPath = lnkPath &amp; \" (\" &amp; j &amp; \")\"\n\t                  lnkPath = lnkPath &amp; \".lnk\"\n\t                  j = j + 1\n\t              Loop While fso.FileExists(lnkPath)\n\t              Set shortcut = wsh.CreateShortcut(lnkPath)  \n\t              shortcut.TargetPath = path \n\t              shortcut.WorkingDirectory = dir\n\t              shortcut.Save\n                Next\n                Set shortcut = Nothing\n                Set wsh = Nothing\n                Set fso = Nothing'/>\n            </Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n    <ShellEx>\n      <Item>\n        <!--复制到文件夹-->\n        <Text>@shell32.dll,-30304</Text>\n        <Icon>imageres.dll,-5304</Icon>\n        <KeyName>CopyTo</KeyName>\n        <Guid>c2fbb630-2971-11d1-a18c-00c04fd75d13</Guid>\n      </Item>\n      <Item>\n        <!--移动到文件夹-->\n        <Text>@shell32.dll,-30305</Text>\n        <Icon>imageres.dll,-5303</Icon>\n        <KeyName>MoveTo</KeyName>\n        <Guid>c2fbb631-2971-11d1-a18c-00c04fd75d13</Guid>\n      </Item>\n    </ShellEx>\n  </Group>\n\n  <Group>\n    <Text Value='此电脑'/>\n    <Text Value='This PC'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-109</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}</RegPath>\n    <Shell>\n      <Item KeyName='SystemInfo'>\n        <Value>\n          <REG_SZ MUIVerb='系统信息' Icon='msinfo32.exe,0'/>\n          <REG_SZ MUIVerb='System Info'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='msinfo32.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='UserAccountControlSettings'>\n        <Value>\n          <REG_SZ MUIVerb='用户账户控制设置'/>\n          <REG_SZ MUIVerb='User Account Control Settings'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='UserAccountControlSettings.exe'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='Gpedit'>\n        <FileExists>%SystemRoot%\\System32\\gpedit.msc</FileExists>\n        <Value>\n          <REG_SZ MUIVerb='组策略编辑器'/>\n          <REG_SZ MUIVerb='Group Policy Editor'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='mmc.exe gpedit.msc'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='VirtualMode'>\n        <Tip Value='解决 Hyper-V 和 VirtualBox 不能共存的问题'/>\n        <Tip Value='Fixed an issue where Hyper-V and VirtualBox could not coexist'>\n          <Culture>en-US</Culture>\n        </Tip>\n        <OSVersion Compare=\"&gt;=\">10.0</OSVersion>\n        <Value>\n          <REG_SZ MUIVerb='虚拟模式' Icon='imageres.dll,-109' SubCommands='' Position='bottom'/>\n          <REG_SZ MUIVerb='Virtual Mode'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='Hyper-V'/>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <FileName>wscript.exe</FileName>\n                    <Arguments>\n                      <CreateFile\n                        FileName='HyperVMode.vbs'\n                        Content='\n                        Dim sap, wsh\n                        Set sap = CreateObject(\"Shell.Application\")\n                        sap.ShellExecute \"bcdedit\", \"/set hypervisorlaunchtype auto\", \"\" ,\"runas\", 0\n                        msg = \"你当前切换的模式为 Hyper-V，\" &amp; VbCrlf\n                        msg = msg &amp; \"该模式可使用 Windows SandBox 和 Hyper-V，\" &amp; VbCrlf\n                        msg = msg &amp; \"不可使用 VirtualBox 和 VMware 等虚拟机程序，\" &amp; VbCrlf\n                        msg = msg &amp; \"是否立即重启计算机应用该模式？\" &amp; VbCrlf\n                        msg = msg &amp; \"你也可稍后自行重启，请保存好工作！\"\n                        If Msgbox(msg, VbYesNo + VbInformation, \"虚拟模式\") = VbYes Then\n                            Set wsh = CreateObject(\"WScript.Shell\")\n                            wsh.Run(\"shutdown -r -f -t 00\")\n                            Set wsh = Nothing\n                        End If\n                        Set sap = Nothing'/>\n                      <CreateFile\n                        FileName='HyperVMode.vbs'\n                        Content='\n                        Dim sap, wsh\n                        Set sap = CreateObject(\"Shell.Application\")\n                        sap.ShellExecute \"bcdedit\", \"/set hypervisorlaunchtype auto\", \"\" ,\"runas\", 0\n                        msg = \"You are currently switching mode to Hyper-V,\" &amp; VbCrlf\n                        msg = msg &amp; \"This mode is available using Windows SandBox and Hyper-V,\" &amp; VbCrlf\n                        msg = msg &amp; \"But Vm programs such as VirtualBox and VMware cannot be used,\" &amp; VbCrlf\n                        msg = msg &amp; \"Do you want to restart the computer immediately to apply the mode?\" &amp; VbCrlf\n                        msg = msg &amp; \"You can also restart yourself later, please save your work!\"\n                        If Msgbox(msg, VbYesNo + VbInformation, \"Virtual Mode\") = VbYes Then\n                            Set wsh = CreateObject(\"WScript.Shell\")\n                            wsh.Run(\"shutdown -r -f -t 00\")\n                            Set wsh = Nothing\n                        End If\n                        Set sap = Nothing'>\n                        <Culture>en-US</Culture>\n                      </CreateFile>\n                    </Arguments>\n                  </Command>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='VirtualBox'/>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <FileName>wscript.exe</FileName>\n                    <Arguments>\n                      <CreateFile\n                        FileName='VirtualBoxMode.vbs'\n                        Content='\n                        Dim sap, wsh\n                        Set sap = CreateObject(\"Shell.Application\")\n                        sap.ShellExecute \"bcdedit\", \"/set hypervisorlaunchtype off\", \"\", \"runas\", 0\n                        msg = \"你当前切换的模式为 VirtualBox，\" &amp; VbCrlf\n                        msg = msg &amp; \"该模式可使用 VirtualBox 和 VMware 等虚拟机程序，\" &amp; VbCrlf\n                        msg = msg &amp; \"不可使用 Windows SandBox 和 Hyper-V，\" &amp; VbCrlf\n                        msg = msg &amp; \"是否立即重启计算机应用该模式？\" &amp; VbCrlf\n                        msg = msg &amp; \"你也可稍后自行重启，请保存好工作！\"\n                        If Msgbox(msg, VbYesNo + VbInformation, \"虚拟模式\") = VbYes Then\n                            Set wsh = CreateObject(\"WScript.Shell\")\n                            wsh.Run(\"shutdown -r -f -t 00\")\n                            Set wsh = Nothing\n                        End If\n                        Set sap = Nothing'/>\n                      <CreateFile\n                        FileName='VirtualBoxMode.vbs'\n                        Content='\n                        Dim sap, wsh\n                        Set sap = CreateObject(\"Shell.Application\")\n                        sap.ShellExecute \"bcdedit\", \"/set hypervisorlaunchtype off\", \"\", \"runas\", 0\n                        msg = \"You are currently switching mode to VirtualBox，\" &amp; VbCrlf\n                        msg = msg &amp; \"This mode is available using VM programs such as VirtualBox and VMware,\" &amp; VbCrlf\n                        msg = msg &amp; \"But Windows SandBox and Hyper-V are not available,\" &amp; VbCrlf\n                        msg = msg &amp; \"Do you want to restart the computer immediately to apply the mode?\" &amp; VbCrlf\n                        msg = msg &amp; \"You can also restart yourself later, please save your work!\"\n                        If Msgbox(msg, VbYesNo + VbInformation, \"Virtual Mode\") = VbYes Then\n                            Set wsh = CreateObject(\"WScript.Shell\")\n                            wsh.Run(\"shutdown -r -f -t 00\")\n                            Set wsh = Nothing\n                        End If\n                        Set sap = Nothing'>\n                        <Culture>en-US</Culture>\n                      </CreateFile>\n                    </Arguments>\n                  </Command>\n                </SubKey>\n              </Item1>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n      <Item KeyName='EditHosts'>\n        <Value>\n          <REG_SZ MUIVerb='编辑 Hosts'/>\n          <REG_SZ MUIVerb='Edit Hosts'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas'/>\n            <FileName>notepad.exe</FileName>\n            <Arguments>%systemroot%\\system32\\drivers\\etc\\hosts</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='FlushDNS'>\n        <Value>\n          <REG_SZ MUIVerb='刷新DNS缓存' Icon='shell32.dll,238'/>\n          <REG_SZ MUIVerb='Flush DNS'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command Default='ipconfig /flushdns'/>\n        </SubKey>\n      </Item>\n      <Item KeyName='BatteryReport'>\n        <Value>\n          <OSVersion Compare=\"&gt;=\">10.0</OSVersion>\n          <REG_SZ MUIVerb='电池使用报告' Icon='powercpl.dll,0'/>\n          <REG_SZ MUIVerb='Battery Report'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute WindowStyle='0'/>\n            <FileName>cmd.exe</FileName>\n            <Arguments>/c cd %temp% &amp; del BatteryReport.html &amp; powercfg /batteryreport /output BatteryReport.html &amp; start BatteryReport.html</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='回收站'/>\n    <Text Value='RecycleBin'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-55</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}</RegPath>\n    <Shell>\n      <Item KeyName='CleanThumbCache'>\n        <Value>\n          <REG_SZ MUIVerb='清理缩略图缓存'/>\n          <REG_SZ MUIVerb='Clean Thumb Cache'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>\n              <CreateFile\n                FileName='CleanThumbCache.bat'\n                Content='\n                taskkill /f /im explorer.exe\n                del /f /s /q /a \"%LocalAppData%\\IconCache.db\"\n                cd /d \"%LocalAppData%\\Microsoft\\Windows\\Explorer\"\n                del /f /s /q /a thumbcache_*.db\n                del /f /s /q /a iconcache_*.db\n                reg delete \"HKCR\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotify\" /v IconStreams /f\n                reg delete \"HKCR\\Local Settings\\Software\\Microsoft\\Windows\\CurrentVersion\\TrayNotify\" /v PastIconsStream /f\n                start explorer'/>\n            </FileName>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='Exe文件'/>\n    <Text Value='Exe Files'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-15</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\SystemFileAssociations\\.exe</RegPath>\n    <Shell>\n      <Item KeyName='FirewallRules'>\n        <Value>\n          <REG_SZ MUIVerb='防火墙规则' Icon='FirewallControlPanel.dll,0' SubCommands=''/>\n          <REG_SZ MUIVerb='Firewall Rules'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Shell>\n            <SubKey>\n              <Item0>\n                <Value>\n                  <REG_SZ MUIVerb='禁止入站' Icon='imageres.dll,-105'/>\n                  <REG_SZ MUIVerb='Not Allow In'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute Verb='runas' WindowStyle='0'/>\n                    <FileName>cmd.exe</FileName>\n                    <Arguments>/R (netsh advfirewall firewall delete rule name=\"_%1\" dir=in program=\"%1\" &amp; netsh advfirewall firewall add rule name=\"_%1\" dir=in program=\"%1\" action=block)</Arguments>\n                  </Command>\n                </SubKey>\n              </Item0>\n              <Item1>\n                <Value>\n                  <REG_SZ MUIVerb='禁止出站' Icon='imageres.dll,-105'/>\n                  <REG_SZ MUIVerb='Not Allow Out'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute Verb='runas' WindowStyle='0'/>\n                    <FileName>cmd.exe</FileName>\n                    <Arguments>/R (netsh advfirewall firewall delete rule name=\"_%1\" dir=out program=\"%1\" &amp; netsh advfirewall firewall add rule name=\"_%1\" dir=out program=\"%1\" action=block)</Arguments>\n                  </Command>\n                </SubKey>\n              </Item1>\n              <Item2>\n                <Value>\n                  <REG_SZ MUIVerb='允许入站' Icon='imageres.dll,-106'/>\n                  <REG_SZ MUIVerb='Allow In'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute Verb='runas' WindowStyle='0'/>\n                    <FileName>cmd.exe</FileName>\n                    <Arguments>/R (netsh advfirewall firewall delete rule name=\"_%1\" dir=in program=\"%1\" &amp; netsh advfirewall firewall add rule name=\"_%1\" dir=in program=\"%1\" action=allow)</Arguments>\n                  </Command>\n                </SubKey>\n              </Item2>\n              <Item3>\n                <Value>\n                  <REG_SZ MUIVerb='允许出站' Icon='imageres.dll,-106'/>\n                  <REG_SZ MUIVerb='Allow Out'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute Verb='runas' WindowStyle='0'/>\n                    <FileName>cmd.exe</FileName>\n                    <Arguments>/R (netsh advfirewall firewall delete rule name=\"_%1\" dir=out program=\"%1\" &amp; netsh advfirewall firewall add rule name=\"_%1\" dir=out program=\"%1\" action=allow)</Arguments>\n                  </Command>\n                </SubKey>\n              </Item3>\n              <Item4>\n                <Value>\n                  <REG_SZ MUIVerb='清除设置' Icon='imageres.dll,-107'/>\n                  <REG_SZ MUIVerb='Clear Settings'>\n                    <Culture>en-US</Culture>\n                  </REG_SZ>\n                </Value>\n                <SubKey>\n                  <Command>\n                    <ShellExecute Verb='runas' WindowStyle='0'/>\n                    <FileName>cmd.exe</FileName>\n                    <Arguments>/R (netsh advfirewall firewall delete rule name=\"_%1\" program=\"%1\")</Arguments>\n                  </Command>\n                </SubKey>\n              </Item4>\n            </SubKey>\n          </Shell>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='DLL文件'/>\n    <Text Value='DLL Files'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-67</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\SystemFileAssociations\\.dll</RegPath>\n    <Shell>\n      <Item KeyName='Register'>\n        <Value>\n          <REG_SZ MUIVerb='注册 DLL'/>\n          <REG_SZ MUIVerb='Register the DLL'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>regsvr32.exe</FileName>\n            <Arguments>\"%1\"</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='UnRegister'>\n        <Value>\n          <REG_SZ MUIVerb='注销 DLL'/>\n          <REG_SZ MUIVerb='UnRegister the DLL'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>regsvr32.exe</FileName>\n            <Arguments>/u \"%1\"</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n\n  <Group>\n    <Text Value='OCX文件'/>\n    <Text Value='OCX Files'>\n      <Culture>en-US</Culture>\n    </Text>\n    <Icon>imageres.dll,-67</Icon>\n    <RegPath>HKEY_CLASSES_ROOT\\SystemFileAssociations\\.ocx</RegPath>\n    <Shell>\n      <Item KeyName='Register'>\n        <Value>\n          <REG_SZ MUIVerb='注册 OCX'/>\n          <REG_SZ MUIVerb='Register the OCX'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>regsvr32.exe</FileName>\n            <Arguments>\"%1\"</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n      <Item KeyName='UnRegister'>\n        <Value>\n          <REG_SZ MUIVerb='注销 OCX'/>\n          <REG_SZ MUIVerb='UnRegister the OCX'>\n            <Culture>en-US</Culture>\n          </REG_SZ>\n        </Value>\n        <SubKey>\n          <Command>\n            <ShellExecute Verb='runas' WindowStyle='0'/>\n            <FileName>regsvr32.exe</FileName>\n            <Arguments>/u \"%1\"</Arguments>\n          </Command>\n        </SubKey>\n      </Item>\n    </Shell>\n  </Group>\n</Data>"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/GuidInfosDic.ini",
    "content": "﻿;<说明>:\n;由于ShellEx类型右键菜单的菜单名称和图标无法直接获取，只能通过制作字典给用户更直观的体验\n;此文件为依赖<GUID>的ShellEx类型右键菜单项目的名称和图标字典\n;<GUID>可通过右键程序内ShellEx项目\"复制guid\"获取\n;不带括号的<GUID>为字典索引\n\n;<Text>、<ResText>、<[地区文化代码]-Text>\n;菜单项目名称\n;优先级为 <ResText>，<[地区文化代码]-Text>，<Text>\n;<ResText>为引用资源文件字符串资源的本地化字符串,\n;格式为\"@<资源文件路径>,-<字符串资源索引>\",如赋值为\"@shell32.dll,-3576\"\n;[地区文化代码]-Text为系统UI语言直接显示文本，比如zh-CN为中国简体中文，en-US为美国英语\n;Text默认为中国简体中文显示文本\n\n;<Icon>:\n;Icon为菜单项目图标资源位置\n;格式为\"<资源文件路径>,<图标序号>\"，如赋值为\"C:Windows\\System32\\imageres.dll,203\"\n;<图标序号>为负数则为图标资源索引,为非负数则为图标资源顺序序号\n;Icon为空时默认提取文件第一个图标，没有图标则使用dll文件默认图标\n\n;<资源文件路径>:\n;<ResText>和<Icon>中的<资源文件路径>一般使用相对路径\n;如果资源文件所在目录是\"%SystemRoot%\"或者\"%SystemRoot%\\System32\"\n;可省略目录路径仅写文件名(含扩展名)，如\"imageres.dll\"\n\n;<GUID文件路径>:\n;HKCR\\CLSID\\<GUID>\n;HKCR\\WOW6432Node\\CLSID\\<GUID>\n;HKLM\\SOFTWARE\\WOW6432Node\\Classes\\CLSID\\<GUID>\n;可能在以上注册表路径的InprocServer32或LocalServer32子项的默认值中包含<GUID文件路径>\n\n;<转义规则>:\n;针对<资源文件路径>:存在引用资源不在<GUID文件路径>的文件中，而是在当前目录或子目录或父目录\n;中其他文件中;相对<GUID文件路径>,当前目录用\".\\\"代替，父目录用\"..\\\"代替,文件为其本身用\"*\"代替\n;针对UWP新模块中的资源引用，用*代替带版本号的UWP包名\n\n;----------------系统------------------\n[20d04fe0-3aea-1069-a2d8-08002b30309d]\nResText = @shell32.dll,-8770\nIcon = imageres.dll, -109\n[00021401-0000-0000-c000-000000000046]\nText = @windows.storage.dll,-8496\nIcon = shell32.dll,-16769\n[37ea3a21-7493-4208-a011-7f9ea79ce9f5]\nResText = @shell32.dll,-1033\nIcon = explorer.exe\n[ff609cc7-d34d-4049-a1aa-2293517ffcc6]\nResText = @stobject.dll,-417\nIcon = imageres.dll,-5346\n[0bf754aa-c967-445c-ab3d-d8fda9bae7ef]\nResText = @stobject.dll,-416\nIcon = imageres.dll,-5346\n[3080f90e-d7ad-11d9-bd98-0000947b0257]\nResText = @shell32.dll,-12715\nIcon = imageres.dll\n[470c0ebd-5d73-4d58-9ced-e91e22e23282]\nResText = @shell32.dll,-51201\nIcon = imageres.dll,-5376\n[a2a9545d-a0c2-42b4-9708-a0b2badd77c8]\nResText = @shell32.dll,-30608\nIcon = imageres.dll,-80\n[90aa3a4e-1cba-4233-b8bb-535773d48449]\nResText = @shell32.dll,-5386\nIcon = imageres.dll,-5354\n[7ba4c740-9e81-11cf-99d3-00aa004ae837]\nResText = @shell32.dll,-30312\nIcon = imageres.dll,-185\n[f3d06e7c-1e45-4a26-847e-f9fcdee59be0]\nResText = @shell32.dll,-30328\nIcon = imageres.dll,-5302\n[c2fbb630-2971-11d1-a18c-00c04fd75d13]\nResText = @shell32.dll,-30304\nIcon = imageres.dll,-5304\n[c2fbb631-2971-11d1-a18c-00c04fd75d13]\nResText = @shell32.dll,-30305\nIcon = imageres.dll,-5303\n[b8cdcb65-b1bf-4b42-9428-1dfdb7ee92af]\nResText = @shell32.dll,-37514\n[09799afb-ad67-11d1-abcd-00c04fc30936]\nResText = @shell32.dll,-5376\nIcon = imageres.dll,-5340\n[3dad6c5d-2167-4cae-9914-f99e41c12cfa]\nText = 包含到库中(&I)\npt-BR-Text = &Incluir na bibioteca\nIcon = imageres.dll,-1001\n[d969a300-e7ff-11d0-a93b-00a0c90f2719]\nResText = @shell32.dll,-95851\nIcon = imageres.dll,-5307\n[a470f8cf-a1e8-4f65-8335-227475aa5c46]\nResText = @ipsecsnp.dll,-100\nText = 加密(&Y)\npt-BR-Text = &criptografar\nIcon = imageres.dll,-59\n[1d27f844-3a1f-4410-85ac-14651078412d]\nResText = @acppage.dll,-2022\nIcon = msdt.exe\n[7ad84985-87b4-4a16-be58-8b72a5b390f7]\nResText = @playtomenu.dll,-101\n[e2bf9676-5f8f-435c-97eb-11607a5bedf7]\nResText = @ntshrui.dll,-107\nIcon = ntshrui.dll,-123\n[e61bf828-5e63-4287-bef1-60b1a4fde0e3]\nResText = @WorkfoldersControl.dll,-1\nIcon = WorkFolders.exe\n[f81e9010-6ea4-11ce-a7ff-00aa003ca9f6]\nResText = @ntshrui.dll,-103\n[474c98ee-cf3d-41f5-80e3-4aab0ab04301]\nResText = @cscui.dll,-38\n[2854f705-3548-414c-a113-93e27c808c85]\nResText = @EhStorShell.dll,-101\n[fbeb8a05-beee-4442-804e-409d6c4515e9]\nResText = @shell32.dll,-12560\nIcon = imageres.dll,-30\n[59099400-57ff-11ce-bd94-0020af85b590]\nText = 复制磁盘(&Y)...\n[d6791a63-e7e2-4fee-bf52-5ded8e86e9b8]\nResText = @wpdshext.dll,-511\n[0af96ede-aebf-41ed-a1c8-cf7a685505b6]\nResText = @shell32.dll,-34618\nIcon = imageres.dll,-5359\n[596ab062-b4d2-4215-9f74-e9109b0a8153]\nResText = @twext.dll,-1037\n[6b9228da-9c15-419e-856c-19e768a13bdc]\nText = Windows 小工具\n[85bbd920-42a0-1069-a2e4-08002b30309d]\nResText = @shell32.dll,-22978\n[1a184871-359e-4f67-aad9-5b9905d62232]\nResText = @fontext.dll,-340\n[645ff040-5081-101b-9f08-00aa002f954e]\nResText = @mmres.dll,-5831\nIcon = shell32.dll,-254\n[bd472f60-27fa-11cf-b8b4-444553540000]\nResText = @zipfldr.dll,-10095\n[5635493f-7d77-4372-a839-8ad89f5b3726]\nResText = @msimsg.dll,-38\n\n;----------------显卡------------------\n[a929c4ce-fd36-4270-b4f5-34ecac5bd63c]\nResText = @nv3dappshextr.dll,-103\nText = 用图形处理器运行\nIcon = nvcpl.dll\n[e97dec16-a50d-49bb-ae24-cf682282e08d]\nResText = @nv3dappshextr.dll,-109\nText = 更改 OpenGL 渲染 GPU...\nIcon = nvcpl.dll\n[3d1975af-48c6-4f8e-a182-be0e08fa86a9]\nResText = @nvsvcr.dll,-4530\nText = NVIDIA 控制面板\nIcon = nvcpl.dll\n[9b5f5829-a529-4b12-814a-e81bcb8d93fc]\nText = 英特尔® 显卡设置\nen-US-Text = Intel® Graphics\nIcon = .\\igfxEM.exe\n;.\\igfxTray.exe\n[3ab1675a-ccff-11d2-8b20-00a0c93cb1f4]\nText = Intel® Graphics\n[5e2121ee-0300-11d4-8d3b-444553540000]\nText = AMD 显卡\nen-US-Text = AMD Graphics\nIcon = .\\RadeonSettings.exe\n\n;----------------压缩------------------\n[5b69a6b4-393b-459c-8ebb-214237a9e7ac]\nText = Bandizip\nIcon = .\\Bandizip.exe\n[9179176e-b763-3200-8500-bb1b90b3d5de]\nText = 360zip\nIcon = .\\360zip.exe\n[b41db860-64e4-11d2-9906-e49fadc173ca]\nText = WinRAR 64bit\n[b41db860-8ee4-11d2-9906-e49fadc173ca]\nText = WinRAR 32bit\n[23170f69-40c1-278a-1000-000100020000]\nText = 7-zip\nIcon = .\\7zG.exe\n[b1832224-9f22-4965-a6e8-e6a6e3c4fdf7]\nText = 52好压\nIcon = .\\kzip_main.exe\n[5fed836a-c96c-4d88-a91e-f63f07726585]\nText = 2345好压\nIcon = .\\HaoZip.exe\n[6adf19e3-77a3-4395-adb4-9fd7d351eb3e]\nText = 快压\n[903d855a-d671-4a8e-a592-9168755917db]\nText = 快压\n[6adf19e3-77a3-4395-adb4-9fd7d351eb3e]\nText = 快压\n[903d855a-d671-4a8e-a592-9168755917db]\nText = 快压\n[e0d79304-84be-11ce-9641-444553540000]\nText = WinZip\nIcon = .\\WzPreloader.exe\n[acf03765-1658-485f-9615-fe03c372fb8c]\nText = 微压\n[dd847e93-86df-4d75-a421-46d29228f6da]\nText = 极光压缩\nIcon = .\\plFM.exe\n[5e3b6ea4-de96-464f-bb86-5587969f4c62]\nText = 万能压缩\n[9175e343-1c41-4490-b178-14f36504f07e]\nText = 160压缩\nIcon = .\\160zip.exe\n[5e3ca55c-d9f3-4d1c-8b94-ad192b0f7c16]\nText = 速压\nIcon = .\\Suzip.exe\n[02e77c8d-2798-441e-8e6d-0c2ed9fe206e]\nText = 简压缩\nIcon = .\\SimpleZip.exe\n[5c551008-a347-4db3-af48-014076fd2b46]\nText = 极速压缩\nIcon = .\\JsZip.exe\n[0a4861a5-448a-48b4-812a-cf71a07a674f]\nText = 6789压缩\n[7522b611-f22b-4f24-9ce4-3ecbba85c126]\nText = CoffeeZip\n[aa7f8063-f898-44d0-b147-8a6e9891e32e]\nText = 布丁压缩\nIcon = .\\PDZip.exe\n[9b8dff9d-0cb2-4100-8f21-c6dd6ce01141]\nText = 布丁压缩\nIcon = .\\PDZip.exe\n[d81a0ed9-6c47-417b-b298-4ebd813cabd0]\nText = 极客压缩\nIcon = .\\GeekZip.exe\n[e677c7ad-2b66-4539-aa29-3771a1cfeda9]\nText = jZip\nIcon = .\\jZip.exe\n[a6630968-27dc-8db8-9bce-e12b3198a9b1]\nText = WinArchiver\nIcon = .\\WinArchiver.exe\n[1532b32d-3a75-4a4d-9b38-5a6000ea7045]\nText = FreeArc\nIcon = ..\\FreeArc.exe\n[ad392e40-428c-459f-961e-9b147782d099]\nText = UltraISO\nIcon = .\\UltraISO.exe\n[be86f80b-eb1a-45b4-b4b6-4b12d302b6bc]\nText = AntZip\n[9d731a0b-89e4-44e2-a6a4-3b05c80d562c]\nText = i-Zip\n[00000000-b39d-4cb2-85f6-6e055d3b9a96]\nText = 在此窗口中打开(&T)\nen-US-Text = Open in &this window\n[9ee0c3ef-c379-4fed-b2a8-651bb61f5c0f]\nText = 打开为文件夹\nen-US-Text = Open as folder\n[9ee0c3ef-c379-4fed-b2a8-651bb61f5c0e]\nText = 压缩并邮寄\nen-US-Text = Pack to and email\n[59624dcd-de34-4e3b-abe4-f40dafa1f2e0]\nText = TC4Shell\n\n;----------------杀软------------------\n[09a47860-11b0-4da5-afa5-26d86198a780]\nText = Microsoft Defender\nIcon = .\\EppManifest.dll\n[18a3e590-f219-4105-9079-93dafa51b9d6]\nResText = @*,-103\nText = 使用火绒安全进行杀毒\nen-US-Text = Scan with Huorong Internet Security\n[9f012318-caa5-402c-9bf6-28eb36f61496]\nResText = @*,-102\nText = 使用火绒安全粉碎文件\nen-US-Text = Shred with Huorong Internet Security\n[63332668-8ce1-445d-a5ee-25929176714e]\nText = 扫描病毒(电脑管家)\n[754df2ce-51e8-4895-b53c-6381418b84ae]\nText = 文件粉碎(电脑管家)\n[cbdecef7-7a29-4cbf-a009-2673d82c7bf9]\nText = 强力卸载(电脑管家)\nIcon = .\\QQPCSoftMgr.exe\n[c5617f6a-39bb-436d-91cf-61c1b45dd688]\nText = 深度加速(管家小火箭)\n[b7667919-3765-4815-a66d-98a09be662d6]\nText = 清理垃圾(电脑管家)\n[086f171d-5ed1-4ed2-b736-cff3ad6a128e]\nText = 使用 360杀毒 扫描\nIcon = .\\msdev.exe\n[7c0f6d57-e799-4c8a-a319-8e2b4d724cf0]\nText = 360安全卫士\nIcon = ..\\360Safe.exe\n[5e19c0ce-c02c-46c2-98c3-a2e12ede0e17]\nText = 360强力卸载 && 桌面助手\nIcon = .\\SoftMgr.exe\n[c4f75db1-b9f4-425a-9f5b-778911bcf176]\nText = 2345扫描病毒 && 强力删除\nIcon = .\\2345MPCSafe.exe\n[6b3ba4a8-ec7e-4714-9ecf-eb33995b3384]\nText = 使用2345软件管家卸载软件\nIcon = ..\\..\\2345SoftMgr.exe\n[ddea5705-1bb0-4c03-ac1e-8ff9716a0d51]\nText = 金山毒霸(64位)\nIcon = .\\kismain.exe\n[d21d88e8-4123-48ba-b0b1-3fdbe4ae5fa4]\nText = 金山毒霸(32位)\nIcon = .\\kismain.exe\n[367f6ae2-6809-4bed-b09b-228893fb33dd]\nText = 金山毒霸\nIcon = .\\kismain.exe\n[758c684b-4d10-4bc1-90da-6bebf0b4e0b4]\nText = 使用联想电脑管家进行扫描\n[c97c3e31-2af4-4651-9e93-ede827605a23]\nText = 强力卸载此软件(联想电脑管家)\n[c49499ac-dc25-478b-b903-e005012b3dd1]\nText = 使用智量扫描\nIcon = .\\WiseVector.exe\n[cca9efd3-29ed-430a-ba6d-e6bbff0a60c2]\nText = McAfee\nIcon = .\\McInstru.exe\n[472083b0-c522-11cf-8763-00608cc02f24]\nText = Avast\nIcon = ..\\AvastUI.exe\n[45ac2688-0253-4ed8-97de-b5370fa7d48a]\nText = 使用 Avira 扫描所选文件\nIcon = ..\\Launcher\\Avira.Systray.exe\n[9b9f6e01-a5cf-4269-b245-cff66a7daebd]\nText = 卡巴斯基\n[57ce581a-0cb6-4266-9ca0-19364c90a0b3]\nText = Malwarebytes\n[f7caa2a1-67a2-44bb-b20f-202fd8eb1dab]\nText = Norton 360\nIcon = .\\uiStub.exe\n[fad61b3d-699d-49b2-be16-7f82cb4c59ca]\nText = Norton文件智能分析\nIcon = .\\uiStub.exe\n[e8215bea-3290-4c73-964b-75502b9b41b2]\nText = Norton File Shredder\n[1c7593cb-c1cc-4ba7-be52-8eea47f9cb1d]\nText = 使用瑞星杀毒\n[0bb81440-5f42-4480-a5f7-770a6f439fc8]\nText = IObit Malware Fighter\nIcon = *,3\n[b089fe88-fb52-11d3-bdf1-0050da34150d]\nText = ESET Endpoint Antivirus\n\n;----------------传输------------------\n[53d2405c-48ab-4c8a-8f59-ce0610f13bbc]\nText = 通过QQ发送到\n[cb3d0f55-bc2c-4c1a-85ed-23ed75b5106b]\nText = OneDrive\nIcon = ..\\..\\OneDrive.exe\n[6d85624f-305a-491d-8848-c1927aa0d790]\nText = 上传到百度网盘\nIcon = .\\BaiduNetdisk.exe\n[2008caf4-a5c1-4037-99a8-699e4d01456d]\nText = 天翼云盘\nIcon = .\\eCloud.exe\n[1d39a523-4df5-4562-8fff-08c740632f4f]\nText = 360云盘\nIcon = .\\360WangPan.exe\n[eee949eb-c9ed-4967-98b0-ed4e543befa5]\nText = 115网盘\nIcon = ..\\115chrome.exe\n[171b6b53-17b1-40b7-afb2-a415b2b40401]\nText = 上传到腾讯微云\nIcon = ..\\..\\..\\..\\..\\..\\..\\WeiyunApp.exe\n[5d652b62-b702-496a-92bc-92c308251fea]\nText = 坚果云\nIcon = *,3\n[67f4d210-bfc2-4add-9a2a-c9b9e1f42c4f]\nText = 上传到 “WPS云文档”\nIcon = ..\\..\\ksolaunch.exe\n[aa147ffb-0b1f-4bb1-9b1e-8d062b35c145]\nText = 自动同步文件夹到 “WPS云文档”\n[970a26b5-2b84-4b60-8067-1440c229672d]\nText = 钉盘\nIcon = ..\\DingtalkLauncher.exe\n[0229e5e7-09e9-45cf-9228-0228ec7d5f17]\nText = MEGA\nIcon = .\\MEGAsync.exe\n[ecd97de5-3c8f-4acb-aeee-ccab78f7711c]\nText = Dropbox\n[30351349-7b7d-4fcc-81b4-1e394ca267eb]\nText = TortoiseSVN\nIcon = .\\TortoiseIDiff.exe\n[10a0fdd2-b0c0-4cd4-a7ae-e594ce3b91c8]\nText = TortoiseGit\nIcon = .\\TortoiseGitProc.exe\n[2a535b11-6cfc-4e85-a75f-0e397b1584cf]\nText = 通过网易邮箱大师发送\nIcon = ..\\mailmaster.exe\n[9557f42f-bd61-4e26-9752-33a8a20fc9f9]\nText = 分享文件(华为电脑管家)\nIcon = .\\PCManager.exe\n[c3db4192-4c22-428f-8c12-cf9cfabbdd17]\nText = 通过AirDroid发送到我的设备\n[0b488c12-e68e-44d7-9259-fb8e5df8bb27]\nText = 内网通\nIcon = .\\ShiYeLine.exe\n[256ef94c-697d-4986-b99b-9d3b15d79b49]\nText = Infinit\n[a97a01b0-3b66-4336-bc9b-168e64bfb296]\nText = 广讯通发送文件\nIcon = .\\GXT.exe\n[41b3b91f-d6b3-3430-bb86-a143f85353ca]\nText = Huawei Share\n[1bca9901-05c3-4d01-8ad4-78da2eac9b3f]\nText = 使用小米互传发送\nIcon = .\\FixServiceTool.exe\n\n;----------------PDF------------------\n[9c5397bb-07be-4e38-98ba-395f94045091]\nText = 福昕PDF编辑器\nIcon = ..\\FoxitPhantom.exe\n[27be7b9d-935f-325c-9a05-63557d69f4f9]\nText = 万兴PDF专家\nIcon = ..\\PDFExpert.exe\n[a6595cd1-bf77-430a-a452-18696685f7c7]\nText = Adobe Acrobat\nIcon = ..\\Acrobat\\Acrobat.exe\n[d25b2cab-8a9a-4517-a9b2-cb5f68a5a802]\nText = 转换为Adobe PDF(&B)\n[1ecda7bf-4dfa-41d8-9380-1a27b26cfc41]\nText = 使用WPS PDF编辑\nIcon = ..\\..\\wpspdf.exe\n[e3ed4700-22d4-41b6-8144-e3f5f1ac5153]\nText = 使用WPS PDF编辑\nIcon = ..\\..\\wpspdf.exe\n[af1d7d2f-6ae8-4baa-abfa-738201f4871c]\nText = WPS Office PDF\nIcon = .\\wpspdf.exe\n[b4e15cd0-f916-4c8e-830a-15e3e9d01a1b]\nText = 迅读PDF大师 合并、拆分、转换\nIcon = .\\MasterPDF.exe\n[19a73c67-f0b8-4a28-8c33-9d4eddd6fcbc]\nText = 云上PDF\nIcon = .\\iPDF.exe\n[29424e92-60a1-40c0-bf79-1b8472dde706]\nText = 使用PDF猫编辑器打开\nIcon = .\\M_pdfEdit.exe\n[29424e91-60a1-40c0-bf79-1b8472dde606]\nText = 使用转转大师PDF编辑器打开\nIcon = .\\ZPDFEdit.exe\n[098a124a-aa1c-38c8-a65e-d1199a14516a]\nText = Convert to...(万兴PDF专家)\n[fb074836-8286-4089-84dc-f504e9ef621c]\nText = ABBYY FineReader\nIcon = ..\\FineUpdate.exe\n[d16adfe3-66c5-4df5-9978-87de0c687e85]\nText = 嗨格式PDF转换器\nIcon = .\\HiPdfConvert.exe\n[2acd35ab-f74a-4c20-aa9b-2de80081626d]\nText = PDF-XChange Editor\nIcon = ..\\PDF Editor\\PDFXEdit.exe\n[6c405cec-8624-4fef-b3ba-9d4e5a8f58b5]\nText = 迅捷PDF转换器\nIcon = .\\pdfconverter.exe\n\n;--------------影音图像----------------\n[ffe2a43c-56b9-4bf5-9a79-cc6d4285608a]\nResText = @*,-3050\nText = 向右、向左旋转(&T)​​\n[e598560b-28d5-46aa-a14a-8a3bea34b576]\nText = 幻灯片放映\n[8a734961-c4aa-4741-ac1e-791acebf5b39]\nText = 联机购买音乐\n[f1b9284f-e9dc-4e68-9d7e-42362a59f0fd]\nText = 添加到“Windows Media Player”列表(&W)\n[ce3fb1d1-02ae-4a5f-a6e9-d9f1b4073e6c]\nText = 使用“Windows Media Player”播放(&P)\n[7d4734e6-047e-41e2-aeaa-e763b4739dc4]\nText = 使用 Media Player 播放(&P)\n[9b6d38f3-8ef4-48a5-ad30-ffffffffffff]\nText = Honeyview\nIcon = .\\Honeyview.exe\n[c2396f1e-4ba2-4b7d-857a-f764761c012b]\nText = ACD看图\nIcon = .\\AcdKantu.exe\n[83a97a48-f5d7-4d12-8ba3-5263a016d936]\nText = 使用光影4.0编辑\n[8f556da3-987d-47b0-aa88-eb8d52fe1b9a]\nText = 迅雷播放组件\nIcon = ..\\Program\\XMP\\XMP.exe\n[5cd76c57-6893-478a-b776-47e7c82504be]\nText = 爱奇艺万能联播\nIcon = .\\GeePlayer.exe\n[a3888921-cfd3-4a6b-89bf-08e6b95716e8]\nText = 图片工厂(&F)\n[51b4d7e5-7568-4234-b4bb-47fb3c016a69]\nResText = @*,-101\nText = 调整图片大小(PowerToys)\n[5c6a637c-9780-4d0f-a379-4732edcce7c3]\nText = 网易云音乐\n[1f77b17b-f531-44db-aca4-76abb5010a28]\nText = AIMP\nIcon = ..\\AIMP.exe\n[8e7861bb-3a13-40a1-af25-633458757201]\nText = QQ影音\n[7a1884a3-f647-49be-b93c-8ffaf4a1f1bf]\nText = 使用PP视频播放\n[8f556da3-987d-47b0-aa88-eb8d52fe1b99]\nText = 迅雷影音\nIcon = ..\\..\\Program\\APlayer.exe\n[4d2fba8d-621b-4447-af6d-5794f479c4a5]\nText = 爱奇艺看图\nIcon = ..\\QyImg.exe\n[4a34b3e3-f50e-4ff6-8979-7e4176466ff2]\nText = SageThumbs\n[d149b06b-bc31-4425-b5bb-0e04308982ae]\nText = 用百图秀打开\n[5add1a3c-29e2-4d18-b79a-c56e1df5486c]\nText = 百图秀\n[1bb8f8e1-6492-4ec9-ac40-9ad0f5c01fa2]\nText = 鲨鱼看图\nIcon = .\\SharkElevate.exe\n[a2cf4243-6525-4764-b3f5-2fcde2f47989]\nText = MPC-BE\nIcon = .\\unins000.exe\n\n;----------------美化------------------\n[cf444751-60fc-48b8-ac0f-363063eb2a9e]\nText = 开启桌面整理(电脑管家)\n[b3a2f1a4-10a2-410c-9c19-622b621c61d0]\nText = 换壁纸(小鸟壁纸)\n[3b7162fb-4389-40c8-83a5-da10d491ec66]\nText = 映射此文件夹到桌面(小智桌面)\nIcon = .\\XZDesktop.exe\n[96babf4f-7c38-4885-b407-3800f461669b]\nText = 打开火萤视频桌面\nIcon = ..\\..\\HYVideoDesktop.exe\n[c3c76829-1d8b-49a2-afb4-196c443f1b0b]\nText = 人工桌面\nIcon = .\\N0vaDesktop.exe\n[a2a9545d-a0c2-42b4-9708-a0b2badd77c9]\nResText = @*,-5381\nText = 附到「开始」菜单(&U)(StartIsBack)\nIcon = .\\StartIsBackCfg.exe\n[6a451c0a-9597-4915-bcce-6e859bc996b2]\nText = Pin to Start (Start10)\nIcon = .\\Start10.exe\n[af8fa9c9-9907-463e-bdc3-4cc1200d6310]\nText = Start Menu 8\nIcon = *,2\n[07451604-fbe4-4475-9dd6-261b7b619417]\nText = 电脑管家经典开始菜单\nIcon = .\\QMStart.exe\n[2d5ad9eb-31bc-48f7-a438-28f363632c73]\nText = 开启布丁桌面\nIcon = .\\PDLanuncher.exe\n[b5e436bc-642a-4bf6-b725-26038af26e89]\nText = 开启桌面整理(元气、猎豹轻桌面)\nIcon = .\\kdesk.exe\n[5f8d079b-8ce6-4f58-bf10-55c1b68d88f3]\nText = 选择颜色设置\nIcon = .\\ChromaTune.exe\n[6c125022-639d-43cc-9f3d-647e6cc69ef1]\nText = 右键菜单背景插件(ContextBG)\n\n;--------------文件处理----------------\n[b298d29a-a6ed-11de-ba8c-a68e55d89593]\nText = Notepad++\n[36d94110-787c-4828-9c1b-0dafebc36069]\nText = EditPlus\nIcon = .\\EditPlus.exe\n[b5eedee0-c06e-11cf-8c56-444553540000]\nText = UltraEdit\nIcon = .\\uedit64.exe\n[51eee242-ad87-11d3-9c1e-0090278bbd99]\nText = Vim\nIcon = ..\\vim.exe\n[ed90173a-3b4c-4e7e-b9cf-79714425d4b5]\nText = PSPad Editor\nIcon = .\\PSPad.exe\n[a3777921-cfd3-4a6b-89bf-08e6b95716e8]\nText = 格式工厂(&F)\nIcon = .\\FormatFactory.exe\n[af9b72b5-f4e4-44b0-a3d9-b55b748efe90]\nText = File Converter\nIcon = .\\FileConverter.exe\n[dde4beeb-dde6-48fd-8eb5-035c09923f83]\nText = Unlocker\nIcon = .\\Unlocker.exe\n[0bb27cda-7029-4c0e-9c56-d922b229f0eb]\nText = 解除文件锁定(LockHunter)\nIcon = .\\LockHunter.exe\n[410bf280-86ef-4e0f-8279-ec5848546ad3]\nText = IObit Unlocker\nIcon = .\\IObitUnlocker.exe\n[836ab26c-2de4-41d3-ac24-4c6c2699b960]\nText = 强力卸载(IObit Uninstaller)\n[2803063f-4b8d-4dc6-8874-d1802487fe2d]\nText = Advanced SystemCare\nIcon = *,3\n[fe8e6ad6-dabe-45e1-88c2-48dc4578924c]\nText = Uninstall Tool\n[2c5515dc-2a7e-4bfd-b813-cacc2b685eb7]\nText = Revo Uninstaller Pro\nIcon = *,1\n[b3026062-4d7e-3601-9a6b-622ceac3fc5c]\nText = File Governor\nIcon = .\\FileGovernor.exe\n[1650dc30-2343-498a-b49a-37b90918f611]\nText = CleanMyPC\n[6cb83a5a-aa68-4895-9f54-175e789ae149]\nText = Balabolka\nIcon = .\\balabolka.exe\n[0440049f-d1dc-4e46-b27b-98393d79486b]\nResText = @*,-101\nText = PowerRename(&W)\n[2e7a2c6c-b938-40a4-ba1c-c7ec982dc202]\nText = 发布DWF\nIcon = .\\AcLauncher.exe\n[57fa2d12-d22d-490a-805a-5cb48e84f12a]\nText = Beyond Compare\nIcon = .\\BCompare.exe\n[c3b42c03-c1b7-4c1a-b384-bbae19646333]\nText = UltraCompare\nIcon = .\\uc.exe\n[1ed0f018-76b9-4db9-9c06-ca0f3088f04f]\nText = FileLocator Pro\n[00000000-0000-0000-0000-000000000012]\nText = 显示隐藏文件+扩展名\n[c1b2c38f-3dca-4e3d-bc34-d5b87b636543]\nText = FileMenu Tools\n[189f1e63-33a7-404b-b2f6-8c76a452cc54]\nText = Smart Defrag\nIcon = *,2\n[4380c993-0c43-4e02-9a7a-0d40b6ea7590]\nText = Defraggler\nIcon = .\\Defraggler.exe\n[271dc252-6fe1-4d59-9053-e4cf50ab99de]\nText = VMware\nIcon = .\\vmware.exe\n[e4d28edc-8c0b-43ee-9e7d-c8a8682334dc]\nText = VMware 64bit\nIcon = .\\vmware.exe\n[c52b9871-e5e9-41fd-b84d-c5acadbec7ae]\nText = Locale Emulator\nIcon = .\\LEGUI.exe\n[0a479751-02bc-11d3-a855-0004ac2568aa]\nText = NTFS文件连接扩展配置工具\nIcon = .\\LSEConfig.exe\n[fdf253ac-1724-4853-be34-c2dbc18fb5ca]\nText = Copywhiz\nIcon = .\\Copywhiz.exe\n[6c467336-8281-4e60-8204-430ced96822d]\nText = 共享文件夹同步\n[6fa85dad-ac32-4d74-9cba-6a1c038f9a56]\nText = 文档加密/解密\n[ef479680-ea35-4ea9-b093-7114f3e3e0da]\nText = Directory Lister\nIcon = .\\DirListerPro.exe\n[8e57c449-7891-49bb-80e5-ddac375f8ac8]\nText = 使用微表格打开\nIcon = .\\microexcel.exe\n[0d8b46ea-7d35-4921-b88c-7e2b1e2d80f0]\nText = WPS Office\nIcon = ..\\..\\wpsoffice.exe\n[53506455-e799-443f-addb-891ca6efc928]\nText = 扫描游戏到快吧游戏\n[2a118eb5-5797-4f5e-8b3d-f4ecba3c98e4]\nText = Adobe Core Sync Extension\n\n;-------------UWP新模块----------------\n[776dbc8d-7347-478c-8d71-791e12ef49d8]\nUwpName = Microsoft.SkypeApp\nResText = @*,-101\nText = 使用 Skype 共享\nIcon = .\\Skype.exe\n[9f156763-7844-4dc4-b2b1-901f640f5155]\nUwpName = Microsoft.WindowsTerminal\nResText = @{*?ms-resource://Microsoft.WindowsTerminal/TerminalApp/Resources/ShellExtension_OpenInTerminalMenuItem}\nText = Open in Windows Terminal\nIcon = .\\WindowsTerminal.exe"
  },
  {
    "path": "ContextMenuManager/Properties/Resources/Texts/UwpModeItemsDic.xml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- 微软在Win10右键菜单中新增的UWP模块, 非Shell、ShellEx类型,\n但是可通过GUID锁定屏蔽来禁用相关右键菜单项目,\nGUID查找位置：HKEY_CLASSES_ROOT\\PackagedCom\\Package\\[包名]\\Class\\[GUID],\nScene的各子节点为菜单项目出现位置, Item必须有Guid属性，\nUwpName、Text、Icon、Tip等属性写在GuidInfosDic.ini里面-->\n\n<Scene>\n  <File>\n    <Item Guid='776dbc8d-7347-478c-8d71-791e12ef49d8'/>\n  </File>\n  <Folder>\n    <Item Guid='9f156763-7844-4dc4-b2b1-901f640f5155'/>\n  </Folder>\n  <Directory>\n    <Item Guid='9f156763-7844-4dc4-b2b1-901f640f5155'/>\n  </Directory>\n  <Background>\n    <Item Guid='9f156763-7844-4dc4-b2b1-901f640f5155'/>\n  </Background>\n  <Desktop>\n    <Item Guid='9f156763-7844-4dc4-b2b1-901f640f5155'/>\n  </Desktop>\n</Scene>"
  },
  {
    "path": "ContextMenuManager/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:4.0.30319.42000\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace ContextMenuManager.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   一个强类型的资源类，用于查找本地化的字符串等。\n    /// </summary>\n    // 此类是由 StronglyTypedResourceBuilder\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   返回此类使用的缓存的 ResourceManager 实例。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"ContextMenuManager.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   重写当前线程的 CurrentUICulture 属性，对\n        ///   使用此强类型资源类的所有资源查找执行重写。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap About {\n            get {\n                object obj = ResourceManager.GetObject(\"About\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Add {\n            get {\n                object obj = ResourceManager.GetObject(\"Add\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap AddExisting {\n            get {\n                object obj = ResourceManager.GetObject(\"AddExisting\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap AddSeparator {\n            get {\n                object obj = ResourceManager.GetObject(\"AddSeparator\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 ;此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典。\n        ///;可帮助作者为此程序提供翻译并提交到Github，以下内容中等号右侧内容替换为翻译文本。\n        ///;General - Translator 为翻译贡献者，General - Language 为语言名称，如en-US 美国英语，\n        ///;General - TranslatorUrl 为翻译贡献者的URL地址(能用Win+R命令打开的URL链接即可)\n        ///;翻译说明：暂时不翻译的值保留为空即可，字典内赋值换行使用\\r\\n或\\n进行转义。\n        ///;翻译贡献者和为多人时请使用\\r\\n或\\n对 Translator 的值和对应的 TranslatorUrl 值换行，\n        ///;没有URL地址赋值为null，使贡献者与链接一一对应，如 Translator = Bob \\r\\n Join \\r\\n Andi, \n        ///;TranslatorUrl = https://github.com/BluePointLilac \\r\\n null \\r\\n https://gitee.com/BluePointLilac\n        ///\n        ///[General]\n        ///Ap [字符串的其余部分被截断]&quot;; 的本地化字符串。\n        /// </summary>\n        internal static string AppLanguageDic {\n            get {\n                return ResourceManager.GetString(\"AppLanguageDic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap CheckUpdate {\n            get {\n                object obj = ResourceManager.GetObject(\"CheckUpdate\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Custom {\n            get {\n                object obj = ResourceManager.GetObject(\"Custom\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Delete {\n            get {\n                object obj = ResourceManager.GetObject(\"Delete\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n        ///&lt;!--每个程序为一个Group，Text为Group项显示文本，Guid用于判断用户是否安装此程序并决定是否显示该Group，不设置Guid则为常驻菜单，RegPath为程序相关注册表主路径;\n        ///其相关菜单项目设置作为一个Item子元素，Item的Text为该Item项显示文本，Tip为鼠标悬浮在开关上时的提示信息，需要重启资源管理器生效则添加RestartExplorer;\n        ///Item的子元素Rule为相关注册表内容，RegPath省略则默认为Group主路径，以\\开头则为Group主路径的子项路径；\n        ///ValueName为相关键名，On为启用键值，Off为禁用键值；不设置On或Off属性时，其值为null，对应注册表键值不存在；\n        ///每个Item可能受多个注册表Rule影响，按照顺序进行键值判定；判定规则：当有多条规则时，前面的规则注册表键值匹配On则为On，匹配Off则为Off，并终止判断，都不匹配时继续往下判断，若所有规则都不匹配则为On\n        ///ValueKind为键值类型，默认键值类型ValueKind为REG_DWORD， [字符串的其余部分被截断]&quot;; 的本地化字符串。\n        /// </summary>\n        internal static string DetailedEditDic {\n            get {\n                return ResourceManager.GetString(\"DetailedEditDic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Donate {\n            get {\n                object obj = ResourceManager.GetObject(\"Donate\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap DownLoad {\n            get {\n                object obj = ResourceManager.GetObject(\"DownLoad\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Enhance {\n            get {\n                object obj = ResourceManager.GetObject(\"Enhance\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n        ///&lt;!--此文件为常用右键菜单字典, 可为此字典添加多语言翻译，添加一个Culture子项并设置为en-US、ja-JP等即可\n        ///Tip属性为鼠标悬浮在开关上时的提示信息，从每个Item节点开始, 子元素Value表示该项的注册表键值，目前仅支持REG_SZ、REG_DWORD、REG_EXPAND_SZ、REG_BINARY的键值类型，\n        ///子元素SubKey的所有子元素是该项的子项，项名即为元素名; 每一Item项和SubKey的所有子元素的属性Default为该注册表项默认值，不放在Value\\REG_SZ元素里面是为了防止与可能存在的键名为Default的键产生冲突\n        ///由于Shell项太过复杂，程序只根据注册表项名判断存在即启用，故同一场景下不允许有相同KeyName属性的Shell项目，ShellEx项只要Guid符合则为启用--&gt;\n        ///\n        ///&lt;Data&gt;\n        ///  &lt;Group&gt;\n        ///    &lt;Text Value=&apos;文件&apos;/&gt;\n        ///    &lt;Text Value=&apos;File&apos;&gt;\n        ///      &lt;Culture&gt;en-US&lt;/Cult [字符串的其余部分被截断]&quot;; 的本地化字符串。\n        /// </summary>\n        internal static string EnhanceMenusDic {\n            get {\n                return ResourceManager.GetString(\"EnhanceMenusDic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 ;&lt;说明&gt;:\n        ///;由于ShellEx类型右键菜单的菜单名称和图标无法直接获取，只能通过制作字典给用户更直观的体验\n        ///;此文件为依赖&lt;GUID&gt;的ShellEx类型右键菜单项目的名称和图标字典\n        ///;&lt;GUID&gt;可通过右键程序内ShellEx项目&quot;复制guid&quot;获取\n        ///;不带括号的&lt;GUID&gt;为字典索引\n        ///\n        ///;&lt;Text&gt;、&lt;ResText&gt;、&lt;[地区文化代码]-Text&gt;\n        ///;菜单项目名称\n        ///;优先级为 &lt;ResText&gt;，&lt;[地区文化代码]-Text&gt;，&lt;Text&gt;\n        ///;&lt;ResText&gt;为引用资源文件字符串资源的本地化字符串,\n        ///;格式为&quot;@&lt;资源文件路径&gt;,-&lt;字符串资源索引&gt;&quot;,如赋值为&quot;@shell32.dll,-3576&quot;\n        ///;[地区文化代码]-Text为系统UI语言直接显示文本，比如zh-CN为中国简体中文，en-US为美国英语\n        ///;Text默认为中国简体中文显示文本\n        ///\n        ///;&lt;Icon&gt;:\n        ///;Icon为菜单项目图标资源位置\n        ///;格式为&quot;&lt;资源文件路径&gt;,&lt;图标序号&gt;&quot;，如赋值为&quot;C:Windows\\System32\\imageres.dll,203&quot;\n        ///;&lt;图标序号&gt;为负数则为图标资源索引, [字符串的其余部分被截断]&quot;; 的本地化字符串。\n        /// </summary>\n        internal static string GuidInfosDic {\n            get {\n                return ResourceManager.GetString(\"GuidInfosDic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Home {\n            get {\n                object obj = ResourceManager.GetObject(\"Home\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Jump {\n            get {\n                object obj = ResourceManager.GetObject(\"Jump\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap MicrosoftStore {\n            get {\n                object obj = ResourceManager.GetObject(\"MicrosoftStore\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap NewFolder {\n            get {\n                object obj = ResourceManager.GetObject(\"NewFolder\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap NewItem {\n            get {\n                object obj = ResourceManager.GetObject(\"NewItem\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Open {\n            get {\n                object obj = ResourceManager.GetObject(\"Open\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Refresh {\n            get {\n                object obj = ResourceManager.GetObject(\"Refresh\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Select {\n            get {\n                object obj = ResourceManager.GetObject(\"Select\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Setting {\n            get {\n                object obj = ResourceManager.GetObject(\"Setting\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Star {\n            get {\n                object obj = ResourceManager.GetObject(\"Star\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap SubItems {\n            get {\n                object obj = ResourceManager.GetObject(\"SubItems\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Translate {\n            get {\n                object obj = ResourceManager.GetObject(\"Translate\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Type {\n            get {\n                object obj = ResourceManager.GetObject(\"Type\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Up {\n            get {\n                object obj = ResourceManager.GetObject(\"Up\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap User {\n            get {\n                object obj = ResourceManager.GetObject(\"User\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;\n        ///&lt;!-- 微软在Win10右键菜单中新增的UWP模块, 非Shell、ShellEx类型,\n        ///但是可通过GUID锁定屏蔽来禁用相关右键菜单项目,\n        ///GUID查找位置：HKEY_CLASSES_ROOT\\PackagedCom\\Package\\[包名]\\Class\\[GUID],\n        ///Scene的各子节点为菜单项目出现位置, Item必须有Guid属性，\n        ///UwpName、Text、Icon、Tip等属性写在GuidInfosDic.ini里面--&gt;\n        ///\n        ///&lt;Scene&gt;\n        ///  &lt;File&gt;\n        ///    &lt;Item Guid=&apos;776dbc8d-7347-478c-8d71-791e12ef49d8&apos;/&gt;\n        ///  &lt;/File&gt;\n        ///  &lt;Folder&gt;\n        ///    &lt;Item Guid=&apos;9f156763-7844-4dc4-b2b1-901f640f5155&apos;/&gt;\n        ///  &lt;/Folder&gt;\n        ///  &lt;Directory&gt;\n        ///    &lt;Item Guid=&apos;9f156763-7844-4dc4-b2b1-901f640f5155&apos;/&gt;\n        ///   [字符串的其余部分被截断]&quot;; 的本地化字符串。\n        /// </summary>\n        internal static string UwpModeItemsDic {\n            get {\n                return ResourceManager.GetString(\"UwpModeItemsDic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找 System.Drawing.Bitmap 类型的本地化资源。\n        /// </summary>\n        internal static System.Drawing.Bitmap Web {\n            get {\n                object obj = ResourceManager.GetObject(\"Web\", resourceCulture);\n                return ((System.Drawing.Bitmap)(obj));\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ContextMenuManager/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"About\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\about.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Add\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\add.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"AddExisting\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\addexisting.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"AddSeparator\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\addseparator.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"AppLanguageDic\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\texts\\applanguagedic.ini;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\n  </data>\n  <data name=\"CheckUpdate\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\checkupdate.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Custom\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\custom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Delete\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"DetailedEditDic\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\texts\\detailededitdic.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\n  </data>\n  <data name=\"Donate\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\donate.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"DownLoad\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\download.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Enhance\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\enhance.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"EnhanceMenusDic\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\texts\\enhancemenusdic.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\n  </data>\n  <data name=\"GuidInfosDic\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\texts\\guidinfosdic.ini;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\n  </data>\n  <data name=\"Home\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\home.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Jump\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\jump.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"MicrosoftStore\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\microsoftstore.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"NewFolder\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\newfolder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"NewItem\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\newitem.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Open\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\open.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Refresh\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\refresh.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Select\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\select.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Setting\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\setting.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Star\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\star.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"SubItems\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\subitems.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Translate\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\translate.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Type\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\type.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"Up\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"User\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\user.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n  <data name=\"UwpModeItemsDic\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\texts\\uwpmodeitemsdic.xml;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>\n  </data>\n  <data name=\"Web\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>resources\\images\\web.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>\n  </data>\n</root>"
  },
  {
    "path": "ContextMenuManager/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:4.0.30319.42000\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace ContextMenuManager.Properties {\n    \n    \n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"16.8.1.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {\n        \n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n        \n        public static Settings Default {\n            get {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ContextMenuManager/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>"
  },
  {
    "path": "ContextMenuManager.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 16\nVisualStudioVersion = 16.0.31005.135\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"ContextMenuManager\", \"ContextMenuManager\\ContextMenuManager.csproj\", \"{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{EF7E60E9-3565-42BA-AFB3-7FE73A1B011C}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {A0E97C81-86B8-4360-8251-DF6FD4494EDA}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "Donate.md",
    "content": "# ContextMenuManager 捐赠名单\n\n## 捐赠说明\n\n> ContextMenuManager完全开源免费，如果你觉得此程序帮助到了你，可以对作者进行捐赠，金额请随意，谢谢支持！\n\n> 备注：收款码平台会隐藏付款方ID，可在支付时备注昵称，已支付用户可通过 1617859183@qq.com 联系我更新用户ID。\n\n## 捐赠名单\n\n> 此名单不定期更新（上次更新：**2022-01-09**）\n\n> 累计金额：**2050.8** 元，累计人次：**241** 人次\n\n|日期|用户ID|平台|金额|备注\n|:--:|:--:|:--:|:--:|:--:\n|2020-10-20|W*t|微信|30\n|2020-10-24|*远|微信|6|右键，一份迟到的支持\n|2020-10-28|*班|微信|3\n|2020-11-03|*方|微信|5\n|2020-11-03|m*c|微信|5\n|2020-11-04|*海|支付宝|5\n|2020-11-06|*龙|微信|6.66|软件好，但用不了\n|2020-11-08|lty2002|QQ|1.88|右键管理好评！\n|2020-11-09|*熊|微信|1|加油\n|2020-11-09|m*s|微信|5|支持一下！CMM\n|2020-11-15|*德|微信|1\n|2020-11-20|**骅|支付宝|1\n|2020-11-24|*师|微信|10\n|2020-11-25|*城|微信|1\n|2020-11-27|*文|微信|3\n|2020-12-05|*勋|支付宝|0.5\n|2020-12-05|**宇|支付宝|9.9\n|2020-12-06|*經|微信|1\n|2020-12-07|*白|微信|1\n|2020-12-11|F*n|微信|5|加油大佬\n|2020-12-11|匿名|支付宝|10|匿名捐赠\n|2020-12-12|*Y|微信|3\n|2020-12-18|*烁|支付宝|5|右键管理软件很好用，感谢！\n|2020-12-18|*班|微信|5|加油\n|2020-12-25|*贵|微信|10|点赞！\n|2020-12-31|*昊|支付宝|15|支持一下，大佬继续加油\n|2021-01-03|匿名|微信|4\n|2021-01-03|s*h|微信|2\n|2021-01-06|*檬|微信|1\n|2021-01-09|*。|微信|2\n|2021-01-09|**璐|支付宝|5|支持开源\n|2021-01-11|*%|微信|1\n|2021-01-13|*犇|微信|3|辛苦，喝瓶肥宅快乐水\n|2021-01-15|*柚|微信|1\n|2021-01-15|**轩|支付宝|10\n|2021-01-23|**政|支付宝|1.88|支持大佬\n|2021-01-26|*宁|微信|10|软件很好用，支持你\n|2021-01-28|*闯|支付宝|5\n|2021-01-28|m*c|微信|4\n|2021-01-28|*闯|支付宝|5\n|2021-02-02|*强|微信|1\n|2021-02-04|i*y|微信|5|cmm太好用了 救大命\n|2021-02-06|F*t|微信|1|感谢作者，牛年牛牛牛\n|2021-02-10|L*g|微信|2\n|2021-02-11|戴*n|微信|5|太好用了，第一次捐赠\n|2021-02-12|*奕|支付宝|2.8|真不错\n|2021-02-18|**凯|支付宝|6|方便好用，支持你\n|2021-02-24|**方|支付宝|2\n|2021-02-25|闭*g|微信|3|请大佬喝饮料🥤\n|2021-02-26|**海|支付宝|30\n|2021-02-26|*觉|微信|1.6\n|2021-02-28|*奇|微信|10\n|2021-03-02|*瑜|微信|3\n|2021-03-04|**方|支付宝|2\n|2021-03-05|*科|支付宝|1\n|2021-03-10|*y|微信|6.66\n|2021-03-12|*禹|支付宝|5\n|2021-03-12|*游|微信|50|谢谢您的软件\n|2021-03-13|k*h|微信|6.66|右键管理强迫症福音\n|2021-03-13|*🍊|微信|10|软件好用，十分感谢！\n|2021-03-16|**骏|支付宝|0.1\n|2021-03-16|**华|支付宝|5\n|2021-03-19|**阳|支付宝|1|感谢帮我移除了天翼云盘右键菜单\n|2021-03-23|*👀|微信|6.66\n|2021-03-25|**楠|支付宝|1\n|2021-03-29|花*.|微信|3|挺好用哒哒\n|2021-03-30|*珊|微信|10\n|2021-04-02|**霖|支付宝|10\n|2021-04-03|**科|支付宝|6\n|2021-04-08|**帅|支付宝|2\n|2021-04-11|*财|微信|2|菜单管理工具太棒了\n|2021-04-12|**基|支付宝|5|请喝维他奶\n|2021-04-13|**方|支付宝|4\n|2021-04-14|**明|支付宝|50\n|2021-04-21|*。|微信|5\n|2021-04-22|生鲜鱼弱|微信|6.66|加油\n|2021-04-26|**彬|支付宝|6.66|大佬加油！！！\n|2021-04-28|*浦|微信|6.66\n|2021-04-29|j*y|微信|0.5|清理右键菜单\n|2021-05-06|*越|支付宝|3\n|2021-05-08|**泽|支付宝|3\n|2021-05-10|G*H|微信|5\n|2021-05-11|j*k|微信|1|谢谢！\n|2021-05-14|*辰|微信|20|谢谢您的右键管理程序\n|2021-05-16|L.E.T|QQ|1.59|真的好用，比电脑管家好多\n|2021-05-18|B*n|微信|10\n|2021-05-21|千年等一回|QQ|21|我很想交你这个朋友\n|2021-05-24|L*g|微信|2\n|2021-05-24|o*1|微信|3|很好用的软件\n|2021-06-02|*亮|微信|6.66\n|2021-06-05|*本|微信|100\n|2021-06-05|*ɞ|微信|6.66|希望能继续更新下去..\n|2021-06-06|**东|支付宝|1\n|2021-06-07|*扬|微信|5\n|2021-06-07|*豆|微信|6.66|非常好的软件，感谢！\n|2021-06-08|**辉|支付宝|1\n|2021-06-08|*潘|微信|1\n|2021-06-17|-*D|微信|0.88|加油\n|2021-06-20|**伟|支付宝|6.66|治好了右击目录就卡机转圈圈的毛病\n|2021-06-20|*W|微信|1|金额很少，但非常感谢\n|2021-06-21|*|微信|10|感谢UP主\n|2021-06-23|H*g|微信|10\n|2021-06-24|**禹|支付宝|9\n|2021-06-26|**桂|支付宝|20\n|2021-06-26|*鹅|微信|25|非常感谢\n|2021-06-26|**璘|支付宝|3\n|2021-06-30|J*n|微信|8.88|良心之作！\n|2021-06-30|L*g|微信|2\n|2021-07-03|*晨|微信|100|感谢做出的付出\n|2021-07-03|对*.|微信|0.66|大佬牛逼\n|2021-07-04|A*a|微信|5\n|2021-07-04|游侠|QQ|10|支持开发\n|2021-07-05|H*d|微信|10\n|2021-07-07|l*5|微信|0.66|感谢，强迫症的福音\n|2021-07-10|*齊|微信|5|谢谢你开发的右键管理\n|2021-07-10|**兴|支付宝|10|省心了(●°u°●) 」\n|2021-07-11|*们|微信|5|右键管理很好用，谢谢\n|2021-07-13|2*9|微信|5\n|2021-07-13|*Z|微信|6|谢谢你的作品，好用\n|2021-07-14|A*u|微信|5\n|2021-07-15|**力|支付宝|6|加油\n|2021-07-16|*缘|微信|8\n|2021-07-16|H*F|微信|16\n|2021-07-19|*羊|微信|1\n|2021-07-22|*早|微信|1\n|2021-07-26|*滨|支付宝|19.9\n|2021-07-29|**忠|支付宝|0.13\n|2021-07-31|玖兰百夜烟花|QQ|2\n|2021-07-31|*祝|微信|1\n|2021-08-02|L*y|微信|8|很感谢你的菜单管理器\n|2021-08-02|404 Not Found|QQ|1\n|2021-08-05|L、|微信|5|小小心意，请笑纳\n|2021-08-09|*家|微信|3|两个平台都星标了加油\n|2021-08-09|五水合小学生|QQ|11.64\n|2021-08-11|L*e|微信|2\n|2021-08-13|*为|微信|5|软件不错\n|2021-08-13|V*d|微信|9.99|非常nb\n|2021-08-15|*ή|微信|1.11|好工具，感谢开发共享\n|2021-08-16|*凡|微信|3\n|2021-08-16|*天|微信|1|感谢蓝点\n|2021-08-18|*戳|微信|0.2\n|2021-08-18|x*p|微信|8\n|2021-08-18|淡***|支付宝|20|🧧喝杯奶茶，提前祝你生日快乐\n|2021-08-22|S*l|微信|10|难得的好软件，努力\n|2021-08-23|*焱|微信|5\n|2021-08-24|L*g|微信|1.5\n|2021-08-24|K*x|微信|15\n|2021-08-25|*📷|微信|0.8|白嫖的有点不好意思\n|2021-08-27|Z*C|微信|0.99\n|2021-08-28|p*5|微信|20|软件很不错哈！\n|2021-09-01|**方|支付宝|2\n|2021-09-02|L*Z|微信|0.23\n|2021-09-04|B*D|微信|1\n|2021-09-04|*。|微信|5|买瓶脉动喝 软件不错\n|2021-09-05|*風|微信|2.56\n|2021-09-05|*永|支付宝|1\n|2021-09-09|**源|支付宝|5\n|2021-09-12|F*t|微信|0.1|捐赠\n|2021-09-13|*起|微信|3|感谢作者~\n|2021-09-13|呦吼|QQ|2.69|软件很好~喵喵喵睡觉了\n|2021-09-14|i*p|微信|10\n|2021-09-16|**茗|支付宝|0.5\n|2021-09-22|*廵|微信|6.66|大佬牛逼\n|2021-09-23|*扬|微信|6.66|加油期待更多好软件\n|2021-09-25|*凯|微信|6.66|谢谢大佬\n|2021-09-27|*岩|微信|1\n|2021-09-27|H*E|微信|6.66\n|2021-09-28|*情|微信|200|太好用了 辣鸡疼熏\n|2021-09-28|*成|支付宝|10\n|2021-09-29|*来|微信|5|软件功能很好，谢谢你\n|2021-09-30|*.|微信|9.3\n|2021-10-01|**杰|支付宝|10\n|2021-10-01|**怡|支付宝|6.66|非常好用，感谢\n|2021-10-03|Pro|QQ|6.66|不错\n|2021-10-05|*若|微信|1.07\n|2021-10-05|**明|支付宝|9.9|药到病除，为作者打电话\n|2021-10-06|*科|支付宝|1\n|2021-10-07|*风|微信|20|感谢作者！\n|2021-10-07|t*n|微信|5|支持下，辛苦了\n|2021-10-09|**斗|支付宝|5\n|2021-10-09|匿名|微信|10|同学，加油！\n|2021-10-10|*。|微信|2\n|2021-10-12|**珊|支付宝|0.06|作者实在是六，先来踩个点\n|2021-10-12|**珊|支付宝|3.64|捐完去点星星\n|2021-10-12|*趣|微信|0.01\n|2021-10-13|*空|微信|3|大佬加油，喝瓶水\n|2021-10-13|**伟|支付宝|0.1\n|2021-10-17|**珊|支付宝|1.08|啥时候更新捐赠名单呀？\n|2021-10-18|**珊|支付宝|0.53\n|2021-10-22|**丽|支付宝|1\n|2021-10-23|d*e|微信|10|软件很好用！\n|2021-10-25|*₆|微信|3.07|加油，零钱全给你了\n|2021-10-26|B*n|微信|0.01|希望开发更多绿色软件\n|2021-11-03|**林|支付宝|5\n|2021-11-03|*鹏|支付宝|1\n|2021-11-06|*洲|支付宝|10\n|2021-11-07|*行|微信|16.88|感谢，管理右键很方便\n|2021-11-07|J*n|微信|10|感谢你的程序\n|2021-11-08|*维|支付宝|30|加油，工具很好用\n|2021-11-09|**杰|支付宝|5\n|2021-11-09|M*e|微信|3\n|2021-11-11|*鑫|微信|66\n|2021-11-11|*饭|微信|5|牛逼！解我心头之恨！\n|2021-11-12|*界|微信|0.2\n|2021-11-13|**强|支付宝|1|感谢你为我的电脑带来了整洁\n|2021-11-14|**凯|支付宝|50\n|2021-11-14|*博|支付宝|5|amd驱动安装估计没注意中招了...\n|2021-11-18|H*z|微信|5\n|2021-11-19|**山|支付宝|1.68\n|2021-11-22|*笨|微信|10|右键管理，蚊子腿见谅\n|2021-11-23|C*n|微信|50|好用\n|2021-11-25|*良|支付宝|6.66\n|2021-11-26|***昱|支付宝|10|右键管理软件很好用，非常喜欢\n|2021-11-28|L*u|微信|10\n|2021-11-28|半凡|QQ|1\n|2021-11-30|*石|微信|5|支持右键管理\n|2021-11-30|*辰|微信|10\n|2021-12-02|K*a|微信|4\n|2021-12-04|*界|微信|8.88|谢谢软件，治好强迫症\n|2021-12-07|*香|微信|1\n|2021-12-07|**源|支付宝|5\n|2021-12-07|*诃|微信|10\n|2021-12-07|**轩|支付宝|1|Windows右键管理简单好用。很棒！\n|2021-12-10|*光|微信|1|莫要嫌少，买个糖吃\n|2021-12-12|**庆|支付宝|2|感谢，为我的右键带来了整洁\n|2021-12-13|*燃|微信|10\n|2021-12-13|*η|微信|1|good software\n|2021-12-15|*红|微信|1|右键管理好\n|2021-12-15|*瑞|支付宝|5\n|2021-12-22|*的|微信|20\n|2021-12-24|*森|微信|1.68|软件可以，加油\n|2021-12-24|**雷|支付宝|5|好用的软件，加油！\n|2021-12-24|D*d|微信|5\n|2021-12-28|**璘|支付宝|15\n|2021-12-30|*扰|微信|20\n|2021-12-31|*叔|微信|1\n|2022-01-03|*叔|微信|1\n|2022-01-03|**瑜|支付宝|5\n|2022-01-05|j*o|微信|66.66|作者加油！捐赠好少\n|2022-01-09|*天|微信|5|解决了困扰很久的问题\n|2022-01-09|*河|微信|20|请你喝杯奶茶软件很好用"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "README-en.md",
    "content": "**[简体中文](README.md)** | **English**\n# ContextMenuManager\n![](Logo/Logo.png)\n------\n> 🖱️ A program to manage the Windows right-click context menu.\n\n## Download the binary\n* [Github Releases][GitHub Releases] or [Gitee Releases][Gitee Releases]\n* Download the zip file (recommended) or the exe file in the Assets list\n* About .NET versions: the .NET 3.5 and .NET 4.0 both are compatible with Windows Vista, 7, 8, 8.1, 10.\n Win7 comes with .NET 3.5, Win8, 8.1, 10 come with .NET 4.0 and up. Vista does not come with .NET 3.5 or 4.0. <br> You may need to install the appropriate [.NET Framework Runtime Library][.NET Framework Runtime Library].\n\n## Key features\n* Enable and disable context menu options for files, folders, submenus (e.g. open, send to), Internet Explorer, and Win+X\n* Modify menu names and icons\n* Delete context menu entries\n* Navigate menus in the registry or File Explorer\n* Add custom menu items and commands\n\n## Supported systems and features\n* Windows Vista, 7, 8, 8.1, 10\n* 32 and 64 bit operating systems\n* Support for display scaling, optimal at 150% DPI\n* localization support: contributions are welcome\n\n## Screenshots\n![](Screenshot/Screenshot-en.png)\n\n## Third-party resources\n* Main program icon from [EasyIcon][EasyIcon]<br>![][AppIcon]\n* [Button icons][AppImage] from [Alibaba Iconfont][IconFont]![](Screenshot/AppImage.png)\n\n## Updates\n* Program and dictionary updates can be installed within the program, overwriting the original files.\n* Due to limitations with Github and Gitee Raw, the program can only check for updates once a month. <br> The latest updates can always be found on [Github Releases][GitHub Releases] or [Gitee Releases][Gitee Releases].\n\n## Notices\n* Some special menu items (Shell extensions, file encryption(&Y)) may not be displayed in the context menu, but will still show as enabled within the program; this is normal.\n* Different context menu manager programs may use different methods for disabling menu options. Using multiple managers at the same time is not recommended. While other programs may use destructive methods, this program utilizes the registry keys provided by the system to hide menu items when possible.\n<br>If you have used other context menu managers in the past, use that program to restore the menu items before using this one in order to avoid any potential issues.\n* This program is not designed to perform clean uninstalls; however, it can help you find the registry and file locations of menu items so that they can be modified. If you are not familiar with such operations, it is recommended you use the enable/disable functions only.\n\n## Contact author\n* This program was developed independently by me (BluePointLilac), though I would like to thank [PcMoe][PcMoe] admin @坑晨 for answering my questions. There will inevitably be bugs, so any reports and suggestions are welcome.\n* My Bilibili page: [蓝点lilac][Bilibili]（Follow me!）\n* My e-mail: 1617859183@qq.com\n\n## Donations\nThis program is completely free of charge; if you find this program useful, you can donate in yuan by scanning the QR codes below（WeChat, Alipay, QQ) \n<br>Any amount is welcome，thank you for your understanding and support! Please also don't forget to star this repo (It means a lot to me!）<br>[Donate List](Donate.md)<br>![][Donate]\n\n  [EasyIcon]: https://www.easyicon.net/1208132-mouse_icon.html\n  [AppIcon]: ContextMenuManager/Properties/AppIcon.ico\n  [AppImage]: ContextMenuManager/Properties/Resources/Images\n  [IconFont]: https://www.iconfont.cn\n  [HashLnk]: https://github.com/riverar/hashlnk\n  [GitHub Releases]: https://github.com/BluePointLilac/ContextMenuManager/releases\n  [Gitee Releases]: https://gitee.com/BluePointLilac/ContextMenuManager/releases\n  [PcMoe]: http://www.pcmoe.net\n  [Bilibili]: https://space.bilibili.com/34492771\n  [Donate]: ContextMenuManager/Properties/Resources/Images/Donate.png\n  [.NET Framework Runtime Library]: https://dotnet.microsoft.com/download/dotnet-framework"
  },
  {
    "path": "README.md",
    "content": "**简体中文** | **[English](README-en.md)**\n# ContextMenuManager\n![](Logo/Logo.png)\n------\n> 🖱️ 一个纯粹的Windows右键菜单管理程序\n\n## 程序下载\n* [最新版本][Latest]<br>\n  [GitHub Releases][GitHub Releases]<br>\n  [Gitee Releases][Gitee Releases]<br>\n* 下载说明：在Assets文件列表里面下载zip（建议）或者直接下载exe\n* .NET版本说明：程序分为.NET3.5版和.NET4.0版，均适用于Win10、8.1、8、7、Vista系统<br>\n  win7自带.NET3.5，win8、win8.1、win10自带.NET4.0以上版本，Vista系统既不自带.NET3.5也不自带4.0以上版本<br>\n  自带.NET可直接运行程序，不自带则需要安装对应版本的[.NET Framework运行库][.NET Framework]\n\n## 主要功能\n* 启用或禁用文件、文件夹、新建、发送到、打开方式、自定义文件格式、IE浏览器、WinX等右键菜单项目\n* 对上述场景右键菜单项目进行修改名称、修改图标、导航注册表位置、导航文件位置、永久删除等操作\n* 对上述场景右键菜单自定义添加项目，自定义菜单命令\n\n## 兼容性能\n* 适用于Win10、8.1、8、7、Vista\n* 适用于 64bit、32bit CPU 操作系统\n* 适用于高分屏，最佳显示缩放比为150%\n* 程序支持国际化多语言显示，欢迎为此程序制作语言字典\n\n## 运行截图\n![](Screenshot/Screenshot.png)\n\n## 资源引用\n* 程序主图标来自 [EasyIcon][EasyIcon]<br>\n![][AppIcon]\n* [程序按钮图标][AppImage] 主要来自于 [阿里巴巴矢量图标资源库][IconFont]<br>\n![](Screenshot/AppImage.png)\n\n## 温馨提示\n* 程序需要对大量的注册表项和文件进行读写删改操作，这些行为比较敏感，<br>\n可能会被 Windows Defender 等误报为病毒，如发生此情况请自行添加进白名单。\n\n* 一些特殊菜单项可能会受到其他因素影响导致不会直接显示在右键菜单中，<br>但是按照程序使用的通用规则在此程序中仍会显示为启用，这是正常的现象。\n\n* 每个右键管理程序禁用菜单方法可能不同，建议不要同时使用多个右键菜单管理程序，<br>\n大部分程序使用简单暴力的备份删除法，此程序尽可能使用了系统提供的键值进行隐藏，<br>\n通过其他程序禁用的菜单项目。请先使用对应程序还原，不然可能无法在此程序中看到它。\n\n* 此程序不用于清理未卸载干净的程序，但是可以帮助你快速定位菜单项相关注册表位置和文件位置，<br>你可以根据相关内容进行你的操作。如果你是一个电脑小白，建议只使用启用\\禁用功能。\n\n## 联系作者\n* 程序由我个人独立开发，当然也要感谢 [萌研社][PcMoe] 站长 @坑晨 平时的答疑解惑。<br>\n能力有限，难免出现一些Bug，欢迎大家积极反馈Bug和提出优化建议。\n* 个人B站：[蓝点lilac][Bilibili]（欢迎大家关注我！）\n* 个人邮箱：1617859183@qq.com\n\n## 捐赠作者\n此程序完全免费，如果你觉得这个程序对你有所帮助，可以通过扫面下方二维码（微信、支付宝、QQ）<br>\n进行捐赠，金额请随意，谢谢你的理解和支持！更加期待你为此项目点亮Star（这对我很重要！）<br>\n[捐赠名单](Donate.md)<br>![][Donate]\n\n## 项目收藏\n[![Stargazers over time](https://starchart.cc/BluePointLilac/ContextMenuManager.svg)](https://starchart.cc/BluePointLilac/ContextMenuManager)\n\n  [Latest]: https://github.com/BluePointLilac/ContextMenuManager/releases/latest\n  [GitHub Releases]: https://github.com/BluePointLilac/ContextMenuManager/releases\n  [Gitee Releases]: https://gitee.com/BluePointLilac/ContextMenuManager/releases\n  [.NET Framework]:https://dotnet.microsoft.com/download/dotnet-framework\n  [EasyIcon]: https://www.easyicon.net/1208132-mouse_icon.html\n  [AppIcon]: ContextMenuManager/Properties/AppIcon.ico\n  [AppImage]: ContextMenuManager/Properties/Resources/Images\n  [IconFont]: https://www.iconfont.cn\n  [PcMoe]: http://www.pcmoe.net\n  [Bilibili]: https://space.bilibili.com/34492771\n  [Donate]: ContextMenuManager/Properties/Resources/Images/Donate.png\n"
  },
  {
    "path": "Update.ini",
    "content": ";自3.3.0.0版本以后使用新的更新模块，此文件不再使用\n\n[Update]\nVersion=3.3.3.0\nUrl=https://github.com/BluePointLilac/ContextMenuManager/releases/download/3.3.3.0/ContextMenuManager.zip\nInfo=【更新描述】\\n(1).极大程度地优化了交互体验；\\n(2).扩充了更多的程序字典；\\n(3).修复已知Bug，优化大量代码。\n"
  },
  {
    "path": "languages/ar-DZ عربية",
    "content": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionary are escaped with \\r\\n or \\n\n\n\n;If you want to help the author add other language dictionaries to this program, you can modify this text and save it in the .\\config\\languages folder,\n\n\n;For example, save the American English dictionary as en-US.ini, and assign en-US English to [General]\\Language\n\n\n;Fork the project on Github or Gitee and submit an application to me, or send the file directly to the mailbox 1617859183@qq.com \n\n\n\n\n\n[General]\n\n\nAppName = مدير قائمة السياق Windows\n\n\nLanguage = ar-DZ عربية\n\n\nTranslator = بوزيد زروق\n\n\nTranslatorUrl = https://github.com/bouzidzerougdz\n\n\n\n\n\n[ToolBar]\n\n\nHome = الرئيسية\n\nType = أنواع الملفات\n\nRule = قواعد أخرى\n\nRefresh = تحديث\n\nAbout = حول\n\n\n\n\n\n[SideBar]\n\nFile = ملفات\n\nFolder = مجلدات\n\nDirectory = مجلدات بمحتوى\n\nBackground = خلفية\n\nDesktop = سطح المكتب\n\nDrive = محركات\n\nAllObjects = كل الكائنات\n\nComputer = الكمبيوتر\n\nRecycleBin = سلة المهملات\n\nLibrary = المكتبات\n\nNew = إنشاء\n\nSendTo = إرسال إلى\n\nOpenWith = فتح بواسطة\n\nWinX = قائمة Win+X\n\n\n\n\n\n\n\nLnkFile = روابط (.lnk)\n\nUwpLnk = روابط (.lnk) لتطبيقات UWP\n\nExeFile = ملفات التنفيذ (.exe)\n\nCustomExtension = تمديدات الملفات\n\nPerceivedType = نوع الملف\n\nDirectoryType = نوع المجلد\n\nUnknownType = نوع الملف غير معروف\n\nMenuAnalysis = تحليل القائمة\n\n\n\n\n\nEnhanceMenu = تعزيز القائمة\n\nDetailedEdit = تحرير مفصل\n\nDragDrop = السحب والإفلات بزر الماوس الأيمن\n\nPublicReferences = المراجع العامة\n\nCustomRegPath = مسار التسجيل المخصص\n\nGuidBlocked = GUID محظور\n\nIEMenu = قائمة سياق Internet Explorer\n\n\n\n\n\nAppSetting = إعدادات التطبيق\n\nAppLanguage = لغة التطبيق\n\nCheckUpdate = التحقق من التحديث\n\nDictionaries = مجلد البرنامج\n\nAboutApp = معلومات عن التطبيق\n\nDonate = التبرع للمؤلف\n\n\n\n\n\n[StatusBar]\n\n\nFile = قائمة السياق لجميع أنواع الملفات\n\nFolder = قائمة السياق لجميع أنواع المجلدات\n\nDirectory = قائمة السياق لجميع المجلدات التي تحتوي على ملفات\n\nBackground = قائمة السياق لجميع المجلدات وخلفية سطح المكتب\n\nDesktop = قائمة السياق لسطح المكتب\n\nDrive = قائمة السياق لجميع الأقراص\n\nAllObjects = قائمة السياق لجميع كائنات النظام الملفاتي (بما في ذلك الملفات والمجلدات)\n\nComputer = قائمة السياق لهذا الكمبيوتر\n\nRecycleBin = قائمة السياق لسلة المحذوفات\n\nLibrary = قائمة السياق لجميع المكتبات وخلفية مجلد المكتبات\n\nNew = قائمة \"إنشاء\" الفرعية لقائمة السياق للمجلدات وخلفية سطح المكتب\n\nSendTo = قائمة \"إرسال إلى\" الفرعية لجميع كائنات النظام الملفاتي\n\nOpenWith = قائمة \"فتح بواسطة\" الفرعية لجميع الملفات\n\nWinX = قائمة السياق لقائمة Win+X في Windows 8-10\n\n\n\n\n\nLnkFile = قائمة السياق للروابط\n\nUwpLnk = قائمة السياق لتطبيقات UWP في ويندوز 8-10\n\nExeFile = قائمة السياق لملفات التنفيذ exe\n\nCustomExtension = تخصيص قائمة السياق لأي امتداد ملف\n\nPerceivedType = تخصيص قائمة السياق لأي نوع من الملفات\n\nDirectoryType = تخصيص قائمة السياق لنوع معين من المجلدات\n\nUnknownType = قائمة السياق لنوع الملفات الذي لا يرتبط بأي تطبيق\n\nMenuAnalysis = تحليل موضع قائمة السياق\n\n\n\n\n\nEnhanceMenu = إضافة بعض العناصر المفيدة إلى القائمة\n\nDetailedEdit = جزء من قواعد القائمة الداخلية لبرامج خارجية، المضمنة في الكتالوج البرمجي\n\nDragDrop = عنصر في القائمة عند سحب وإسقاط بزر الماوس الأيمن\n\nPublicReferences = تعديل عناصر قائمة السياق للروابط العامة التي أضافها المستخدم\n\nCustomRegPath = تخصيص مسار القائمة السياقية في التسجيل\n\nGuidBlocked = مناسب لمشاريع ShellEx الصعبة التي تعتمد على GUID (بعض GUID معطلة)\n\nIEMenu = قائمة السياق في متصفح الإنترنت إنترنت إكسبلورر\n\n\n\n\n\n[Menu]\n\n\nChangeText = تغيير النص\n\nItemIcon = أيقونة العنصر\n\nChangeIcon = تغيير الأيقونة\n\nShieldIcon = أيقونة الدرع\n\nAddIcon = إضافة أيقونة\n\nDeleteIcon = حذف الأيقونة\n\nItemPosition = موقع العنصر\n\nSetDefault = تعيين كافتراضي\n\nSetTop = تعيين في الأعلى\n\nSetBottom = تعيين في الأسفل\n\nOtherAttributes = سمات أخرى\n\nOnlyWithShift = إظهار فقط عند الضغط على Shift\n\nOnlyInExplorer = إظهار فقط في مستكشف الملفات\n\nNoWorkingDirectory = عدم استخدام معلومات المجلد في قائمة السياق\n\nNeverDefault = عدم استخدام زر الفأرة الأيسر لتنفيذ الأوامر الافتراضية\n\nShowAsDisabledIfHidden = إذا كان العنصر معطلًا، عرضه بلون رمادي بدلاً من إخفائه\n\nDetails = تفاصيل\n\nWebSearch = البحث عبر الإنترنت\n\nChangeCommand = تغيير الأمر\n\nRunAsAdministrator = تشغيل كمسؤول\n\nFileProperties = خصائص الملف\n\nFileLocation = موقع الملف\n\nRegistryLocation = موقع التسجيل\n\nExportRegistry = تصدير التسجيل\n\nDelete = حذف العنصر\n\nDeleteReference = حذف الإشارة\n\nHandleGuid = التعامل مع GUID\n\nCopyGuid = نسخ GUID\n\nBlockGuid = حظر GUID\n\nClsidLocation = موقع CLSID\n\nAddGuidDic = إضافة قاموس GUID\n\nInitialData = تحرير البيانات الأولية للملف\n\nBeforeSeparator = عرض فوق الفاصل\n\nChangeGroup = تغيير المجموعة\n\nRestoreDefault = استعادة الافتراضيات\n\nEdit = تحرير\n\nSave = حفظ\n\nFoldAll = طي الكل\n\nUnfoldAll = فتح الكل\n\n\n\n\n\n[Dialog]\n\n\nBrowse = استعراض\n\nProgram = برنامج\n\nAllFiles = جميع الملفات\n\nRegistryFile = ملف السجل\n\nItemText = نص العنصر\n\nItemCommand = أمر العنصر في القائمة\n\nCommandArguments = وسائط الأمر\n\nSingleMenu = قائمة مستوى واحد\n\nMultiMenu = قائمة متعددة المستويات\n\nPublic = عام\n\nPrivate = خاص\n\nSelectAll = تحديد الكل\n\nInputGuid = أدخل دليل GUID المحلي\n\nAddGuidDic = إضافة دليل GUID المحلي\n\nDeleteGuidDic = حذف دليل GUID\n\nNoPerceivedType = نوع غير معروف\n\nTextFile = ملف نصي\n\nDocumentFile = مستند\n\nImageFile = ملف صورة\n\nVideoFile = ملف فيديو\n\nAudioFile = ملف صوتي\n\nCompressedFile = ملف مضغوط\n\nSystemFile = ملف نظام\n\nDocumentDirectory = مجلد المستندات\n\nImageDirectory = مجلد الصور\n\nVideoDirectory = مجلد الفيديو\n\nAudioDirectory = مجلد الصوتيات\n\nEditSubItems = تحرير العناصر الفرعية لـ \"%s\"\n\nDetailedEdit = تحرير \"%s\" بالتفصيل\n\nCheckReference = حدد العنصر في القائمة الذي ترغب في إضافة الرابط إليه\n\nCheckCopy = حدد العنصر في القائمة الذي ترغب في نسخه\n\nSelectExtension = حدد امتداد الملف\n\nSelectPerceivedType = حدد نوع الملف\n\nSelectDirectoryType = حدد نوع المجلد\n\nSelectGroup = حدد المجموعة للحفظ\n\nSelectNewItemType = حدد نوع عنصر \"إنشاء\"\n\nSelectObjectType = حدد نوع الكائن للتحليل\n\nSelectDropEffect = حدد تأثير الإسقاط الافتراضي\n\nDefaultDropEffect = افتراضيًا (نفس القرص - نقل، قرص آخر - نسخ)\n\nCopyDropEffect = نسخ (Ctrl)\n\nMoveDropEffect = نقل (Shift)\n\nCreateLinkDropEffect = إنشاء ارتباطات (Alt)\n\nDownloadLanguages = تحميل ملفات اللغة\n\nTranslateTool = أداة الترجمة\n\nDefaultText = النص الافتراضي\n\nOldTranslation = الترجمة القديمة\n\nNewTranslation = الترجمة الجديدة\n\nDonateInfo = يتم تحديث هذه القائمة من وقت لآخر. آخر تحديث: %date \\r\\n\\r\\nالإجمالي: %money يوان، %count أشخاص\n\n\n\n[Message]\n\n\nTextCannotBeEmpty = نص القائمة لا يمكن أن يكون فارغًا!\n\nCommandCannotBeEmpty = أمر القائمة لا يمكن أن يكون فارغًا!\n\nStringParsingFailed = فشل تحليل السلاسل المحلية!\n\nTextLengthCannotExceed80 = لقد أدخلت نص قائمة طويل جدًا. الحد الأقصى للطول هو 80 حرفًا!\n\nConfirmDeletePermanently = هل تريد حقًا حذف هذا العنصر نهائيًا؟\\r\\n تنبيه: لا يمكن التراجع عن هذه العملية!\n\nDeleteButCanRestore = هل تريد حقًا حذف هذا العنصر من سجل القائمة نهائيًا؟\\r\\n نظرًا لتمكين النسخ الاحتياطي التلقائي (وهو مفعل بشكل افتراضي)،\\r\\n يمكن استعادة هذا العنصر لاحقًا من مجلد النسخ الاحتياطي.\n\nConfirmDeleteReference = هل تريد حقًا حذف هذا العنصر؟\\r\\n تنبيه: سيصبح جميع العناصر التي تشير إليها هذا العنصر غير صالحة!\n\nConfirmDelete = هل تريد حقًا حذف هذا العنصر؟\n\nConfirmDeleteReferenced = هل تريد حقًا حذف هذا العنصر نهائيًا؟\\r\\n تنبيه: سيصبح جميع العناصر التي تشير إليها غير صالحة.\n\nCannotAddNewItem = لا يمكن إضافة عنصر جديد بسبب قيود النظام. الحد الأقصى لعناصر القائمة الفرعية هو 16.\n\nVistaUnsupportedMulti = ويندوز فيستا لا يدعم القوائم متعددة المستويات!\n\nCannotHideSubItem = إصدار Windows الخاص بك لا يدعم إخفاء العناصر الفرعية!\n\nUnsupportedFilename = اسم الملف غير مدعوم. ربما يكون هناك بالفعل عنصر قائمة بنفس الاسم!\n\nNoOpenModeExtension = لا يتم ربط هذا الامتداد بأي تطبيق.\\r\\n انقر بزر الماوس الأيمن فوق الملف ذو هذا الامتداد لربطه بتطبيق.\n\nCannotChangePath = لا يمكن تغيير مسار الملف!\n\nCopiedToClipboard = تم نسخه إلى الحافظة:\n\nMalformedGuid = GUID بتنسيق غير صالح\n\nHasBeenAdded = تمت إضافة هذا العنصر!\n\nSelectSubMenuMode = هذه القائمة متعددة المستويات لا تحتوي على عناصر فرعية.\\r\\n يوجد اختياران:\\r\\n ① تجعل جميع عناصر القائمة الفرعية في هذه القائمة مخصصة (الخيار الموصى به)\\r\\n ② يمكن لهذه القائمة متعددة المستويات الربط بنفس العناصر الفرعية للقوائم المتعددة المستويات الأخرى.\\r\\n انتظر الاختيار...\n\nEditInitialData = يدعم هذا البرنامج حاليًا تحرير بيانات الملفات النصية العادية فقط (.txt، .bat، إلخ).\\r\\n للأنواع الأخرى من الملفات، قم بتحرير قيمة المفتاح \"Data\" في التسجيل بنفسك.\\r\\n هل ترغب في المتابعة؟\n\nPromptIsOpenItem = هذا العنصر يحتوي على قائمة \"فتح\".\\r\\n قد تعيق العمليات الأعمى قدرتك على فتح الملفات والمجلدات.\\r\\n هل تريد المتابعة؟ (غير موصى به)\n\nSelectRegPath = الخطوات:\\r\\n1. افتح محرر التسجيل\\r\\n2. انتقل إلى المسار المستهدف\\r\\n3. أغلق محرر التسجيل.\\nهل ترغب في المتابعة؟\n\nRestartApp = سيتم إعادة تشغيل البرنامج!\n\nFileNotExists = الملف غير موجود!\n\nFolderNotExists = المجلد غير موجود!\n\nUpdateInfo = هناك إصدار جديد متاح\\r\\nالإصدار الحالي: %v1\\r\\nأحدث إصدار: %v2\\r\\nهل ترغب في تنفيذ عملية التحديث؟\n\nUpdateSucceeded = تم التحديث بنجاح!\n\nDicUpdateSucceeded = تم تحديث القواميس وملفات الترجمة.\n\nVersionIsLatest = لديك أحدث إصدار.\n\nWebDataReadFailed = فشل في جلب البيانات من الإنترنت.\n\nOpenWebUrl = هل ترغب في فتح رابط URL؟\n\nAuthorityProtection = ربما يتم حماية هذا العنصر في سجل القائمة بواسطة برنامج لضمان الأمان.\\r\\n لا يمكن تعطيله أو حذفه أو تعديله.\n\nWinXSorted = تم إعادة ترقيم بعض العناصر لتحسين الترتيب.\\r\\n يجب إعادة تشغيل مستكشف الملفات لتطبيق التغييرات.\n\nRestoreDefault = يرجى تأكيد استعادة العنصر إلى القيم الافتراضية.\n\nDeleteGroup = هل ترغب حقًا في حذف هذه المجموعة نهائيًا مع جميع عناصر القائمة الخاصة بها؟\n\n\n\n[Tip]\n\n\nRestartExplorer = عند إعادة تشغيل المستكشف، سيومض سطح المكتب. هذا أمر طبيعي.\\r\\n كما ستدخل التغييرات حيز التنفيذ أيضًا عند إعادة تشغيل الكمبيوتر وتسجيل الخروج والدخول للنظام.\n\n\nCustomFolder = إيقاف تشغيل هذا الخيار سيقوم أيضًا بإيقاف تشغيل علامة التبويب المخصصة في لوحة خصائص كائن نظام الملفات.\n\n\nSendToDrive = يعمل فقط في حالة توصيل قرص قابل للإزالة.\\r\\n يعرض كل أقسام القرص القابل للإزالة.\n\n\nBuildSendtoMenu = إيقاف تشغيل هذا الخيار سيسرع ظهور القائمة الرئيسية، ولكن سيبطئ ظهور قائمة \"إرسال\" الفرعية.\n\n\nInvalidItem = إذا كان العنصر غير صالح، سيتم إخفاء جميع عناصر القائمة تحت هذا العنصر (يُنصح بحذفه).\n\n\nEditSubItems = تحرير عناصر القائمة الفرعية\n\n\nAddReference = إضافة مرجع من مشروع الإشارات العامة\n\n\nAddFromPublic = نسخ العنصر من العام\n\n\nAddFromParentMenu = نسخ العنصر من القائمة الأم\n\n\nAddSeparator = إضافة فاصل\n\n\nDeleteGuidDic = حذف القاموس المحلي لـ GUID الذي أضافه المستخدم\n\n\nLockNewMenu = إذا تم تمكينه، فلن تتمكن البرامج الطرفية من إضافة عناصر جديدة وفرز العناصر الحالية (ويمكن إغلاقه واستعادته)\n\n\nDropOrSelectObject = إسقاط أو تحديد الكائن\n\n\nConfigPath = بعد تغيير مسار حفظ ملف التكوين والبيانات، قد تصبح بعض القوائم المحسنة التي تم تمكينها غير صالحة.\\r\\n يمكن إعادة تمكينها في القائمة المحسنة.\n\n\nCommandFiles = هذا الأمر يعتمد على ملف التكوين. عند نقل ملف التكوين، سيصبح هذا العنصر من القائمة غير صالح. يجب تمكينه مرة أخرى.\n\n\nCreateGroup = إنشاء مجموعة جديدة\n\n\nImmediatelyCheck = التحقق على الفور\n\n\n\n[Other]\n\n\nCustomFolder = تخصيص هذا المجلد...\n\nBuildSendtoMenu = إنشاء قائمة \"إرسال\" الفرعية\n\nNewItem = إنشاء عنصر قائمة جديد\n\nAddGuidBlockedItem = إضافة عنصر GUID محظور\n\nLockNewMenu = قفل القائمة الجديدة\n\nInvalidItem = عنصر القائمة غير صالح:\n\nSeparator = >>>>>> فاصل <<<<<<\n\nSelectRegPath = حدد مسار التسجيل\n\nCurrentExtension = الملحق المحدد حاليًا للملف - %s\n\nCurrentPerceivedType = نوع الملف المحدد حاليًا - %s\n\nCurrentDirectoryType = نوع المجلد المحدد حاليًا - %s\n\nCurrentFilePath = المسار الحالي للملف:\n\nCurrentRegPath = المسار الحالي في التسجيل:\n\nWinXSortable = ترتيب قائمة Win+X\n\nShowFilePath = إظهار مسار الملف في شريط الحالة\n\nOpenMoreRegedit = فتح محرر التسجيل في نافذة منفصلة\n\nOpenMoreExplorer = فتح المستكشف في نافذة منفصلة\n\nRestartExplorer = لجعل التغييرات سارية المفعول، يجب إعادة تشغيل مستكشف Windows.\n\nSwitchDictionaries = التبديل بين القواميس\n\nWebDictionaries = قواميس الويب\n\nUserDictionaries = القواميس الخاصة\n\nDictionaryDescription = القواميس\n\nGuidInfosDictionary = معلومات GUID\n\nUwpMode = وضع UWP\n\nTranslators = المترجمون\n\nDonationList = قائمة التبرعات\n\nConfigPath = مسار حفظ ملفات التكوين والبيانات\n\nAppDataDir = مجلد التطبيقات\n\nAppDir = مجلد البرنامج\n\nAutoBackup = نسخ احتياطي تلقائي للتسجيل عند حذف القائمة\n\nSetUpdateFrequency = تحديد تردد التحديث\n\nOnceAWeek = مرة كل أسبوع\n\nOnceAMonth = مرة شهريًا\n\nOnceASeason = مرة كل ثلاثة أشهر\n\nNeverCheck = أبدًا\n\nSetRequestRepo = طلب مستودع\n\nProtectOpenItem = حماية عنصر القائمة \"فتح\"\n\nWebSearchEngine = محرك البحث على الويب\n\nCustomEngine = مخصص...\n\nSetCustomEngine = تحديد محرك البحث (استخدم %s بدلاً من الكلمات المرادة البحث عنها)\n\nHideDisabledItems = إخفاء العناصر المعطلة\n\nHideSysStoreItems = إخفاء عناصر متجر النظام\n\nSetPerceivedType = تعيين نوع %s...\n\nSetDefaultDropEffect = عند السحب والإفلات -\n\nTopMost = دائمًا في المقدمة\n\n\n\n\n\nAboutApp = [التوافق] \\r\\n 1 = متوافق مع ويندوز 10، 8.1، 8، 7، فيستا \\r\\n 2 = متوافق مع نظام التشغيل بنية 64 بت و 32 بت\\r\\n 3 = متوافق مع عالية الدقة (High DPI)، مثالي بنسبة 150%\\r\\n\\r\\n[المصدر المفتوح]\\r\\n 1 = لغات البرمجة: C#، Winform، رخصة MIT\\r\\n 2 = مستودع Github: https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = مستودع Gitee: https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[تلميحات]\\r\\n 1 = يقوم هذا البرنامج بقراءة/كتابة كمية كبيرة من ملفات النظام وإدخالات التسجيل، وقد يتم اعتراضه من قبل Windows Defender لأن هذه العمليات حساسة للغاية، يرجى إضافة هذا البرنامج يدويًا إلى قائمة الاستثناءات\\r\\n\\r\\n 2 = قد تتأثر بعض العناصر الخاصة في القوائم بعوامل أخرى، قد لا تظهر في القائمة المنسدلة. \\r\\n ومع ذلك، قد تظهر لا تزال كما مفعلة في هذا البرنامج وفقًا للقواعد العامة المستخدمة من قبل البرنامج. هذا أمر طبيعي. \\r\\n\\r\\n 3 = قد يكون طريقة تعطيل القائمة لكل برنامج إدارة قائمة نصية مختلفة. لا تستخدم عدة برامج لإدارة قائمة السياق في نفس الوقت. \\r\\n معظم البرامج تستخدم طريقة بسيطة ومتقلبة للنسخ الاحتياطي والحذف. يستخدم هذا البرنامج القيم المقدمة من نظام التشغيل لإخفاء المفاتيح قدر الإمكان. \\r\\n إذا كنت قد استخدمت برنامجًا آخر لتعطيل عنصر القائمة من قبل، يرجى استخدام ذلك البرنامج لاستعادته، وإلا قد لا تتمكن من رؤيته في هذا البرنامج. \\r\\n\\r\\n 4 = لم يتم تصميم هذا البرنامج لتنظيف البرامج التي تمت إزالتها، لكن يمكن أن يساعدك في تحديد مواقع التسجيل والملفات لمثل هذه العناصر في القوائم. \\r\\n يمكنك فعل ما تشاء. إذا كنت مبتدئًا فقط (أو غير متأكد من بعض الخيارات)، فقم بتبديل مفتاح التمكين/التعطيل فقط (لتقليل مخاطر تلف نظام التشغيل).\n\n\n\nDictionaries = [وصف القاموس] \\r\\n يحتوي هذا البرنامج على عدة ملفات قاموس، وكل قاموس يحتوي على قاموس مستخدم وقاموس شبكة. \\r\\n إذا كنت ترغب في إضافة قاموس إلى هذا البرنامج، يمكنك النقر بزر الماوس الأيمن لحفظ الملف واتباع التعليمات الموجودة في الملف لإضافته. \\r\\n أرسل قاموسك إلى بريدي الإلكتروني أو قم بتقديمه على GitHub للمساهمة في هذا المشروع. \\r\\n العلامة التبويب اليمنى هي محتوى القاموس الأصلي، يمكنك تبديل العلامة التبويبية لعرضها \\r\\n\\r\\n[محتوى القاموس]\\n 1 = قاموس لغة عرض نص البرنامج (مجلد اللغات) \\r\\n 2 = قاموس أيقونات نص الدليل ShellEx (GuidInfosDic.ini) \\r\\n 3 = قاموس الإعدادات الداخلية لقائمة برامج الطرف الثالث (DetailedEditDic.xml) \\r\\n 4 = قاموس العناصر المحسّنة في القائمة (EnhanceMenusDic.xml)\n\n\n\nDonate = هذا البرنامج مجاني تمامًا. إذا وجدت هذا البرنامج مفيدًا، \\r\\n يمكنك التبرع عن طريق مسح الرمز الشريطي أدناه (WeChat، Alipay، Tencent QQ).\\r\\n يمكنك تحديد المبلغ بناءً على اختيارك. شكرًا لدعمك! كما أتمنى أن تفكر \\r\\n في إعطاء هذا المشروع نجمة على GitHub أو Gitee (هذا يعني الكثير بالنسبة لي!).\n\n\n"
  },
  {
    "path": "languages/de-DE.ini",
    "content": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionary are escaped with \\r\\n or \\n\n;If you want to help the author add other language dictionaries to this program, you can modify this text and save it in the .\\config\\languages folder,\n;For example, save the American English dictionary as en-US.ini, and assign en-US English to [General]\\Language\n;Fork the project on Github or Gitee and submit an application to me, or send the file directly to the mailbox 1617859183@qq.com \n\n[General]\nAppName = Windows Context Menu Manager\nLanguage = de-DE German\nTranslator = akaydev-coder (Deepl) \\r\\n Alex K.\nTranslatorUrl = https://github.com/akaydev-coder\n\n[ToolBar]\nHome = Home\nType = Dateitypen\nRule = Andere Regeln\nRefresh = Aktualisieren\nAbout = Über\n\n[SideBar]\nFile = Datei\nFolder = Ordner\nDirectory = Verzeichnis\nBackground = Hintergrund\nDesktop = Desktop\nDrive = Laufwerk\nAllObjects = Alle Objekte\nComputer = Dieser PC\nRecycleBin = Papierkorb\nLibrary = Bibliothek\nNew = Neu\nSendTo = Senden an\nOpenWith = Öffnen mit\nWinX = Win+X\n\nLnkFile = .lnk-Datei\nUwpLnk = UWP .lnk\nExeFile = .exe-Dateien\nCustomExtension = Benutzerdefinierte Erweiterung\nPerceivedType = Wahrgenommener Dateityp\nDirectoryType = Ordnertyp\nUnknownType = Unbekannter Dateityp\nMenuAnalysis = Menü-Analyse\n\nEnhanceMenu = Menü erweitern\nDetailedEdit = Detaillierte Bearbeitung\nDragDrop = Ziehen und Ablegen\nPublicReferences = ÖÖffentliche Referenzen\nCustomRegPath = Benutzerdefinierter Registrierungspfad\nGuidBlocked = GUID blockiert\nIEMenu = IE-Kontextmenü\n\nAppSetting = Einstellungen\nAppLanguage = Sprache\nCheckUpdate = Update prüfen\nDictionaries = Wörterbücher\nAboutApp = Software-Informationen\nDonate = Spende an den Autor\n\n[StatusBar]\nFile = Kontextmenü für alle Dateitypen\nFolder = Kontextmenü für alle Ordnertypen\nDirectory = Kontextmenü für alle Datei-Ordner\nBackground = Kontextmenü für alle Ordner- und Desktop-Hintergründe\nDesktop = Kontextmenü für den Desktop\nDrive = Kontextmenü für alle Laufwerke\nAllObjects = Kontextmenü für alle Dateisystemobjekte (einschließlich Dateien und Ordner)\nComputer = Kontextmenü für diesen PC\nRecycleBin = Kontextmenü für den Papierkorb\nLibrary = Kontextmenü für alle Bibliotheken und Bibliotheksordnerhintergründe\nNew = Menü \"Neu\" für das Kontextmenü für Ordner und Desktop Hintergrund\nSendTo = Menü \"Senden an\" für alle Dateisystemobjekte\nOpenWith = Menü \"Öffnen mit\" für alle Dateien\nWinX = Win8-Win10 Kontextmenü für das Win+X Startmenü\n\nLnkFile = Kontextmenü für alle Shortcuts\nUwpLnk = Hinzufügen einiger nützlicher Menüpunkte\nExeFile = Detaillierte Einstellungsregeln für die internen Menüs des Systems undanderer Programme\nCustomExtension = Menüpunkt beim Rechtsklick und Ziehen einer Datei\nPerceivedType = Bearbeiten der Shell-Typ-Untermenüeinträge von öffentlichen Referenzen,die von Benutzern hinzugefügt wurden\nDirectoryType = Anpassen des Kontextmenü-Registrierungspfades\nUnknownType = Geeignet für hartnäckige ShellEx-Projekte, die auf GUIDs angewiesen sind(einige GUIDs sind deaktiviert)\nMenuAnalysis = Kontextmenü im Internet Explorer\n\nEnhanceMenu = Hinzufügen einiger nützlicher Menüpunkte\nDetailedEdit = Detaillierte Einstellungsregeln für die internen Menüs des Systems und anderer Programme\nDragDrop = Menüpunkt beim Rechtsklick und Ziehen einer Datei\nPublicReferences = Bearbeiten der Shell-Typ-Untermenüeinträge von öffentlichen Referenzen, die von Benutzern hinzugefügt wurden\nCustomRegPath = Anpassen des Kontextmenü-Registrierungspfades\nGuidBlocked = Geeignet für hartnäckige ShellEx-Projekte, die auf GUIDs angewiesen sind (einige GUIDs sind deaktiviert)\nIEMenu = Kontextmenü im Internet Explorer\n\n[Menu]\nChangeText = Umbenennen\nItemIcon = Icon des Elements\nChangeIcon = Ändere Icon\nShieldIcon = Icon \"Schild\"\nAddIcon = Icon Hinzufügen\nDeleteIcon = Icon Löschen\nItemPosition = Position des Elements\nSetDefault = Standard\nSetTop = Oben anordnen\nSetBottom = Unten anordnen\nOtherAttributes = Andere Eigenschaften\nOnlyWithShift = Nur bei gedrückter Umschalttaste anzeigen\nOnlyInExplorer = Nur im Datei-Explorer anzeigen\nNoWorkingDirectory = Die Ordnerinformationen nicht im Kontextmenü verwenden\nNeverDefault = Standardmäßig niemals die linke Taste zum Ausführen von Befehlen verwenden\nShowAsDisabledIfHidden = Wenn ein Element deaktiviert ist, wird es ausgegraut, anstatt es auszublenden\nDetails = Details\nWebSearch = Web Suche\nChangeCommand = Befehl ändern\nRunAsAdministrator = Als Administrator ausführen\nFileProperties = Datei-Eigenschaften\nFileLocation = Speicherort der Datei\nRegistryLocation = Speicherort in der Registrierung\nExportRegistry = Registrierung exportieren\nDelete = Element löschen\nDeleteReference = Referenz löschen\nHandleGuid = GUID-Aktionen\nCopyGuid = GUID kopieren\nBlockGuid = GUID sperren\nClsidLocation = CLSID Speicherort\nAddGuidDic = GUID Wörterbuch hinzufügen\nInitialData = Datei-Initialdaten bearbeiten\nBeforeSeparator = Wird oberhalb des Trennzeichens angezeigt\nChangeGroup = Gruppe ändern\nRestoreDefault = Standard wiederherstellen\nEdit = bearbeiten\nSave = Speichern\nFoldAll = Alles einklappen\nUnfoldAll = Alle aufklappen\n\n[Dialog]\nBrowse = Durchsuchen\nProgram = Programm\nAllFiles = Alle Dateien\nRegistryFile = Registrierungsdatei\nItemText = Element Text\nItemCommand = Menü-Befehl\nCommandArguments = Befehlsargumente\nSingleMenu = Einstufiges Menü\nMultiMenu = Mehrstufiges Menü\nPublic = Öffentlich\nPrivate = Privat\nSelectAll = Alles auswählen\nInputGuid = Lokales GUID-Wörterbuch eingeben\nAddGuidDic = Lokales GUID-Wörterbuch hinzufügen\nDeleteGuidDic = GUID-Wörterbuch löschen\nNoPerceivedType = Typ unbekannt\nTextFile = Textdatei\nDocumentFile = Dokument-Datei\nImageFile = Bilddatei\nVideoFile = Videodatei\nAudioFile = Audiodatei\nCompressedFile = Komprimierte Datei\nSystemFile = System-Datei\nDocumentDirectory = Dokumentenordner\nImageDirectory = Bild-Ordner\nVideoDirectory = Video-Ordner\nAudioDirectory = Audio-Ordner\nEditSubItems = Untermenüpunkte für \"%s\" bearbeiten\nDetailedEdit = Bearbeiten Sie \"%s\" im Detail\nCheckReference = Markieren Sie den Menüpunkt, zu dem Sie einen Verweis hinzufügen möchten\nCheckCopy = Markieren Sie den Menüpunkt, den Sie kopieren möchten\nSelectExtension = Bitte wählen Sie eine Dateierweiterung\nSelectPerceivedType = Bitte wählen Sie einen bestimmten Dateityp aus\nSelectDirectoryType = Bitte wählen Sie einen bestimmten Ordnertyp aus\nSelectGroup = Wählen Sie, um die Gruppe zu speichern\nSelectNewItemType = Wählen Sie \"Neu\" als Objekttyp\nSelectObjectType = Wählen Sie den zu analysierenden Objekttyp\nSelectDropEffect = Standard-Drop-Effekt auswählen\nDefaultDropEffect = Standard (in das gleiche Laufwerk verschieben、von einem anderen Laufwerk kopieren)\nCopyDropEffect = Kopieren(Strg)\nMoveDropEffect = Verschieben(Shift)\nCreateLinkDropEffect = Verknüpfung erstellen(Alt)\nDownloadLanguages = Mehrsprachige Dateien herunterladen\nTranslateTool = Übersetzungstool\nDefaultText = Standardtext\nOldTranslation = Alte Übersetzung\nNewTranslation = Neue Übersetzung\nDonateInfo = Diese Liste wird von Zeit zu Zeit aktualisiert, letzte Aktualisierung: %date \\r\\n\\r\\nSumme: %money Yuan, %count Personen\n\n[Message]\nTextCannotBeEmpty = Der Menütext darf nicht leer sein!\nCommandCannotBeEmpty = Der Menübefehl darf nicht leer sein!\nStringParsingFailed = Das Analysieren der lokalisierten Zeichenfolge ist fehlgeschlagen!\nTextLengthCannotExceed80 = Der von Ihnen eingegebene Menütext ist zu lang. Die Länge darf 80 Zeichen nicht überschreiten!\nConfirmDeletePermanently = Sind Sie sicher, dass Sie dieses Element dauerhaft löschen möchten? \\r\\n Seien Sie vorsichtig, dieser Vorgang kann nicht rückgängig gemacht werden!\nDeleteButCanRestore = Sind Sie sicher, dass Sie den Registrierungseintrag dieses Menüs löschen wollen? \\r\\n Da die automatische Sicherung aktiviert ist (standardmäßig aktiviert), \\r\\n kann es nach dem Löschen aus dem Sicherungsordner wiederhergestellt werden.\nConfirmDeleteReference = Sind Sie sicher, dass Sie diesen Eintrag löschen möchten? \\r\\n Seien Sie vorsichtig, alle Einträge, die auf diesen Eintrag verweisen, werden ungültig!\nConfirmDelete = Sind Sie sicher, dass Sie diesen Eintrag löschen wollen?\nConfirmDeleteReferenced = Sind Sie sicher, dass Sie diesen Eintrag endgültig löschen wollen? \\r\\n Bitte beachten Sie, dass alle Einträge, die auf diesen Eintrag verweisen, ungültig werden.\nCannotAddNewItem = Hinzufügen nicht möglich! Das System begrenzt die maximale Anzahl von Untermenüpunkten auf 16.\nVistaUnsupportedMulti = Windows Vista unterstützt keine mehrstufigen Menüs!\nCannotHideSubItem = Ihre Version von Windows unterstützt das Ausblenden von Untermenu Einträgen nicht!\nUnsupportedFilename = Nicht unterstützter Dateiname. \\r\\n Ein Menüpunkt mit demselben Dateinamen ist möglicherweise bereits vorhanden!\nNoOpenModeExtension = Es gibt keine Anwendung, die mit dieser Erweiterung verknüpft ist. \\r\\n Klicken Sie mit der rechten Maustaste auf eine Datei dieses Typs mit dieser Erweiterung, um sie mit einer Anwendung zu verknüpfen!\nCannotChangePath = Dateipfadänderungen sind nicht erlaubt!\nCopiedToClipboard = In die Zwischenablage kopiert:\nMalformedGuid = GUID mit falschem Format\nHasBeenAdded = Dieses Element wurde hinzugefügt!\nSelectSubMenuMode = Die Anzahl der Unterpunkte im aktuellen mehrstufigen Menü ist 0. Es gibt zwei Möglichkeiten: \\r\\n ① Alle Untermenüpunkte in diesem mehrstufigen Menü sind privat (empfohlen),\\r\\n ② Das mehrstufige Menü kann auf dieselben Unterpunkte wie andere mehrstufige Menüs verweisen. \\r\\n Anspruchsvolle Auswahl...\nEditInitialData = Dieses Programm unterstützt derzeit nur die Bearbeitung der Anfangsdaten von reinen Textdateien (.txt, .bat, etc.).\\r\\n Für andere Dateitypen bearbeiten Sie bitte den Wert des Registrierungsschlüssels \"Daten\" selbst.\\r\\n Bestätigen Sie, wenn Sie den Vorgang fortsetzen möchten.\nPromptIsOpenItem = Dieses Element verfügt über ein \"Öffnen\"-Menü,\\r\\n Blindvorgänge verhindern möglicherweise das Öffnen von Dateien und Ordnern,\\r\\n Bestätigen Sie, ob Sie den Vorgang fortsetzen möchten. (Nicht empfohlen)\nSelectRegPath = Schritte: \\r\\n1. Öffnen Sie den Registrierungseditor\\r\\n2. Navigieren Sie zum Zielpfad\\r\\n3. Schließen Sie den Registrierungseditor\\nFortfahren?\nRestartApp = Das Programm wird neu gestartet!\nFileNotExists = Die Datei ist nicht vorhanden!\nFolderNotExists = Der Ordner ist nicht vorhanden!\nUpdateInfo = Eine neuere Version ist verfügbar\\r\\nAktuelle Version%v1\\r\\nNeueste Version%v2\\r\\nMöchten Sie auf die neueste Version aktualisieren?\nUpdateSucceeded = Update erfolgreich!\nDicUpdateSucceeded = Wörterbücher und mehrsprachige Dateien werden aktualisiert.\nVersionIsLatest = Die aktuelle Version ist die neueste.\nWebDataReadFailed = Die Daten konnten nicht aus dem Internet abgerufen werden.\nOpenWebUrl = Möchten Sie die URL öffnen?\nAuthorityProtection = Dieses Menüelement ist möglicherweise durch Sicherheitssoftware geschützt. Es kann nicht deaktiviert, gelöscht oder anderweitig personalisiert werden.\nWinXSorted = Einige Elemente wurden neu nummeriert, um die Sortierfunktion zu optimieren.\\r\\n Sie müssen den Datei-Explorer neu starten, bevor die Änderungen wirksam werden.\nRestoreDefault = Bestätigen Sie, um den Standardmenüpunkt wiederherzustellen.\nDeleteGroup = Sind Sie sicher, dass Sie diese Gruppe und alle darin enthaltenen Menüpunkte dauerhaft löschen möchten?\n\n[Tip]\nRestartExplorer = Nach dem Neustart des Explorers flackert der Desktop eine Zeit lang. Das ist normal.\\r\\n Durch einen Neustart oder das An- und Abmelden am PC werden die Änderungen ebenfalls wirksam.\nCustomFolder = Wenn Sie diese Option deaktivieren, wird auch die benutzerdefinierte Registerkarte \\r\\n in den Eigenschaften des Dateisystemobjekts ausgeschaltet.\nSendToDrive = Funktioniert nur, wenn ein Wechseldatenträger angeschlossen ist.\\r\\n Zeigt alle Partitionen des Wechseldatenträgers an.\nBuildSendtoMenu = Die Deaktivierung dieser Option beschleunigt das Aufklappen des Hauptmenüs \\r\\n verlangsamt aber die Aufklappgeschwindigkeit des Untermenüs \"Senden an\".\nInvalidItem = Wenn ein Menüpunkt ungültig ist, werden alle Menüpunkte \\r\\n unter diesem Punkt ausgeblendet (Löschung empfohlen).\nEditSubItems = Untermenüpunkte bearbeiten\nAddReference = Referenz aus öffentlichem Referenzprojekt hinzufügen\nAddFromPublic = Element aus öffentlichem Projekt kopieren\nAddFromParentMenu = Eintrag aus dem übergeordneten Menü kopieren\nAddSeparator = Trennzeichen hinzufügen\nDeleteGuidDic = Löschen des vom Benutzer hinzugefügten lokalen GUID-Wörterbuchs\nLockNewMenu = Sobald die Funktion aktiviert ist, kann sie Programme von Drittanbietern daran hindern, Objekte hinzuzufügen, und sie kann vorhandene Objekte sortieren (schließen und wiederherstellen).\nDropOrSelectObject = ein Objekt ablegen oder auswählen\nConfigPath = Nach einer Änderung des Speicherpfads der Konfigurations- und Datendatei werden einige der aktivierten erweiterten Menüs ungültig. Sie können im erweiterten Menü wieder aktiviert werden.\nCommandFiles = Dieser Befehl ist von der Konfigurationsdatei abhängig. Wenn Sie den Speicherort der Konfigurationsdatei verschieben, wird dieses Menüelement ungültig. Aktivieren Sie ihn wieder.\nCreateGroup = Eine neue Gruppe erstellen\nImmediatelyCheck = Jetzt prüfen\n\n[Other]\nCustomFolder = Diesen &Ordner anpassen...\nBuildSendtoMenu = Untermenü \"Senden an\" erstellen\nNewItem = Neuen Menüpunkt erstellen\nAddGuidBlockedItem = GUID-gesperrtes Element hinzufügen\nLockNewMenu = Das neue Menü sperren\nInvalidItem = Ungültiger Menüpunkt:\nSeparator = >>>>>> Separator <<<<<<\nSelectRegPath = Einen Registrierungspfad auswählen\nCurrentExtension = Die aktuell ausgewählte Dateierweiterung ist %s\nCurrentPerceivedType = Der aktuell ausgewählte wahrgenommene Dateityp ist %s\nCurrentDirectoryType = Der aktuell gewählte wahrgenommene Ordnertyp ist %s\nCurrentFilePath = Aktueller Dateipfad: \nCurrentRegPath = Aktueller Registrierungspfad:\nWinXSortable = Win+X-Menü-Sortierung einschalten\nShowFilePath = Dateipfad in der Statusleiste anzeigen\nOpenMoreRegedit = Registry-Editor in einem separaten Fenster öffnen\nOpenMoreExplorer = Öffnen des Datei-Explorers in einem separaten Fenster\nRestartExplorer = Der Windows Explorer muss neu gestartet werden, damit die Änderungen wirksam werden.\nSwitchDictionaries = Wörterbuch wechseln\nWebDictionaries = Web-Wörterbücher\nUserDictionaries = Benutzer-Wörterbücher\nDictionaryDescription = Wörterbuchbeschreibung\nGuidInfosDictionary = GUID-Informationen\nUwpMode = UWP-Module\nTranslators = Übersetzer\nDonationList = Spendenliste\nConfigPath = Speicherort der Konfigurations- und Datendateien\nAppDataDir = App Daten Verzeichnis\nAppDir = Programmverzeichnis\nAutoBackup = Automatisches Sichern der Registrierung beim Löschen von Menüs\nSetUpdateFrequency = Wie oft die Aktualisierung überprüft werden soll\nOnceAWeek = Einmal pro Woche\nOnceAMonth = Einmal im Monat\nOnceASeason = Einmal alle drei Monate\nNeverCheck = Niemals\nSetRequestRepo = Repo anfordern\nProtectOpenItem = Den Menüpunkt \"Öffnen\" schützen\nWebSearchEngine = Suchmaschine, die für die Websuche verwendet wird\nCustomEngine = Benutzerdefiniert...\nSetCustomEngine = Suchmaschine definieren (%s anstelle von Suchbegriffen verwenden) \nHideDisabledItems = Deaktivierte Elemente ausblenden\nHideSysStoreItems = Systemeinträge ausblenden\nSetPerceivedType = %s wahrgenommenen Typ einstellen...\nSetDefaultDropEffect = Standard-Dropeffekt einstellen\nTopMost = Immer an erster Stelle\n\nAboutApp = [Kompatibilität] \\r\\n 1 = Kompatibel mit Win10、8.1、8、7、Vista \\r\\n 2 = Kompatibel mit 64bit、32bit OS\\r\\n 3 = High DPI kompatibel, optimal mit 150%\\r\\n\\r\\n[Open Source]\\r\\n 1 = Programmiersprachen: C sharp，Winform，MIT License\\r\\n 2 = Github repo：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee repo：https://gitee. com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[Hinweise]\\r\\n 1 = Dieses Programm liest/schreibt eine große Menge an Systemdateien und Registrierungseinträgen, \\r\\n es kann von Windows Defender markiert werden, da diese Vorgänge hochsensibel sind, bitte fügen Sie dieses Programm manuell zur Ausschlussliste hinzu\\r\\n\\r\\n 2 = Einige spezielle Menüelemente können durch andere Faktoren beeinflusst werden, sie werden möglicherweise nicht im Kontextmenü angezeigt. \\r\\n Es kann jedoch sein, dass sie in diesem Programm gemäß den allgemeinen Regeln, die das Programm verwendet, weiterhin als aktiviert angezeigt werden. Dies ist normal. \\r\\n\\r\\n 3 = Die Methode zum Deaktivieren des Menüs kann für jedes Kontextmenü-Verwaltungsprogramm unterschiedlich sein. Verwenden Sie nicht mehrere Kontextmenü-Verwaltungsprogramme gleichzeitig. \\r\\n Die meisten Programme verwenden eine einfache und flüchtige Sicherungs-Löschmethode. Dieses Programm verwendet die vom Betriebssystem bereitgestellten Schlüsselwerte, um Tasten so weit wie möglich auszublenden. \\r\\n Wenn Sie zuvor mit anderen Programmen einen Menüpunkt deaktiviert haben, verwenden Sie bitte dieses Programm, um ihn wiederherzustellen, da Sie ihn sonst in diesem Programm möglicherweise nicht sehen können. \\r\\n\\r\\n 4 = Dieses Programm ist nicht dafür gedacht, Programme zu bereinigen, die deinstalliert wurden, aber es kann Ihnen dabei helfen, die Registrierung und die Dateispeicherorte solcher Menüpunkte zu finden.\\r\\n Sie können tun, was Sie wollen. Wenn Sie ein Neuling sind (oder sich bei einigen Optionen unsicher sind), schalten Sie nur den Schalter enable\\disable um (um das Risiko einer Beschädigung des Betriebssystems zu verringern).\n\nDictionaries = [Wörterbuchbeschreibung] \\r\\n Dieses Programm hat mehrere Wörterbuchdateien, und jedes Wörterbuch hat ein Benutzerwörterbuch und ein Netzwerkwörterbuch. \\r\\n Wenn Sie ein Wörterbuch zu diesem Programm hinzufügen möchten, können Sie mit der rechten Maustaste auf die Datei klicken, um sie zu speichern, und den Anweisungen in der Datei folgen, um sie hinzuzufügen. \\r\\n Senden Sie Ihr Wörterbuch an meine E-Mail oder senden Sie es an GitHub, um Ihren Beitrag zu diesem Projekt zu leisten. \\r\\n Die rechte Registerkarte ist der ursprüngliche Inhalt des Wörterbuchs, Sie können die Registerkarte umschalten, um ihn zu sehen \\r\\n\\r\\n[Wörterbuchinhalt]\\r\\n 1 = Wörterbuch für die Programmanzeigetext-Sprache (Verzeichnis Languages) \\r\\n 2 = Wörterbuch für den ShellEx-Menüpunkt GUID-Text-Icon (GuidInfosDic. ini) \\r\\n 3 = Wörterbuch für interne Einstellungen von Drittanbieterprogrammen (DetailedEditDic.xml) \\r\\n 4 = Wörterbuch für erweiterte Menüelemente (EnhanceMenusDic.xml)\n\nDonate = Dieses Programm ist völlig kostenlos. Wenn Sie diese Software hilfreich finden,\\r\\n können Sie spenden, indem Sie den QR-Code unten scannen (WeChat, Alipay, Tencent QQ).\\r\\n Der Betrag ist Ihnen überlassen. Vielen Dank für Ihre Unterstützung! Ich hoffe auch, dass Sie in Betracht ziehen, dieses Projekt auf Github oder Gitee zu veröffentlichen (das bedeutet mir sehr viel!).\n"
  },
  {
    "path": "languages/en-US.ini",
    "content": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionary are escaped with \\r\\n or \\n\r\n;If you want to help the author add other language dictionaries to this program, you can modify this text and save it in the .\\config\\languages folder,\r\n;For example, save the American English dictionary as en-US.ini, and assign en-US English to [General]\\Language\r\n;Fork the project on Github or Gitee and submit an application to me, or send the file directly to the mailbox 1617859183@qq.com \r\n\r\n[General]\r\nAppName = Windows Context Menu Manager\r\nLanguage = en-US English\r\nTranslator = mimmiepower (Google Translate) \\r\\n Geoff B. \\r\\n Jing\r\nTranslatorUrl = https://github.com/mimmiechan \\r\\n https://github.com/geoff-B \\r\\n https://github.com/delgh1\r\n\r\n[ToolBar]\r\nHome = Home\r\nType = File Types\r\nRule = Other Rules\r\nRefresh = Refresh\r\nAbout = About\r\n\r\n[SideBar]\r\nFile = File\r\nFolder = Folder\r\nDirectory = Directory\r\nBackground = Background\r\nDesktop = Desktop\r\nDrive = Disk\r\nAllObjects = All objects\r\nComputer = This PC\r\nRecycleBin = Recycle Bin\r\nLibrary = Library\r\nNew = New\r\nSendTo = Send to\r\nOpenWith = Open with\r\nWinX = Win+X\r\n\r\nLnkFile = .lnk file\r\nUwpLnk = UWP .lnk\r\nExeFile = .exe files\r\nCustomExtension = Specific file type\r\nPerceivedType = Perceived file type\r\nDirectoryType = Folder type\r\nUnknownType = Unknown file type\r\nMenuAnalysis = Menu Analysis\r\n\r\nEnhanceMenu = Menu ehancements\r\nDetailedEdit = Detailed editing\r\nDragDrop = Drag drop\r\nPublicReferences = Public references\r\nCustomRegPath = Custom registry path\r\nGuidBlocked = GUID blocked\r\nIEMenu = IE context menu\r\n\r\nAppSetting = Settings\r\nAppLanguage = Language\r\nCheckUpdate = Check Update\r\nDictionaries = Program folder\r\nAboutApp = Software information\r\nDonate = Donate to the author\r\n\r\n[StatusBar]\r\nFile = Context menu for all file types\r\nFolder = Context menu for all folder types\r\nDirectory = Context menu for all file folders\r\nBackground = Context menu for all folder and desktop backgrounds\r\nDesktop = Context menu for the Desktop\r\nDrive = Context menu for all disk drives\r\nAllObjects = Context menu for all file system objects (including files and folders)\r\nComputer = Context menu for This PC\r\nRecycleBin = Context menu for the Recycle Bin\r\nLibrary = Context menu for all Libraries and Library folder background\r\nNew = \"New\" menu for the context menu for folder and desktop background\r\nSendTo = \"Send to\" menu for all file system objects\r\nOpenWith = \"Open With\" menu for all files\r\nWinX = Win8-Win10 context menu for the Win+X Start Menu\r\n\r\nLnkFile = Context menu for all shortcuts\r\nUwpLnk = Context menu for all Win10, Win8 UWP apps\r\nExeFile = Context menu for .exe executable files\r\nCustomExtension = Customize the context menu for any file type\r\nPerceivedType = Customize the context menu for the specified perceived file\r\nDirectoryType = Customize the context menu for the specified folder type\r\nUnknownType = Context menu for file with a file type that are not associated with any app\r\nMenuAnalysis = Analyze the context menu location\r\n\r\nEnhanceMenu = Add some useful menu items\r\nDetailedEdit = Detailed setting rules for the internal menus of the system and other programs\r\nDragDrop = Menu item when right-clicking and dragging a file\r\nPublicReferences = Edit the Shell type sub-menu items of public references added by users\r\nCustomRegPath = Costomize the context menu registry path\r\nGuidBlocked = Suitable for stubborn ShellEx projects that rely on GUIDs (some GUIDs are disabled)\r\nIEMenu = Context menu in Internet Explorer\r\n\r\n[Menu]\r\nChangeText = Rename\r\nItemIcon = Item icon\r\nChangeIcon = Change icon\r\nShieldIcon = Shield icon\r\nAddIcon = Add icon\r\nDeleteIcon = Delete icon\r\nItemPosition = Item location\r\nSetDefault = Default\r\nSetTop = Put on top\r\nSetBottom = Put on the bottom\r\nOtherAttributes = Other properties\r\nOnlyWithShift = Show only while holding Shift\r\nOnlyInExplorer = Show only in File Explorer\r\nNoWorkingDirectory = Do not use the folder information in the context menu\r\nNeverDefault = Never use the left button to execute commands by default\r\nShowAsDisabledIfHidden = If item is deactivated, gray out instead of hiding it\r\nDetails = Details\r\nWebSearch = Web search\r\nChangeCommand = Change command\r\nRunAsAdministrator = Run as administrator\r\nFileProperties = File properties\r\nFileLocation = File location\r\nRegistryLocation = Registry location\r\nExportRegistry = Export registry\r\nDelete = Delete item\r\nDeleteReference = Delete reference\r\nHandleGuid = GUID actions\r\nCopyGuid = Copy GUID\r\nBlockGuid = Block GUID\r\nClsidLocation = CLSID location\r\nAddGuidDic = Add GUID dictionary\r\nInitialData = Edit file initial data\r\nBeforeSeparator = Displayed above the separator\r\nChangeGroup = Change group\r\nRestoreDefault = Restore default\r\nEdit = Edit\r\nSave = Save\r\nFoldAll = Fold all\r\nUnfoldAll = Unfold all\r\n\r\n[Dialog]\r\nBrowse = Browse\r\nProgram = Program\r\nAllFiles = All files\r\nRegistryFile = Registry file\r\nItemText = Item text\r\nItemCommand = Menu command\r\nCommandArguments = Command arguments\r\nSingleMenu = Single-level menu\r\nMultiMenu = Multi-level menu\r\nPublic = Public\r\nPrivate = Private\r\nSelectAll = Select all\r\nInputGuid = Enter GUID local dictionary\r\nAddGuidDic = Add GUID local dictionary\r\nDeleteGuidDic = Delete GUID dictionary\r\nNoPerceivedType = Type unknown\r\nTextFile = Text file\r\nDocumentFile = Document file\r\nImageFile = Image file\r\nVideoFile = Video file\r\nAudioFile = Audio file\r\nCompressedFile = Compressed file\r\nSystemFile = System file\r\nDocumentDirectory = Document folder\r\nImageDirectory = Image folder\r\nVideoDirectory = Video folder\r\nAudioDirectory = Audio folder\r\nEditSubItems = Edit sub-menu items for \"%s\"\r\nDetailedEdit = Edit \"%s\" in detail\r\nCheckReference = Check the menu item to which you want to add a reference to\r\nCheckCopy = Check the menu item you want to copy\r\nSelectExtension = Please select a file extension\r\nSelectPerceivedType = Please select a perceived file type\r\nSelectDirectoryType = Please select a perceived folder type\r\nSelectGroup = Select to save the group\r\nSelectNewItemType = Select \"New\" item type\r\nSelectObjectType = Select object type to analyze\r\nSelectDropEffect = Select default drop effect\r\nDefaultDropEffect = Default(move in the same drive、copy from a different drive)\r\nCopyDropEffect = Copy(Ctrl)\r\nMoveDropEffect = Move(Shift)\r\nCreateLinkDropEffect = Create shortcuts(Alt)\r\nDownloadLanguages = Download multi-language files\r\nTranslateTool = Translation tool\r\nDefaultText = Default text\r\nOldTranslation = Old translation\r\nNewTranslation = New translation\r\nDonateInfo = This list is updated once in a while，last update: %date \\r\\n\\r\\nTotal: %money Yuan, %count people\r\n\r\n[Message]\r\nTextCannotBeEmpty = Menu text cannot be empty!\r\nCommandCannotBeEmpty = Menu command cannot be empty!\r\nStringParsingFailed = Localized string parsing failed!\r\nTextLengthCannotExceed80 = Menu text you entered is too long. The length cannot exceed 80 characters!\r\nConfirmDeletePermanently = Are you sure you want to permanently delete this item? \\r\\n Be careful, this operation cannot be undone!\r\nDeleteButCanRestore = Are you sure you want to delete the registry item of this menu? \\r\\n Since automatic backup is enabled (enabled by default),\\r\\n it can be restored from the backup folder after deletion.\r\nConfirmDeleteReference = Are you sure you want to delete this item? \\r\\n Be careful, all items referencing this item will become invalid!\r\nConfirmDelete = Are you sure you want to delete this item?\r\nConfirmDeleteReferenced = Are you sure you want to permanently delete this item? \\r\\n Please note that all items referencing this item will be invalid.\r\nCannotAddNewItem = Cannot add! The system limits the maximum number of sub-menu items to 16.\r\nVistaUnsupportedMulti = Windows Vista does not support multi-level menu!\r\nCannotHideSubItem = Your version of Windows does not support hiding subitems!\r\nUnsupportedFilename = Unsupported filename. \\r\\n A menu item with the same filename may already exist!\r\nNoOpenModeExtension = There is no app associated with this extension. \\r\\n Right-click a file of this type with this extension to associate it with an app!\r\nCannotChangePath = File path changes are not allowed!\r\nCopiedToClipboard = Copied to clipboard:\r\nMalformedGuid = GUID with incorrect format\r\nHasBeenAdded = This item has been added!\r\nSelectSubMenuMode = The number of sub-items in the current multi-level menu is 0. There are two choices: \\r\\n ① All sub-menu items in this multi-level menu are private (recommended),\\r\\n ② The multi-level menu can reference the same sub-items as other multi-level menus. \\r\\n Demanding choice...\r\nEditInitialData = This program currently only supports editing the initial data of plain text files (.txt, .bat, etc.).\\r\\n For other types of files, please edit the registry \"Data\" key value by yourself.\\r\\n Confirm if you want to continue the operation.\r\nPromptIsOpenItem = This item has an \"Open\" menu,\\r\\n Blind operations may prevent you from opening files and folders,\\r\\n Confirm if you want to continue the operation. (Not recommended)\r\nSelectRegPath = Steps: \\r\\n1. Open Registry Editor\\r\\n2. Navigate to target path\\r\\n3. Close the Registry Editor\\nContinue?\r\nRestartApp = The program will restart!\r\nFileNotExists = The file does not exist!\r\nFolderNotExists = The folder does not exist!\r\nUpdateInfo = A newer version is available\\r\\nCurrent version%v1\\r\\nLatest version%v2\\r\\nDo you want to update to the latest version?\r\nUpdateSucceeded = Update succeeded!\r\nDicUpdateSucceeded = Dictionaries and multi-language files are updated.\r\nVersionIsLatest = The current version is the latest.\r\nWebDataReadFailed = Failed to fetch data from the Internet.\r\nOpenWebUrl = Open the URL?\r\nAuthorityProtection = This menu registry item may be protected by security software.\\r\\n It cannot be disabled, deleted, and other personalized modifications.\r\nWinXSorted = Some items have been renumbered in order to optimize the sorting function.\\r\\n You need to restart File Explorer before changes take effect\r\nRestoreDefault = Confirm to restore to the default menu item.\r\nDeleteGroup = Are you sure to permanently delete this group and all its menu items?\r\n\r\n[Tip]\r\nRestartExplorer = The desktop will flicker for a while after restarting Explorer. This is normal.\\r\\n Restarting or logging in and out of your PC will also make the changes take effect.\r\nCustomFolder = Disabling this option will also disable the custom tab \\r\\n in the file system object properties panel.\r\nSendToDrive = Only works if a removable disk is connected.\\r\\n Displays all partitions of the removable disk.\r\nBuildSendtoMenu = Disabling this option will speed up the pop-up speed of the main menu \\r\\n but will slow down the pop-up speed of the \"Send to\" sub-menu\r\nInvalidItem = If a menu item is invalid, all menu items \\r\\n under this item will be hidden (deletion recommended).\r\nEditSubItems = Edit sub-menu Items\r\nAddReference = Add reference from public reference project\r\nAddFromPublic = Copy item from public\r\nAddFromParentMenu = Copy item from parent menu\r\nAddSeparator = Add a seperator\r\nDeleteGuidDic = Delete the local GUID dictionary added by the user\r\nLockNewMenu = Once enabled, it can prevent third-party programs from adding items \\r\\n and can sort existing items (close and restore)\r\nDropOrSelectObject = Drop or select an object\r\nConfigPath = After changing the configuration and data file save path, \\r\\n some of the enhanced menus that have been enabled will become invalid.\\r\\n They can be re-enabled in the enhanced menu\r\nCommandFiles = This command depends on the configuration file. Moving the configuration file location will cause this menu item to become invalid. Re-enable it.\r\nCreateGroup = Create a new group\r\nImmediatelyCheck = Check now\r\n\r\n[Other]\r\nCustomFolder = Customize this &folder...\r\nBuildSendtoMenu = Create \"Send to\" submenu\r\nNewItem = Create new menu item\r\nAddGuidBlockedItem = Add GUID blocked item\r\nLockNewMenu = Lock the new menu\r\nInvalidItem = Invalid menu item:\r\nSeparator = >>>>>> Separator <<<<<<\r\nSelectRegPath = Select a registry path\r\nCurrentExtension = The currently selected file extension is %s\r\nCurrentPerceivedType = The currently selected perceived file type is %s\r\nCurrentDirectoryType = The currently selected perceived folder type is %s\r\nCurrentFilePath = Current file path: \r\nCurrentRegPath = Current registry path:\r\nWinXSortable = Enable Win+X menu sorting\r\nShowFilePath = Show file path in the status bar\r\nOpenMoreRegedit = Open Registry Editor in a separate window\r\nOpenMoreExplorer = Open File Explorer in a separate window\r\nRestartExplorer = Windows Explorer must be restarted for the changes to take effect.\r\nSwitchDictionaries = Switch dictionary\r\nWebDictionaries = Web dictionaries\r\nUserDictionaries = User dictionaries\r\nDictionaryDescription = Dictionary description\r\nGuidInfosDictionary = GUID information\r\nUwpMode = UWP Modules\r\nTranslators = Translators\r\nDonationList = Donation list\r\nConfigPath = Save location of configuration and data files\r\nAppDataDir = AppData\r\nAppDir = Program directory\r\nAutoBackup = Automatically back up the registry when deleting menus\r\nSetUpdateFrequency = How often to check update\r\nOnceAWeek = Once a week\r\nOnceAMonth = Once a month\r\nOnceASeason = Once every three months\r\nNeverCheck = Never\r\nSetRequestRepo = Request Repo\r\nProtectOpenItem = Protect the \"Open\" menu item\r\nWebSearchEngine = Search engine used for web searches\r\nCustomEngine = Custom...\r\nSetCustomEngine = Define search engine (use %s instead of search keywords) \r\nHideDisabledItems = Hide disabled items\r\nHideSysStoreItems = Hide system store items\r\nSetPerceivedType = Set %s perceived type...\r\nSetDefaultDropEffect = Set default drop effect\r\nTopMost = Always on top\r\n\r\nAboutApp = [Compatiblity] \\r\\n 1 = Compatible with Win10、8.1、8、7、Vista \\r\\n 2 = Compatible with 64bit、32bit OS\\r\\n 3 = High DPI compatible, optimal with 150%\\r\\n\\r\\n[Open source]\\r\\n 1 = Programming languages: C sharp，Winform，MIT License\\r\\n 2 = Github repo：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee repo：https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[Hints]\\r\\n 1 = This program reads/writes a large amount of system files and registry entries,\\r\\n it may be flagged by Windows Defender as these operations are highly sensitive, please manually add this program to the exclusion list\\r\\n\\r\\n 2 = Some special menu items may be affected by other factors, they may not be displayed in the context menu. \\r\\n However, they may still be displayed as enabled in this program according to the general rules used by the program. This is normal. \\r\\n\\r\\n 3 = The method of disabling the menu for each context menu management program may be different. Do not use multiple context menu management programs at the same time. \\r\\n Most programs use a simple and volatile backup-delete method. This program uses the key values ​​provided by the OS to hide keys as much as possible. \\r\\n If you have used other programs to disable an menu item before, please use that program to restore it, otherwise you may not be able to see it in this program. \\r\\n\\r\\n 4 = This program is not designed to clean up programs that have been uninstalled, but it can help you locate the registry and file locations of such menu items.\\r\\n You can do whatever you want. If you are just a newbie (or unsure about some options), toggle the enable\\disable switch only (to reduce the risk of corrupting the OS). \r\n\r\nDictionaries = [Dictionary description] \\r\\n This program has several dictionary files, and each dictionary has a user dictionary and a network dictionary. \\r\\n If you want to add a dictionary to this program, you can right-click to save the file and follow the instructions in the file to add it. \\r\\n Send your dictionary to my email or submit it to GitHub to make your contribution to this project. \\r\\n The right tab is the original dictionary content, you can switch the tab to view it \\r\\n\\r\\n[Dictionary content]\\n 1 = Program display text language dictionary (Languages directory) \\r\\n 2 = ShellEx menu item GUID text icon dictionary (GuidInfosDic.ini) \\r\\n 3 = Third-party program menu internal setting dictionary (DetailedEditDic.xml) \\r\\n 4 = Enhanced menu items Dictionary (EnhanceMenusDic.xml) \r\n\r\nDonate = This program is completely free. If you find this software helpful,\\r\\n you can donate by scanning the QR code below (WeChat, Alipay, Tencent QQ).\\r\\n The amount is up to you. Thank you for your support! I also hope you consider \\r\\n starring this project on Github or Gitee (this means a lot to me!).\r\n"
  },
  {
    "path": "languages/ja-JP.ini",
    "content": ";This file is the display text dictionary of the ContextMenuManager program, and the newline characters in the dictionary are escaped with \\r\\n or \\n\n;If you want to help the author add other language dictionaries to this program, you can modify this text and save it in the .\\config\\languages folder,\n;For example, save the American English dictionary as en-US.ini, and assign en-US English to [General]\\Language\n;Fork the project on Github or Gitee and submit an application to me, or send the file directly to the mailbox 1617859183@qq.com \n\n[General]\nAppName = Windows 右クリックメニュー管理\nLanguage = ja-JP 日本語\nTranslator = 夕綺Yuuki \\r\\n Jing\nTranslatorUrl = https://github.com/JDYuuki \\r\\n https://github.com/delgh1\n\n[ToolBar]\nHome = ホーム\nType = ファイルタイプ\nRule = 他のルール\nRefresh = リフレッシュ\nAbout = ヘルプ\n\n[SideBar]\nFile = ファイル\nFolder = フォルダー\nDirectory = ディレクトリ\nBackground = ディレクトリ背景\nDesktop = デスクトップ背景\nDrive = ディスク\nAllObjects = すべてのオブジェクト\nComputer = PC\nRecycleBin = ごみ箱\nLibrary = ライブラリ\nNew = 新規作成\nSendTo = 送る\nOpenWith = ...で開く\nWinX = Win+X\n\nLnkFile = lnkファイル\nUwpLnk = uwp リンク\nExeFile = アプリケーション\nCustomExtension = カスタムフォーマット\nPerceivedType = 認識されたファイルのタイプ\nDirectoryType = フォルダタイプ\nUnknownType = 不明なタイプ\nMenuAnalysis = メニュー分析\n\nEnhanceMenu = メニュを強化する\nDetailedEdit = 詳細情報を編集する\nDragDrop = 右クリックしてドラッグ\nPublicReferences = 公共レファレンス\nCustomRegPath = カスタムレジストリパス\nGuidBlocked = GUIDブロック\nIEMenu = IE 右クリックメニュー\n\nAppSetting = 設定\nAppLanguage = 言語\nCheckUpdate = アップデート\nDictionaries = 辞書\nAboutApp = ソフト情報\nDonate = 著作者へ寄付\n\n[StatusBar]\nFile = すべてのファイルタイプの右クリックメニュー\nFolder = すべてのフォルダの右クリックメニュー\nDirectory = すべてのファイルディレクトリの右クリックメニュー\nBackground = すべてのディレクトリの背景とデスクトップの背景の右クリックメニュー\nDesktop = デスクトップの右クリックメニュー\nDrive = すべてのディスクドライブの右クリックメニュー\nAllObjects = すべてのファイルシステムオブジェクト（ファイルとフォルダーを含む）の右クリックメニュー\nComputer = PCの右クリックメニュー\nRecycleBin = ごみ箱の右クリックメニュー\nLibrary = すべてのライブラリとライブラリディレクトリの右クリックメニュー\nNew = すべてのディレクトリとデスクトップの「新規作成」メニュー\nSendTo = すべてのファイルシステムオブジェクトの「送る」メニュー\nOpenWith = すべてのファイルの「開く」メニュー\nWinX = Win8-Win10「スタート」ボタンの右クリックメニュー\n\nLnkFile = すべてのショートカットの右クリックメニュー\nUwpLnk = すべてのWin10、Win8 UWPアプリの右クリックメニュー\nExeFile = すべてのアプリケーションの右クリックメニュー\nCustomExtension = 指定のファイル形式の右クリックメニュー\nPerceivedType = 認識されたファイルタイプの右クリックメニュー\nDirectoryType = フォルダタイプの右クリックメニュー\nUnknownType = すべての形式不明なのファイルの右クリックメニュー\nMenuAnalysis = 右クリックメニュー位置を分析する\n\nEnhanceMenu = お好きなメニューアイテムを追加する\nDetailedEdit = プログラムディレクトリに含まれる第三者プログラムの内部メニュー設定ルール\nDragDrop = 右クリックしてドラッグしたメニュー\nPublicReferences = ユーザが追加したパブリックShellタイプサブメニューを編集する\nCustomRegPath = 右クリックメニューのレジストリパスを編集する\nGuidBlocked = GUIDに依存する頑固なShellExプロジェクトに適しています（一部のGUIDは無効）\nIEMenu = Internet Explorer の右クリックメニュー\n\n[Menu]\nChangeText = 名前を変更\nItemIcon = アイテムアイコン\nChangeIcon = アイコンの変更\nShieldIcon = シールドアイコン\nAddIcon = アイコンを追加\nDeleteIcon = アイコンを削除\nItemPosition = アイテムの場所\nSetDefault = デフォルト\nSetTop = トップに置く\nSetBottom = ボトムに置く\nOtherAttributes = その他の属性\nOnlyWithShift = Shiftキーを押した後にのみ表示する\nOnlyInExplorer = エクスプロ—ラ—のみ表示する\nNoWorkingDirectory = 右クリックにあるディレクトリ情報は使用しない\nNeverDefault = デフォルトでは、左ボタンを使用してコマンドを実行しない\nShowAsDisabledIfHidden = アイテムが非アクティブ化されている場合は、非表示にするのではなくグレー表示\nDetails = 詳細情報\nWebSearch = Web検索\nChangeCommand = コマンドの変更\nRunAsAdministrator = 管理者として実行する\nFileProperties = ファイルのプロパティ\nFileLocation = ファイル位置\nRegistryLocation = レジストリ位置\nExportRegistry = レジストリキーを導出する\nDelete = 削除\nDeleteReference = 参照を削除\nHandleGuid = GUIDを処理する\nCopyGuid = GUIDをコピー\nBlockGuid = GUIDをブロック\nClsidLocation = CLSID位置\nAddGuidDic = GUID辞書を追加する\nInitialData = 初期データを編集する\nBeforeSeparator = 分割線の上に表示\nChangeGroup = グループを変更する\nRestoreDefault = デフォルト値に戻す\nEdit = 編集\nSave = 保存\nFoldAll = 全て折り畳み\nUnfoldAll = 全て展開\n\n[Dialog]\nBrowse = ブラウズ\nProgram = プログラム\nAllFiles = 全てのファイル\nRegistryFile = レジストリファイル\nItemText = アイテムテキスト\nItemCommand = メニューコマンド\nCommandArguments = コマンド引数\nSingleMenu = シングルメニュー\nMultiMenu = マルチメニュー\nPublic = パブリック\nPrivate = プライベート\nSelectAll = 全選択\nInputGuid = GUIDを入力\nAddGuidDic = GUIDローカル辞書を追加\nDeleteGuidDic = GUID辞書を削除\nNoPerceivedType = 不明なタイプ\nTextFile = テキストファイル\nDocumentFile = ドキュメント\nImageFile = イメージファイル\nVideoFile = ビデオファイル\nAudioFile = オーディオファイル\nCompressedFile = 圧縮ファイル\nSystemFile = システムファイル\nDocumentDirectory = ドキュメントフォルダ\nImageDirectory = イメージディレクトリ\nVideoDirectory = ビデオディレクトリ\nAudioDirectory = オーディオディレクトリ\nEditSubItems = 「%s」のサブメニュー項目を編集\nDetailedEdit = \"%s\" を詳細に編集する\nCheckReference = 引用を追加したいメニュー項目をチェックしてください\nCheckCopy = コピーしたいメニューアイテムをチェック\nSelectExtension = ファイル拡張子を選択してください\nSelectPerceivedType = 認識されたファイルタイプを選択してください\nSelectDirectoryType = 認識されたフォルダタイプを選択してください\nSelectGroup = 選択してグループを保存する\nSelectNewItemType = \"新規\" アイテムタイプを保存する\nSelectObjectType = 分析したいオブジェクトタイプを選択する\nSelectDropEffect = ドロップ効果のデフォルト設定選択する\nDefaultDropEffect = デフォルト設定(同じドライブ内移動、異なるドライブ間にコピー)\nCopyDropEffect = コピー(Ctrl)\nMoveDropEffect = 移動(Shift)\nCreateLinkDropEffect = ショットカットを生成(Alt)\nDownloadLanguages = 多言語対応ファイルのダウンロード\nTranslateTool = 翻訳ツール\nDefaultText = デフォルト値\nOldTranslation = 古い訳文\nNewTranslation = 新しい訳文\nDonateInfo = このリストは常に更新されます。前回の更新日: %date \\r\\n\\r\\n合計: %money 人民元, %count 回\n\n[Message]\nTextCannotBeEmpty = メニューテキストを空にすることはできません！\nCommandCannotBeEmpty = メニューコマンドを空にすることはできません！\nStringParsingFailed = ローカライズされた文字列解析に失敗!\nTextLengthCannotExceed80 = メニューテキストが長すぎます。長さは半角80文字を超えることはできません！\nConfirmDeletePermanently = このアイテムを完全に削除しますか。\\r\\nこの操作は復元できません、注意してください!\nDeleteButCanRestore = 本当に削除しますか？ \\r\\n 自動バックアップが有効化されているので(既定値)、\\r\\n 復元できます。\nConfirmDeleteReference = プロジェクトへの参照を削除しますか。\nConfirmDelete = このアイテムを削除しますか。\nConfirmDeleteReferenced = このアイテムを完全に削除しますか。\\r\\nこのアイテムを参照するすべてのアイテムは無効になります、注意してください。\nCannotAddNewItem = システムはサブメニュー項目の最大数を16に制限します、\\r\\n追加できません！\nVistaUnsupportedMulti = Windows Vista がマルチメニューを対応しません!\nCannotHideSubItem = あなたのWindowsバージョンはサブメニューの隠しを対応していません!\nUnsupportedFilename = サポートされていないファイル名、\\r\\n同じファイル名のメニュー項目がすでに存在している可能性があります！\nNoOpenModeExtension = この拡張子に関連付けられているアプリはありません。 \\r\\n この拡張子を持つこのタイプのファイルを右クリックして、アプリに関連付けます!\nCannotChangePath = ファイルパスの変更は許可されていません！\nCopiedToClipboard = クリップボードにコピー：\nMalformedGuid = 不明なGuid！\nHasBeenAdded = このアイテムが追加されました！\nSelectSubMenuMode = 当現在のマルチレベルメニューのサブ項目数は0です。二つの選択肢がある:\\r\\n①このマルチレベルメニューのすべてのサブメニュー項目はプライベートですが、\\r\\n②このマルチレベルメニューは、他のマルチレベルメニューと同じサブアイテムを参照できます、\\r\\n選択してください。\nEditInitialData = プレーンテキストファイル（.txt、.batなど）のみをサポートします、\\r\\nバイナリデータを書き込む必要がある場合は、レジストリ内の関連するタイプの「Data」キー値を自分で編集してください、\\r\\n編集を続けますか。\nPromptIsOpenItem = このアイテムは「開く」メニュー、\\r\\n盲目的な操作には、ファイルやフォルダを開くことができなくなる場合があります、\\r\\n続行するかどうか。(お勧めしません)\nSelectRegPath = ステップ: \\r\\n1. Registry Editorを開く\\r\\n2. ターゲットパスに移動する\\r\\n3.Registry Editor閉じる\\n続けますか?\nRestartApp = プログラムが再起動します！\nFileNotExists = ファイルは存在しません!\nFolderNotExists = フォルダは存在しません!\nUpdateInfo = 新しいバージョンへアップデートできます。\\r\\n現在のバージョン%v1\\r\\n新しいバージョン%v2\\r\\nアップデートしますか?\nUpdateSucceeded = アップデートは成功でした!\nDicUpdateSucceeded = 辞書と多言語ファイルが更新されました。\nVersionIsLatest = すでに最新版です。\nWebDataReadFailed = インターネットへの接続が失敗しました。\nOpenWebUrl = URLを開きますか?\nAuthorityProtection = このメニューレジストリ項目は、セキュリティソフトウェアによって保護されている可能性があります。\\r\\n無効にしたり、削除したり、その他の個人的な変更を加えたりすることはできません。\nWinXSorted = 並べ替え機能を最適化するために、一部のアイテムの番号が付け直されました。\\r\\n変更を有効にするには、File Explorerを再起動する必要があります。\nRestoreDefault = デフォルトのメニュー項目に戻すことを確認してください。\nDeleteGroup = このグループとそのすべてのメニュー項目を完全に削除してもよろしいですか？\n\n[Tip]\nRestartExplorer = Explorerを再起動すると、デスクトップがしばらくちらつきます。通常の現象を心配する必要はありません、\\r\\n後でコンピュータを再起動またはログオフして、操作を有効にすることもできます。\nCustomFolder = このオプションを無効にすると、ファイルシステムオブジェクトのプロパティパネルのカスタムタブも無効になります\nSendToDrive = リムーバブルディスクが挿入されている場合にのみ機能します、\\r\\nリムーバブルディスクのすべてのパーティションを表示する\nBuildSendtoMenu = このオプションを無効にすると、メインメニューのポップアップ表示速度が速くなります、\\r\\nただし、サブメニューポップアップの表示速度が遅くなります\nInvalidItem = メニュー項目が無効な場合、この項目の下にあるすべてのメニュー項目が非表示になります（削除することをお勧めします）\nEditSubItems = サブメニュー項目の編集\nAddReference = パブリックリファレンスプロジェクトからのリファレンスを追加する\nAddFromPublic = パブリックからアイテムをコピー\nAddFromParentMenu = 親メニューからアイテムをコピー\nAddSeparator = 分割線を追加\nDeleteGuidDic = ユーザーが追加したローカルGUID辞書を削除します\nLockNewMenu = 有効にすると、サードパーティプログラムがアイテムを追加するのを防ぐことができます\\r\\n既存のアイテムを並べ替えることができます（閉じて復元）\nDropOrSelectObject = オブジェクトをドロップまたは選択します\nConfigPath = 構成とデータファイルの保存パスを変更すると、\\r\\n有効になっている一部の拡張メニューが無効になります。\\r\\n拡張メニューで再度有効にできます\nCommandFiles = このコマンドは、構成ファイルによって異なります。構成ファイルの場所を移動すると、このメニュー項目が無効になります。再度有効にします。\nCreateGroup = 新しいグループを作成します\nImmediatelyCheck = 今すぐチェック\n\n[Other]\nCustomFolder = このフォルダーのカスタマイズ(&F)...\nBuildSendtoMenu = 「送る」サブメニューを作成\nNewItem = 新しいメニュー項目を作成\nAddGuidBlockedItem = GUIDロックアイテムを追加\nLockNewMenu = 新しいメニューをロックする\nInvalidItem = 無効なメニュー項目：\nSeparator = >>>>>> プロジェクトの分割線 <<<<<<\nSelectRegPath = 请选择注册表项\nCurrentExtension = 選択されている拡張子は %s\nCurrentPerceivedType = 選択されている認識されたファイルタイプは %s\nCurrentDirectoryType = 選択されている認識されたフォルダタイプは %s\nCurrentFilePath = 現在のファイルパス: \nCurrentRegPath = 現在のレジストリパス:\nWinXSortable = Win+Xメニューの並べ替えを有効にする\nShowFilePath = ステータスバーにファイルパスを表示する\nOpenMoreRegedit = 別のウィンドウでRegistry Editorを開く\nOpenMoreExplorer = 別のウィンドウでFile Explorerを開きます\nRestartExplorer = 変更を有効にするには、Windows Explorerを再起動する必要があります。\nSwitchDictionaries = 辞書を切り替える\nWebDictionaries = Web辞書\nUserDictionaries = ユーザ辞書\nDictionaryDescription = 辞書の説明\nGuidInfosDictionary = GUID情報\nUwpMode = UWP モジュール\nTranslators = 翻訳者\nDonationList = 寄付リスト\nConfigPath = 構成ファイルとデータファイルの保存場所\nAppDataDir = AppData\nAppDir = Programフォルダ\nAutoBackup = メニューを削除するときにレジストリを自動的にバックアップする\nSetUpdateFrequency = 更新をチェックする頻度\nOnceAWeek = 週一回\nOnceAMonth = 月一回\nOnceASeason = 三ヶ月間一回\nNeverCheck = 一度もしない\nSetRequestRepo = レポをリクエストする\nProtectOpenItem = 「開く」メニュー項目を保護する\nWebSearchEngine = Web検索に使用される検索エンジン\nCustomEngine = カスタム...\nSetCustomEngine = 検索エンジンを定義する（検索キーワードの代わりに %s を使う）\nHideDisabledItems = 無効なアイテムを非表示にする\nHideSysStoreItems = システムストアアイテムを非表示にする\nSetPerceivedType = %s 認識タイプを設定する...\nSetDefaultDropEffect = デフォルトのドロップ効果を設定する\nTopMost = 常にトップに\n\nAboutApp = [互換性]\\r\\n 1 = Win10、8.1、8、7、Vistaと互換性があります \\r\\n 2 = 64bit、32bit OSと互換性があります\\r\\n 3 = High DPIと互換性があります。150%は最適。\\r\\n\\r\\n[オープンソース]\\r\\n 1 = プログラミング言語: C sharp，Winform，MIT ライセンス\\r\\n 2 = Github repo：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee repo：https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[ご案内]\\r\\n 1 = このプログラムは、大量のシステムファイルとレジストリエントリを読み書きします。\\r\\n これらの操作は非常に機密性が高いため、Windows Defenderによってマルウェアとして検知される場合があります。このプログラムを除外リストに手動で追加してください。\\r\\n\\r\\n 2 = 一部の特別なメニュー項目は、他の要因の影響を受ける可能性があり、コンテキストメニューに表示されない場合があります。 \\r\\n ただし、プログラムで使用される一般的な規則に従って、このプログラムで有効として表示される場合があります。これは正常です。\\r\\n\\r\\n 3 = コンテキストメニュー管理プログラムごとにメニューを無効にする方法は異なる場合があります。複数のコンテキストメニュー管理プログラムを同時に使用しないでください。\\r\\n ほとんどのプログラムは、単純で揮発性のバックアップ/削除方法を使用します。このプログラムは、OSが提供するキー値を使用して、キーを可能な限り非表示にします。\\r\\n以前に他のプログラムを使用してメニュー項目を無効にしたことがある場合は、そのプログラムを使用してメニュー項目を復元してください。そうしないと、このプログラムで表示できない場合があります。\\r\\n\\r\\n 4 = このプログラムは、アンインストールされたプログラムをクリーンアップするようには設計されていません。ただし、このようなメニュー項目のレジストリとファイルの場所を見つけるのに役立ちます。\\r\\n あなたはあなたがやりたいことを何でもすることができます。初心者の場合（または一部のオプションがわからない場合）は、有効/無効スイッチのみを切り替えてください（OSが破損するリスクを減らすため）。\n\nDictionaries = [辞書の説明] \\r\\n このプログラムにはいくつかの辞書ファイルがあり、各辞書にはユーザー辞書とネットワーク辞書があります。\\r\\n このプログラムに辞書を追加する場合は、右クリックしてファイルを保存し、ファイルの指示に従って追加できます。\\r\\n 辞書を私のメールに送信するか、GitHubに送信して、このプロジェクトに貢献してください。\\r\\n右側のタブは元の辞書のコンテンツであり、タブを切り替えて表示できます\\r\\n\\r\\n [辞書のコンテンツ]\\n 1 = プログラム表示テキスト言語辞書（言語ディレクトリ）\\r\\n 2 = ShellExメニュー項目GUIDテキストアイコン辞書（GuidInfosDic.ini）\\r\\n 3 = サードパーティプログラムメニュー内部設定辞書（DetailedEditDic.xml）\\r\\n 4 = 拡張メニュー項目辞書（EnhanceMenusDic.xml）\n\nDonate = このプログラムは完全に無料です。このソフトウェアが役に立った場合は、\\r\\n以下のQRコード（WeChat、Alipay、Tencent QQ）をスキャンして寄付できます。\\r\\n金額はあなた次第です。ご支援いただきありがとうございます！また、\\r\\n このプロジェクトをGithubまたはGiteeで主演することを検討してください（これは私にとって大きな意味があります！）。\n"
  },
  {
    "path": "languages/ko-KR.ini",
    "content": ";이 파일은 ContextMenuManager 프로그램의 표시 텍스트 사전이며 사전의 새 줄 문자는 \\r\\n 또는 \\n로 이스케이프됩니다\r\n;작성자가 이 프로그램에 다른 언어 사전을 추가하는 것을 도와주려면 이 텍스트를 수정하고 .\\config\\languages 폴더에 저장할 수 있습니다,\r\n;예를 들어, 미국 영어 사전을 en-us.ini로 저장하고 [일반]\\language에 en-us 영어를 할당합니다\r\n;Github 또는 Gitee에서 프로젝트를 포크하여 저에게 신청서를 제출하거나 파일을 우편함 1617859183@qq.com으로 직접 보내십시오 \r\n\r\n[General]\r\nAppName = Windows 상황에 맞는 메뉴 관리자\r\nLanguage = ko-KR 한국어\r\nTranslator = 비너스걸💋 \\r\\n VenusGirl💗\r\nTranslatorUrl = https://venusgirls.tistory.com/ \\r\\n https://github.com/VenusGirl\r\n\r\n[ToolBar]\r\nHome = 홈\r\nType = 파일 유형\r\nRule = 기타 규칙\r\nRefresh = 새로 고침\r\nAbout = 제품 정보\r\n\r\n[SideBar]\r\nFile = 파일\r\nFolder = 폴더\r\nDirectory = 디렉터리\r\nBackground = 배경\r\nDesktop = 바탕화면\r\nDrive = 디스크\r\nAllObjects = 모든 개체\r\nComputer = 내  PC\r\nRecycleBin = 휴지통\r\nLibrary = 라이브러리\r\nNew = 새로 만들기\r\nSendTo = 보내기\r\nOpenWith = 열기\r\nWinX = Win+X\r\n\r\nLnkFile = .lnk 파일\r\nUwpLnk = UWP .lnk\r\nExeFile = .exe 파일\r\nCustomExtension = 지정된 파일 유형\r\nPerceivedType = 인식된 파일 유형\r\nDirectoryType = 폴더 유형\r\nUnknownType = 알 수 없는 파일 유형\r\nMenuAnalysis = 메뉴 분석\r\n\r\nEnhanceMenu = 메뉴 향상\r\nDetailedEdit = 상세편집\r\nDragDrop = 끌어서 놓기\r\nPublicReferences = 공개 참고 자료\r\nCustomRegPath = 사용자 지정 레지스트리 경로\r\nGuidBlocked = GUID 차단됨\r\nIEMenu = IE 상황에 맞는 메뉴\r\n\r\nAppSetting = 설정\r\nAppLanguage = 언어\r\nCheckUpdate = 업데이트 확인\r\nDictionaries = 프로그램 폴더\r\nAboutApp = 소프트웨어 정보\r\nDonate = 저자에게 기부하기\r\n\r\n[StatusBar]\r\nFile = 모든 파일 유형에 대한 상황에 맞는 메뉴\r\nFolder = 모든 폴더 유형의 상황에 맞는 메뉴\r\nDirectory = 모든 파일 폴더의 상황에 맞는 메뉴\r\nBackground = 모든 폴더 및 바탕 화면 배경에 대한 상황에 맞는 메뉴\r\nDesktop = 바탕 화면의 상황에 맞는 메뉴\r\nDrive = 모든 디스크 드라이브의 상황에 맞는 메뉴\r\nAllObjects = 모든 파일 시스템 개체 (파일 및 폴더 포함)의 상황에 맞는 메뉴\r\nComputer = 내 PC의 상황에 맞는 메뉴\r\nRecycleBin = 휴지통의 상황에 맞는 메뉴\r\nLibrary = 모든 라이브러리 및 라이브러리 폴더 배경에 대한 상황에 맞는 메뉴\r\nNew = 폴더 및 바탕 화면 배경에 대한 상황에 맞는 메뉴의 \"새로 만들기\" 메뉴\r\nSendTo = 모든 파일 시스템 개체에 대한 \"보내기\" 메뉴\r\nOpenWith = 모든 파일에 대한 \"열기\" 메뉴\r\nWinX = Win+X 시작 메뉴를 위한 Win8-Win10 상황에 맞는 메뉴\r\n\r\nLnkFile = 모든 바로 가기의 상황에 맞는 메뉴\r\nUwpLnk = 모든 Win10, Win8 UWP 앱의 상황에 맞는 메뉴\r\nExeFile = .exe 실행 파일의 상황에 맞는 메뉴\r\nCustomExtension = 모든 파일 유형에 대해 상황에 맞는 메뉴 사용자 지정\r\nPerceivedType = 지정된 인식 파일의 상황에 맞는 메뉴 사용자 지정\r\nDirectoryType = 지정된 폴더 유형의 상황에 맞는 메뉴 사용자 지정\r\nUnknownType = 앱과 연결되지 않은 파일 형식의 파일의 상황에 맞는 메뉴\r\nMenuAnalysis = 상황에 맞는 메뉴 위치 분석\r\n\r\nEnhanceMenu = 유용한 메뉴 항목 추가\r\nDetailedEdit = 시스템 및 기타 프로그램의 내부 메뉴에 대한 상세 설정 규칙\r\nDragDrop =파일을 마우스 오른쪽 버튼으로 클릭하고 끌 때 메뉴 항목\r\nPublicReferences = 사용자가 추가한 공개 참조의 셸 유형 하위 메뉴 항목 편집\r\nCustomRegPath = 상황에 맞는 메뉴 레지스트리 경로 사용자 지정\r\nGuidBlocked = GUID에 의존하는 완고한 ShellEx 프로젝트에 적합 (일부 GUID는 비활성화됨)\r\nIEMenu = Internet Explorer의 상황에 맞는 메뉴\r\n\r\n[Menu]\r\nChangeText = 이름 바꾸기\r\nItemIcon = 항목 아이콘\r\nChangeIcon = 아이콘 변경\r\nShieldIcon = 방패 아이콘\r\nAddIcon = 아이콘 추가\r\nDeleteIcon = 삭제 아이콘\r\nItemPosition = 항목 위치\r\nSetDefault = 기본값\r\nSetTop = 위에 올려 놓기\r\nSetBottom = 바닥에 올려 놓기\r\nOtherAttributes = 기타 속성\r\nOnlyWithShift = Shift를 누른 상태에서만 표시\r\nOnlyInExplorer = 파일 탐색기에만 표시\r\nNoWorkingDirectory = 상황에 맞는 메뉴에서 폴더 정보 사용 안 함\r\nNeverDefault = 기본적으로 왼쪽 버튼을 사용하여 명령 실행 안 함\r\nShowAsDisabledIfHidden = 항목이 비활성화되면 숨기지 않고 회색으로 표시\r\nDetails = 세부 사항\r\nWebSearch = 웹 검색\r\nChangeCommand = 명령 변경\r\nRunAsAdministrator = 관리자로 실행\r\nFileProperties = 파일 속성\r\nFileLocation = 파일 위치\r\nRegistryLocation = 레지스트리 위치\r\nExportRegistry = 레지스트리 내보내기\r\nDelete = 항목 삭제\r\nDeleteReference = 참조 삭제\r\nHandleGuid = GUID 작업\r\nCopyGuid = GUID 복사\r\nBlockGuid = GUID 차단\r\nClsidLocation = CLSID 위치\r\nAddGuidDic = GUID 사전 추가\r\nInitialData = 파일 초기 데이터 편집\r\nBeforeSeparator = 구분 기호 위에 표시됨\r\nChangeGroup = 그룹 변경\r\nRestoreDefault = 기본값 복원\r\nEdit = 편집\r\nSave = 저장\r\nFoldAll = 모두 접기\r\nUnfoldAll = 모두 펴기\r\n\r\n[Dialog]\r\nBrowse = 찾아보기\r\nProgram = 프로그램\r\nAllFiles = 모든 파일\r\nRegistryFile = 레지스트리 파일\r\nItemText = 항목 텍스트\r\nItemCommand = 메뉴 명령\r\nCommandArguments = 명령 인수\r\nSingleMenu = 단일 수준 메뉴\r\nMultiMenu = 다중 수준 메뉴\r\nPublic = 일반\r\nPrivate = 개인\r\nSelectAll = 모두 선택\r\nInputGuid = GUID 로컬 사전 입력\r\nAddGuidDic = GUID 로컬 사전 추가\r\nDeleteGuidDic = GUID 사전 삭제\r\nNoPerceivedType = 유형 알 수 없음\r\nTextFile = 텍스트 파일\r\nDocumentFile = 문서 파일\r\nImageFile = 이미지 파일\r\nVideoFile = 비디오 파일\r\nAudioFile = 오디오 파일\r\nCompressedFile = 압축 파일\r\nSystemFile = 시스템 파일\r\nDocumentDirectory = 문서 폴더\r\nImageDirectory = 이미지 폴더\r\nVideoDirectory = 비디오 폴더\r\nAudioDirectory = 오디오 폴더\r\nEditSubItems = \"%s\"의 하위 메뉴 항목 편집\r\nDetailedEdit = \"%s\" 세부 정보 편집\r\nCheckReference = 참조를 추가할 메뉴 항목을 선택\r\nCheckCopy = 복사할 메뉴 항목 선택\r\nSelectExtension = 파일 확장명을 선택하십시오\r\nSelectPerceivedType = 인식되는 파일 형식을 선택하십시오\r\nSelectDirectoryType = 인식되는 폴더 유형을 선택하십시오\r\nSelectGroup = 그룹을 저장하려면 선택\r\nSelectNewItemType = \"새로 만들기\" 항목 유형 선택\r\nSelectObjectType = 분석할 개체 유형 선택\r\nSelectDropEffect = 기본 끌기 효과 선택\r\nDefaultDropEffect = 기본값 (같은 드라이브로 이동→다른 드라이브에서 복사)\r\nCopyDropEffect = 복사 (Ctrl)\r\nMoveDropEffect = 이동 (Shift)\r\nCreateLinkDropEffect = 바로 가기 만들기 (Alt)\r\nDownloadLanguages = 다국어 파일 다운로드\r\nTranslateTool = 번역 도구\r\nDefaultText = 기본 텍스트\r\nOldTranslation = 오래된 번역\r\nNewTranslation = 새로운 번역\r\nDonateInfo = 이 목록은 가끔 업데이트됩니다，마지막 업데이트: %date \\r\\n\\r\\n전체: %money 위안, %count 사람\r\n\r\n[Message]\r\nTextCannotBeEmpty = 메뉴 텍스트는 비워 둘 수 없습니다!\r\nCommandCannotBeEmpty = 메뉴 명령은 비워 둘 수 없습니다!\r\nStringParsingFailed = 지역화된 문자열 구문 분석에 실패했습니다!\r\nTextLengthCannotExceed80 = 입력한 메뉴 텍스트가 너무 깁니다. 길이는 80자를 초과할 수 없습니다!\r\nConfirmDeletePermanently = 이 항목을 영구적으로 삭제하시겠습니까? \\r\\n 이 작업은 취소할 수 없으므로 주의하십시오!\r\nDeleteButCanRestore = 이 메뉴의 레지스트리 항목을 삭제하시겠습니까? \\r\\n 자동 백업은 실행 (기본 실행)되어 있으므로,\\r\\n 삭제 후 백업 폴더에서 복원할 수 있습니다.\r\nConfirmDeleteReference = 이 항목을 삭제하시겠습니까? \\r\\n 이 항목을 참조하는 모든 항목이 무효화됩니다!\r\nConfirmDelete = 이 항목을 삭제하시겠습니까?\r\nConfirmDeleteReferenced = 이 항목을 영구적으로 삭제하시겠습니까? \\r\\n 이 항목을 참조하는 모든 항목은 유효하지 않습니다.\r\nCannotAddNewItem = 추가할 수 없습니다! 시스템은 하위 메뉴 항목의 최대 수를 16개로 제한합니다.\r\nVistaUnsupportedMulti = Windows Vista는 다중 수준 메뉴를 지원하지 않습니다!\r\nCannotHideSubItem = 사용 중인 Windows 버전이 하위 항목 숨기기를 지원하지 않습니다!\r\nUnsupportedFilename = 지원되지 않는 파일 이름입니다. \\r\\n 파일 이름이 같은 메뉴 항목이 이미 있을 수 있습니다!\r\nNoOpenModeExtension = 이 확장과 연결된 앱이 없습니다. \\r\\n 앱과 연결하려면 확장자가 이 유형 파일을 마우스 오른쪽 버튼으로 클릭하십시오!\r\nCannotChangePath = 파일 경로 변경이 허용되지 않습니다!\r\nCopiedToClipboard = 클립보드에 복사했습니다:\r\nMalformedGuid = GUID의 형식이 잘못되었습니다\r\nHasBeenAdded = 이 항목이 추가되었습니다!\r\nSelectSubMenuMode = 현재 다중 수준 메뉴의 하위 항목 수는 0개입니다. 두 가지 선택이 있습니다: \\r\\n ① 이 다중 수준 메뉴의 모든 하위 메뉴 항목은 비공개 (권장)입니다\\r\\n ② 다중 수준 메뉴는 다른 다중 수준 메뉴와 동일한 하위 항목을 참조할 수 있습니다. \\r\\n 선택이 필요합니다...\r\nEditInitialData = 이 프로그램은 현재 일반 텍스트 파일 (.txt, .bat 등)의 초기 데이터 편집만 지원합니다.\\r\\n 다른 유형의 파일의 경우 레지스트리 \"데이터\" 키 값을 직접 편집하십시오.\\r\\n 작업을 계속할지 확인합니다.\r\nPromptIsOpenItem = 이 항목에는 \"열기\" 메뉴가 있습니다,\\r\\n 블라인드 작업으로 인해 파일 및 폴더를 열지 못할 수 있습니다,\\r\\n 작업을 계속하려면 확인하십시오. (권장하지 않습니다)\r\nSelectRegPath = 단계: \\r\\n1. 레지스트리 편집기 열기\\r\\n2. 대상 경로로 이동\\r\\n3. 레지스트리 편집기 닫기\\n계속하시겠습니까?\r\nRestartApp = 프로그램이 다시 시작됩니다!\r\nFileNotExists = 파일이 존재하지 않습니다!\r\nFolderNotExists =폴더가 존재하지 않습니다!\r\nUpdateInfo = A newer version is available\\r\\n현재 버전%v1\\r\\n최신 버전%v2\\r\\n최신 버전으로 업데이트하시겠습니까?\r\nUpdateSucceeded = 업데이트가 성공했습니다!\r\nDicUpdateSucceeded = 사전 및 다국어 파일이 업데이트됩니다.\r\nVersionIsLatest = 현재 버전이 최신 버전입니다.\r\nWebDataReadFailed = 인터넷에서 데이터를 가져오지 못했습니다.\r\nOpenWebUrl = URL을 여시겠습니까?\r\nAuthorityProtection = 이 메뉴 레지스트리 항목은 보안 소프트웨어에 의해 보호될 수 있습니다.\\r\\n 비활성화, 삭제 및 기타 개인화된 수정은 할 수 없습니다.\r\nWinXSorted = 정렬 기능을 최적화하기 위해 일부 항목의 번호가 다시 지정되었습니다.\\r\\n 변경 내용을 적용하려면 파일 탐색기를 다시 시작해야 합니다.\r\nRestoreDefault = 기본 메뉴 항목으로 복원할지 확인합니다.\r\nDeleteGroup = 이 그룹과 모든 메뉴 항목을 완전히 삭제하시겠습니까?\r\n\r\n[Tip]\r\nRestartExplorer = 탐색기를 다시 시작한 후 바탕화면이 잠시 깜박입니다. 이것은 정상입니다.\\r\\n PC를 다시 시작하거나 로그인하거나 로그아웃해도 변경 사항이 적용됩니다.\r\nCustomFolder = 이 옵션을 사용하지 않도록 설정하면 파일 시스템 개체 속성 \\r\\n 패널의 사용자 지정 탭도 사용할 수 없게 됩니다.\r\nSendToDrive = 이동식 디스크가 연결된 경우에만 작동합니다.\\r\\n 이동식 디스크의 모든 파티션을 표시합니다.\r\nBuildSendtoMenu = 이 옵션을 비활성화하면 기본 메뉴의 팝업 속도는 빨라지지만 \\r\\n \"보네기\" 하위 메뉴의 팝업 속도는 느려집니다.\r\nInvalidItem = 메뉴 항목이 잘못된 경우 이 항목 아래의 \\r\\n 모든 메뉴 항목이 숨겨집니다 (삭제 권장).\r\nEditSubItems = 하위 메뉴 항목 편집\r\nAddReference = 공개 참조 프로젝트에서 참조 추가\r\nAddFromPublic = 공용에서 항목 복사\r\nAddFromParentMenu = 상위 메뉴에서 항목 복사\r\nAddSeparator = 구분 기호 추가\r\nDeleteGuidDic = 사용자가 추가한 로컬 GUID 사전 삭제\r\nLockNewMenu =활성화되면 타사 프로그램이 항목을 추가하지 못하도록 할 수 있으며 기존 항목을 정렬할 수 있습니다 (닫기 및 복원).\r\nDropOrSelectObject = 개체 삭제 또는 선택\r\nConfigPath = 구성 및 데이터 파일 저장 경로를 변경하면 활성화된, \\r\\n 고급 메뉴 중 일부가 유효하지 않게 됩니다.\\r\\n 향상된 메뉴에서 다시 활성화할 수 있습니다\r\nCommandFiles = 이 명령은 구성 파일에 따라 다릅니다. 구성 파일 위치를 이동하면 이 메뉴 항목이 유효하지 않게 됩니다. 다시 활성화하십시오.\r\nCreateGroup = 새 그룹 만들기\r\nImmediatelyCheck = 지금 확인\r\n\r\n[Other]\r\nCustomFolder = 이 폴더 사용자 지정(&F)...\r\nBuildSendtoMenu = \"보내기\" 하위 메뉴 만들기\r\nNewItem = 새 메뉴 항목 만들기\r\nAddGuidBlockedItem = 차단된 GUID 항목 추가\r\nLockNewMenu = 새 메뉴 잠금\r\nInvalidItem = 잘못된 메뉴 항목:\r\nSeparator = >>>>>> 구분 기호 <<<<<<\r\nSelectRegPath = 레지스트리 경로 선택\r\nCurrentExtension = 현재 선택한 파일 확장명은 %s입니다\r\nCurrentPerceivedType = 현재 선택된 인식 파일 형식은 %s입니다\r\nCurrentDirectoryType = 현재 선택된 인식 폴더 유형은 %s입니다\r\nCurrentFilePath = 현재 파일 경로:\r\nCurrentRegPath = 현재 레지스트리 경로:\r\nWinXSortable = Win+X 메뉴 정렬 사용\r\nShowFilePath = 상태 표시줄에 파일 경로 표시\r\nOpenMoreRegedit = 별도의 창에서 레지스트리 편집기 열기\r\nOpenMoreExplorer = 별도의 창에서 파일 탐색기 열기\r\nRestartExplorer = 변경 내용을 적용하려면 Windows 탐색기를 다시 시작해야 합니다.\r\nSwitchDictionaries =사전 전환\r\nWebDictionaries = 웹 사전\r\nUserDictionaries = 사용자 사전\r\nDictionaryDescription = 사전 설명\r\nGuidInfosDictionary = GUID 정보\r\nUwpMode = UWP 모듈\r\nTranslators = 번역자\r\nDonationList = 기부 목록\r\nConfigPath = 구성 및 데이터 파일의 위치 저장\r\nAppDataDir = AppData\r\nAppDir = 프로그램 디렉터리\r\nAutoBackup = 메뉴 삭제 시 레지스트리 자동 백업\r\nSetUpdateFrequency = 업데이트 확인 빈도\r\nOnceAWeek = 일주일에 한번\r\nOnceAMonth = 한달에 한번\r\nOnceASeason = 3개월에 한번\r\nNeverCheck = 절대 안 함\r\nSetRequestRepo = Repo 요청\r\nProtectOpenItem = \"열기\" 메뉴 항목 보호\r\nWebSearchEngine = 웹 검색에 사용되는 검색 엔진\r\nCustomEngine = 사용자 지정...\r\nSetCustomEngine = 검색 엔진 정의 (검색 키워드 대신 %s 사용) \r\nHideDisabledItems = 사용할 수 없는 항목 숨기기\r\nHideSysStoreItems = 시스템 저장소 항목 숨기기\r\nSetPerceivedType = %s 인식 유형 설정...\r\nSetDefaultDropEffect = 기본 삭제 효과 설정\r\nTopMost = 항상 맨 위에\r\n\r\nAboutApp = [호환성] \\r\\n 1 = Win10、8.1、8、7、Vista와 호환 \\r\\n 2 = 64비트、32비트 OS와 호환\\r\\n 3 = 높은 DPI 호환, 150%로 최적\\r\\n\\r\\n[공개 소스]\\r\\n 1 = 프로그래밍 언어: C sharp，Winform，MIT 라이선스\\r\\n 2 = Github repo：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee repo：https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[힌트]\\r\\n 1 = 이 프로그램은 많은 양의 시스템 파일 및 레지스트리 항목을 읽고 씁니다,\\r\\n 이러한 작업은 매우 중요하므로 Windows Defender에서 플래그를 지정할 수 있습니다. 이 프로그램을 제외 목록에 수동으로 추가하십시오\\r\\n\\r\\n 2 = 일부 특수 메뉴 항목은 다른 요인의 영향을 받을 수 있으며 상황에 맞는 메뉴에 표시되지 않을 수 있습니다. \\r\\n 그러나 프로그램이 사용하는 일반 규칙에 따라 이 프로그램에서 활성화된 상태로 표시될 수 있습니다. 이는 정상적인 현상입니다. \\r\\n\\r\\n 3 = 상황에 맞는 메뉴 관리 프로그램마다 메뉴를 비활성화하는 방법이 다를 수 있습니다. 여러 상황에 맞는 메뉴 관리 프로그램을 동시에 사용하지 마십시오. \\r\\n 대부분의 프로그램은 간단하고 휘발성이 강한 백업-삭제 방법을 사용합니다. 이 프로그램은 OS에서 제공하는 키 값을 사용하여 키를 최대한 숨깁니다. \\r\\n 이전에 다른 프로그램을 사용하여 메뉴 항목을 사용 불가능으로 설정한 적이 있는 경우 해당 프로그램을 사용하여 복원하십시오. 그렇지 않으면 이 프로그램에서 해당 항목을 볼 수 없습니다. \\r\\n\\r\\n 4 = 이 프로그램은 제거된 프로그램을 정리하도록 설계되지 않았지만 이러한 메뉴 항목의 레지스트리 및 파일 위치를 찾는 데 도움이 될 수 있습니다.\\r\\n 원하는대로 할 수 있습니다. 초보이거나 일부 옵션에 대해 잘 모르는 경우 사용함\\사용 안 함 스위치만 전환하십시오 (OS 손상 위험을 줄이기 위해). \r\n\r\nDictionaries = [사전 설명] \\r\\n 이 프로그램에는 여러 개의 사전 파일이 있으며, 각 사전에는 사용자 사전과 네트워크 사전이 있습니다. \\r\\n 이 프로그램에 사전을 추가하려면 마우스 오른쪽 버튼을 눌러 파일을 저장한 후 파일의 지침에 따라 사전을 추가합니다. \\r\\n 이 프로젝트에 기여하려면 사전을 내 이메일로 보내거나 GitHub에 제출하십시오. \\r\\n 오른쪽 탭은 원래 사전 내용입니다. 탭을 전환하여 볼 수 있습니다 \\r\\n\\r\\n[사전 내용]\\n 1 = 프로그램 표시 텍스트 언어 사전 (언어 디렉터리) \\r\\n 2 = ShellEx 메뉴 항목 GUID 텍스트 아이콘 사전 (GuidInfosDic.ini) \\r\\n 3 = 타사 프로그램 메뉴 내부 설정 사전 (DetailedEditDic.xml) \\r\\n 4 = 향상된 메뉴 항목사전 (EnhanceMenusDic.xml) \r\n\r\nDonate = 이 프로그램은 완전히 무료입니다. 이 소프트웨어가 유용한 경우,\\r\\n 아래 QR 코드(WeChat, Alipay, Tencent QQ)를 스캔하여 기부할 수 있습니다.\\r\\n 금액은 당신에게 달려 있습니다. 지원해 주셔서 감사합니다! 또한 Github 또는 Gitee에서 \\r\\n 이 프로젝트를 주연으로 생각하기를 바랍니다 (이것은 나에게 많은 것을 의미합니다!)."
  },
  {
    "path": "languages/zh-CN.ini",
    "content": "﻿;此文件为 ContextMenuManager Windows右键管理程序 的显示文本字典。\n;可帮助作者为此程序提供翻译并提交到Github，以下内容中等号右侧内容替换为翻译文本。\n;General - Translator 为翻译贡献者，General - Language 为语言名称，如en-US 美国英语，\n;General - TranslatorUrl 为翻译贡献者的URL地址(能用Win+R命令打开的URL链接即可)\n;翻译说明：暂时不翻译的值保留为空即可，字典内赋值换行使用\\r\\n或\\n进行转义。\n;翻译贡献者和为多人时请使用\\r\\n或\\n对 Translator 的值和对应的 TranslatorUrl 值换行，\n;没有URL地址赋值为null，使贡献者与链接一一对应，如 Translator = Bob \\r\\n Join \\r\\n Andi, \n;TranslatorUrl = https://github.com/BluePointLilac \\r\\n null \\r\\n https://gitee.com/BluePointLilac\n\n[General]\nAppName = Windows右键管理\nLanguage = zh-CN 简体中文\nTranslator = 蓝点lilac\nTranslatorUrl = tencent://message/?uin=1617859183\n\n[ToolBar]\nHome = 主页\nType = 文件类型\nRule = 其他规则\nRefresh = 刷新\nAbout = 关于\n\n[SideBar]\nFile = 文件\nFolder = 文件夹\nDirectory = 目录\nBackground = 目录背景\nDesktop = 桌面背景\nDrive = 磁盘分区\nAllObjects = 所有对象\nComputer = 此电脑\nRecycleBin = 回收站\nLibrary = 库\nNew = 新建菜单\nSendTo = 发送到\nOpenWith = 打开方式\nWinX = Win+X\n\nLnkFile = lnk文件\nUwpLnk = uwp lnk\nExeFile = exe文件\nCustomExtension = 自选格式\nPerceivedType = 感知类型\nDirectoryType = 目录类型\nUnknownType = 未知格式\nMenuAnalysis = 菜单分析\n\nEnhanceMenu = 增强菜单\nDetailedEdit = 详细编辑\nDragDrop = 右键拖拽\nPublicReferences = 公共引用\nCustomRegPath = 自选路径\nGuidBlocked = GUID 锁\nIEMenu = IE浏览器\n\nAppSetting = 程序设置\nAppLanguage = 程序语言\nCheckUpdate = 检测更新\nDictionaries = 程序字典\nAboutApp = 关于程序\nDonate = 捐赠作者\n\n[StatusBar]\nFile = 所有类型文件的右键菜单\nFolder = 所有文件夹的右键菜单\nDirectory = 所有文件目录的右键菜单\nBackground = 所有目录背景和桌面背景的右键菜单\nDesktop = 桌面背景右键菜单\nDrive = 所有磁盘驱动器的右键菜单\nAllObjects = 所有文件系统对象(包括文件、文件夹)的右键菜单\nComputer = 此电脑图标的右键菜单\nRecycleBin = 回收站图标的右键菜单\nLibrary = 所有库和库目录背景的右键菜单\nNew = 所有目录背景和桌面背景的右键 \"新建\" 的菜单项目\nSendTo = 所有文件系统对象的右键 \"发送到\" 的菜单项目\nOpenWith = 所有文件右键 \"打开方式\" 的菜单项目\nWinX = Win8~Win10 \"开始\" 按钮的右键 Win+X 菜单项目\n\nLnkFile = 所有LNK快捷方式的右键菜单\nUwpLnk = Win8~Win10 UWP应用快捷方式的右键菜单\nExeFile = 所有EXE可执行文件的右键菜单\nCustomExtension = 自定义指定格式文件的右键菜单\nPerceivedType = 自定义指定文件感知类型的右键菜单\nDirectoryType = 自定义指定目录感知类型的右键菜单\nUnknownType = 所有未关联打开方式的格式文件的右键菜单\nMenuAnalysis = 分析指定文件对象所有的右键菜单所在位置\n\nEnhanceMenu = 添加一些强大便捷的菜单项\nDetailedEdit = 系统和其他程序内部部分菜单详细设置规则\nDragDrop = 右键拖拽文件时的菜单项目\nPublicReferences = 编辑用户添加的公共引用的Shell类型子菜单项目\nCustomRegPath = 编辑自定义注册表路径的右键菜单项目\nGuidBlocked = 适用于隐藏部分顽固的依赖GUID的ShellEx类型项目\nIEMenu = Internet Explorer 网页的右键菜单\n\n[Menu]\nChangeText = 更改文本\nItemIcon = 菜单图标\nChangeIcon = 更改图标\nShieldIcon = 盾牌图标\nAddIcon = 添加图标\nDeleteIcon = 删除图标\nItemPosition = 菜单位置\nSetDefault = 默认\nSetTop = 置顶\nSetBottom = 置底\nOtherAttributes = 其他属性\nOnlyWithShift = 仅在按住 Shift 键后显示\nOnlyInExplorer = 仅在 Explorer 窗口显示\nNoWorkingDirectory = 不使用右键所处目录信息\nNeverDefault = 从不用作左键默认执行命令\nShowAsDisabledIfHidden = 被禁用时灰色显示不隐藏\nDetails = 详细信息\nWebSearch = 网页搜索\nChangeCommand = 更改命令\nRunAsAdministrator = 提升权限\nFileProperties = 文件属性\nFileLocation = 文件位置\nRegistryLocation = 注册表位置\nExportRegistry = 导出注册表\nDelete = 删除此项\nDeleteReference = 删除引用\nHandleGuid = 处理GUID\nCopyGuid = 复制GUID\nBlockGuid = 锁定GUID\nClsidLocation = CLSID路径\nAddGuidDic = 添加字典\nInitialData = 编辑文件初始数据\nBeforeSeparator = 显示在分割线上方\nChangeGroup = 更换分组\nRestoreDefault = 还原默认\nEdit = 编辑\nSave = 保存\nFoldAll = 全部折叠\nUnfoldAll = 全部展开\n\n[Dialog]\nBrowse = 浏览\nProgram = 程序\nAllFiles = 所有文件\nRegistryFile = 注册表文件\nItemText = 菜单文本\nItemCommand = 菜单命令\nCommandArguments = 命令参数\nSingleMenu = 一级\nMultiMenu = 多级\nPublic = 公有\nPrivate = 私有\nSelectAll = 全选\nInputGuid = 输入Guid\nAddGuidDic = 添加Guid本地字典\nDeleteGuidDic = 删除\nNoPerceivedType = 无感知\nTextFile = 文本文件\nDocumentFile = 文档文件\nImageFile = 图像文件\nVideoFile = 视频文件\nAudioFile = 音频文件\nCompressedFile = 压缩文件\nSystemFile = 系统文件\nDocumentDirectory = 文档目录\nImageDirectory = 图像目录\nVideoDirectory = 视频目录\nAudioDirectory = 音频目录\nEditSubItems = 编辑 \"%s\" 的子菜单项目\nDetailedEdit = 详细编辑 \"%s\" 菜单项目\nCheckReference = 请勾选你想要引用的菜单项目\nCheckCopy = 请勾选你想要复制的菜单项目\nSelectExtension = 请选择一个文件扩展名\nSelectPerceivedType = 请选择一个文件感知类型\nSelectDirectoryType = 请选择一个目录感知类型\nSelectGroup = 请选择保存分组\nSelectNewItemType = 请选择新建菜单类型\nSelectObjectType = 请选择要分析的对象类型\nSelectDropEffect = 请选择拖拽文件默认命令\nDefaultDropEffect = 默认(同盘移动、异盘复制)\nCopyDropEffect = 复制(Ctrl)\nMoveDropEffect = 移动(Shift)\nCreateLinkDropEffect = 创建快捷方式(Alt)\nDownloadLanguages = 下载语言文件\nTranslateTool = 翻译工具\nDefaultText = 默认文本\nOldTranslation = 旧译文\nNewTranslation = 新译文\nDonateInfo = 此名单不定期更新，上次更新：%date \\r\\n\\r\\n累计金额：%money 元，累计人次：%count 人次\n\n[Message]\nTextCannotBeEmpty = 菜单文本不能为空！\nCommandCannotBeEmpty = 菜单命令不能为空！\nStringParsingFailed = 本地化字符串解析失败！\nTextLengthCannotExceed80 = 菜单文本过长，长度不允许超过80！\nConfirmDeletePermanently = 确认是否永久删除此项？\\r\\n此操作无法还原，请谨慎操作！\nDeleteButCanRestore = 确认删除此菜单的注册表项目？\\r\\n由于启用了自动备份(默认启用)，\\r\\n删除后可在备份文件夹中还原。\nConfirmDeleteReference = 确认是否移除对该项目的引用？\nConfirmDelete = 确认是否删除该项？\nConfirmDeleteReferenced = 确认是否删除此项？\\r\\n所有引用此项的项目都会失效，请谨慎操作！\nCannotAddNewItem = 系统限制子菜单数目最多为16，\\r\\n无法添加更多的子菜单项目！\nVistaUnsupportedMulti = Vista系统不支持多级菜单！\nCannotHideSubItem = 你的系统版本太低，不支持隐藏子级菜单！\nUnsupportedFilename = 不支持的文件名，\\r\\n可能已经存在相同文件名的菜单项目！\nNoOpenModeExtension = 此扩展名没有关联默认打开方式，\\r\\n请先为此类型文件关联打开方式！\nCannotChangePath = 不允许更改文件路径！\nCopiedToClipboard = 已复制到剪切板:\nMalformedGuid = 格式不正确的Guid\nHasBeenAdded = 此项目已被添加！\nSelectSubMenuMode = 该多级菜单子项目数为0，你有两个选择:\\r\\n①该多级菜单的所有子菜单项目私有(推荐)，\\r\\n②该多级菜单可与其他多级菜单引用相同子项，\\r\\n请做出你的选择......\nEditInitialData = 此程序现仅支持编辑纯文本文件的初始数据，\\r\\n其他类型文件请自行编辑注册表\"Data\"键值，\\r\\n请确认是否继续你的操作？\nPromptIsOpenItem = 该项为文件或文件夹的\"打开\"菜单，\\n盲目操作可能会导致无法打开文件或文件夹，\\n请确认是否继续你的操作？(不建议)\nSelectRegPath = 操作步骤：\\r\\n① 打开注册表编辑器(自动)\\r\\n② 导航到目标注册表路径\\r\\n③ 关闭注册表编辑器窗口\\n请确认是否继续？\nRestartApp = 程序将会重新启动！\nFileNotExists = 文件不存在！\nFolderNotExists = 文件夹不存在！\nUpdateInfo = 【检测更新】\\r\\n当前版本：%v1\\r\\n最新版本：%v2\\r\\n是否立即下载更新？\nUpdateSucceeded = 程序更新成功！\nDicUpdateSucceeded = 字典和语言文件更新成功!\nVersionIsLatest = 当前版本为最新版！\nWebDataReadFailed = 网络数据读取失败!\nOpenWebUrl = 是否打开相关网页?\nAuthorityProtection = 此菜单注册表项目可能受安全软件保护，\\r\\n无法对其进行禁用删除和其他个性化修改。\nWinXSorted = 为优化排序功能已对部分项目重新编号，\\r\\n需要重启文件资源管理器应用效果\nRestoreDefault = 确认还原为默认菜单项目？\nDeleteGroup = 确认永久删除此组及组内所有菜单项目？\n\n[Tip]\nRestartExplorer = 重启Explorer会使桌面闪烁片刻，正常现象无需担心，\\r\\n或者你也可以稍后重启或注销计算机使你的操作生效\nCustomFolder = 禁用此项将会同时禁用文件系统\\r\\n对象属性面板中的自定义选项卡\nSendToDrive = 仅当插入可移动磁盘时有作用，\\r\\n显示该可移动磁盘的所有分区\nBuildSendtoMenu = 禁用此项将加快主菜单弹出速度\\r\\n但会延缓发送到子菜单弹出速度\nInvalidItem = 无效菜单项目将导致此项以下的\\r\\n所有菜单项目不可见(建议删除)\nEditSubItems = 编辑子菜单项目\nAddReference = 从公共引用项目中添加引用\nAddFromPublic = 从公共引用中复制菜单项目\nAddFromParentMenu = 从母菜单中复制项目\nAddSeparator = 添加分隔线\nDeleteGuidDic = 删除用户自行添加的该项的本地Guid字典\nLockNewMenu = 启用后可阻止第三方程序增加项目\\r\\n且可对现有项目排序(关闭后复原)\nDropOrSelectObject = 请拖拽或通过按钮选择文件或目录\nConfigPath = 更改配置和数据文件保存路径后，\\r\\n会导致部分已启用增强菜单失效，\\r\\n可在增强菜单中重新启用一遍\nCommandFiles = 此命令依赖配置文件，移动配置文件位置\\r\\n会导致此菜单项失效，重新启用一遍即可\nCreateGroup = 新建一个分组\nImmediatelyCheck = 立即检查\n\n[Other]\nCustomFolder = 自定义文件夹(&F)...\nBuildSendtoMenu = 快速构建发送到子菜单\nNewItem = 新建一个菜单项目\nAddGuidBlockedItem = 添加GUID锁定项目\nLockNewMenu = 锁定新建菜单并启用排序功能\nInvalidItem = 无效菜单项目:\nSeparator = >>>>>> 分割线 <<<<<<\nSelectRegPath = 请选择注册表项\nCurrentExtension = 你当前选择的文件扩展名为 %s\nCurrentPerceivedType = 你当前选择的文件感知类型为 %s\nCurrentDirectoryType = 你当前选择的目录感知类型为 %s\nCurrentFilePath = 你当前选择的文件对象路径为\nCurrentRegPath = 你当前选择的注册表路径为\nWinXSortable = 启用 WinX 菜单排序功能\nShowFilePath = 状态栏实时显示文件路径\nOpenMoreRegedit = 注册表编辑器窗口多开\nOpenMoreExplorer = 文件资源管理器窗口多开\nRestartExplorer = 当前部分操作需要重启文件资源管理器生效\nSwitchDictionaries = 切换字典\nWebDictionaries = 网络字典\nUserDictionaries = 用户字典\nDictionaryDescription = 字典说明\nGuidInfosDictionary = GUID信息\nUwpMode = UWP模块\nTranslators = 翻译贡献者\nDonationList = 捐赠名单\nConfigPath = 配置和数据文件保存位置\nAppDataDir = AppData 目录\nAppDir = 程序所在目录\nAutoBackup = 删除菜单时自动备份注册表\nSetUpdateFrequency = 设置程序自动检查更新频率\nOnceAWeek = 每周一次\nOnceAMonth = 每月一次\nOnceASeason = 每季一次\nNeverCheck = 从不检查\nSetRequestRepo = 设置网络数据访问存储库站点\nProtectOpenItem = 保护名称为 \"打开\" 的菜单项目\nWebSearchEngine = 设置网页搜索使用的搜索引擎\nCustomEngine = 自定义\nSetCustomEngine = 设置搜索引擎 (以 %s 代替搜索关键词)\nHideDisabledItems = 隐藏已禁用的菜单项目\nHideSysStoreItems = 隐藏公共引用中的系统菜单\nSetPerceivedType = 设置扩展名为 %s 的文件感知类型为\nSetDefaultDropEffect = 设置文件对象默认拖拽命令为\nTopMost = 使窗口始终在屏幕最上方\n\nAboutApp = [兼容性能]\\r\\n 1 = 适用于Win10、8.1、8、7、Vista \\r\\n 2 = 适用于 64bit、32bit CPU 操作系统\\r\\n 3 = 适配高分屏，最佳缩放比为150%\\r\\n\\r\\n[代码开源]\\r\\n 1 = 代码语言：C Sharp，Winform 程序，MIT 开源协议\\r\\n 2 = Github 仓库：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee 仓库：https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[温馨提示]\\r\\n 1 = 程序需要对大量的注册表项和文件进行读写删改操作，这些行为比较敏感，\\r\\n 可能会被Windows Defender等误报为病毒，如发生此情况请自行添加进白名单。\\r\\n\\r\\n 2 = 一些特殊菜单项可能会受到其他因素影响导致不会直接显示在右键菜单中，\\r\\n    但是按照程序使用的通用规则在此程序中仍会显示为启用状态，这是正常的现象。\\r\\n\\r\\n 3 = 每个右键管理程序禁用菜单方法可能不同，建议不要同时使用多个右键菜单管理程序，\\r\\n 大部分程序使用简单暴力的备份-删除法，此程序尽可能使用了系统提供的键值进行隐藏，\\r\\n 通过其他程序禁用的菜单项目，请先使用对应程序还原，不然可能无法在此程序中看到它。\\r\\n\\r\\n 4 = 此程序不用于清理未卸载干净的程序，但可帮助你定位菜单项相关注册表和文件位置，\\r\\n 你可根据相关内容进行你的操作，如果你是一个电脑小白，建议只碰启用\\禁用开关。\n\nDictionaries = [字典说明]\\r\\n 此程序拥有几个字典文件，每份字典又有用户字典(User目录)和网络字典(Web目录)\\r\\n 如果想为此程序添加字典可右键保存文件至User目录，并按照文件内说明进行添加\\r\\n 你可以将你的字典发送到我的邮箱或者提交合并到Github为此项目做出你的贡献\\n 右侧选项卡中为原始字典内容，你可以切换选项卡进行查看和右键编辑、保存操作\\r\\n\\r\\n[字典内容]\\r\\n 1 = 程序显示文本语言字典 (Languages目录)\\r\\n 2 = ShellEx菜单项GUID文本图标字典 (GuidInfosDic.ini)\\r\\n 3 = 系统和其他程序内部部分菜单详细设置规则字典 (DetailedEditDic.xml)\\r\\n 4 = 增强菜单项目字典 (EnhanceMenusDic.xml)\\r\\n 5 = UWP新模块字典 (UWPModeItemsDic.xml)\n\nDonate = 此程序完全免费，如果你觉得这个软件对你有所帮助，你可以通过扫描\\r\\n下方二维码(微信、支付宝、腾讯QQ)进行捐赠，金额请随意，谢谢支持！\\r\\n也期待你在Github或者Gitee上为此程序项目点亮Star (这对我很重要！)"
  },
  {
    "path": "languages/zh-TW.ini",
    "content": "﻿;此檔案為 ContextMenuManager Windows右鍵管理程式 的顯示文字字典\n;翻譯：可幫助作者為此程式提供翻譯並提交到Github，以下內容中等號右側內容取代為翻譯文字，\n;General-Translator為翻譯貢獻者，General-Language為語言名稱，如en-US 美國英語\n;翻譯檔案儲存在Config\\languages資料夾中，檔案名儲存為en-US.ini\n;翻譯說明：暫時不翻譯的值保留為空即可，字典內賦值換行使用\\r\\n或\\n進行轉義\n\n[General]\nAppName = Windows右鍵管理\nLanguage = zh-TW 繁體中文（臺灣）\nTranslator = jfcherng\nTranslatorUrl = https://github.com/jfcherng\n\n[ToolBar]\nHome = 首頁\nType = 檔案類型\nRule = 其他規則\nRefresh = 重新整理\nAbout = 關於\n\n[SideBar]\nFile = 檔案\nFolder = 文件夾\nDirectory = 資料夾\nBackground = 資料夾背景\nDesktop = 桌面背景\nDrive = 磁碟分區\nAllObjects = 所有物件\nComputer = 本機\nRecycleBin = 資源回收筒\nLibrary = 庫\nNew = 建立選單\nSendTo = 傳送到\nOpenWith = 開啟檔案\nWinX = Win+X\n\nLnkFile = lnk檔案\nUwpLnk = uwp lnk\nExeFile = exe檔案\nCustomExtension = 自選格式\nPerceivedType = 感知類型\nDirectoryType = 資料夾類型\nUnknownType = 未知格式\nMenuAnalysis = 選單分析\n\nEnhanceMenu = 增強選單\nDetailedEdit = 詳細編輯\nDragDrop = 右鍵拖曳\nPublicReferences = 公共引用\nCustomRegPath = 自選路徑\nGuidBlocked = GUID 鎖\nIEMenu = IE瀏覽器\n\nAppSetting = 程式設定\nAppLanguage = 程式語言\nCheckUpdate = 檢測更新\nDictionaries = 程式字典\nAboutApp = 關於程式\nDonate = 捐贈作者\n\n[StatusBar]\nFile = 所有類型檔案的右鍵選單\nFolder = 所有資料夾的右鍵選單\nDirectory = 所有檔案資料夾的右鍵選單\nBackground = 所有資料夾背景和桌面背景的右鍵選單\nDesktop = 桌面背景右鍵選單\nDrive = 所有磁碟驅動器的右鍵選單\nAllObjects = 所有檔案系統物件（包括檔案、資料夾）的右鍵選單\nComputer = 此電腦圖示的右鍵選單\nRecycleBin = 資源回收筒圖示的右鍵選單\nLibrary = 所有庫和庫資料夾背景的右鍵選單\nNew = 所有資料夾背景和桌面背景的右鍵 \"新增\" 的選單項目\nSendTo = 所有檔案系統物件的右鍵 \"傳送到\" 的選單項目\nOpenWith = 所有檔案右鍵 \"開啟檔案\" 的選單項目\nWinX = Win8~Win10 \"開始\" 按鈕的右鍵 Win+X 選單項目\n\nLnkFile = 所有LNK捷徑的右鍵選單\nUwpLnk = Win8~Win10 UWP應用程式捷徑的右鍵選單\nExeFile = 所有EXE可執行檔的右鍵選單\nCustomExtension = 自訂指定格式檔案的右鍵選單\nPerceivedType = 自訂指定檔案感知類型的右鍵選單\nDirectoryType = 自訂指定資料夾感知類型的右鍵選單\nUnknownType = 所有未關聯開啟檔案的格式檔案的右鍵選單\nMenuAnalysis = 分析指定檔案物件所有的右鍵選單所在位置\n\nEnhanceMenu = 新增一些有用的選單項目\nDetailedEdit = 編輯自定義註冊表路徑的右鍵菜單項目\nDragDrop = 右鍵拖曳檔案時的選單項目\nPublicReferences = 編輯使用者新增的公共引用的Shell類型子選單項目\nCustomRegPath = 編輯自訂註冊表路徑的右鍵選單項目\nGuidBlocked = 適用於隱藏部分頑固的依賴GUID的ShellEx類型項目\nIEMenu = Internet Explorer 網頁的右鍵選單\n\n[Menu]\nChangeText = 更改文字\nItemIcon = 選單圖示\nChangeIcon = 更改圖示\nShieldIcon = 盾牌圖示\nAddIcon = 新增圖示\nDeleteIcon = 刪除圖示\nItemPosition = 選單位置\nSetDefault = 預設\nSetTop = 置頂\nSetBottom = 置底\nOtherAttributes = 其他屬性\nOnlyWithShift = 僅在按住 Shift 鍵後顯示\nOnlyInExplorer = 僅在 Explorer 視窗顯示\nNoWorkingDirectory = 不使用右鍵所處資料夾訊息\nNeverDefault = 從不用作左鍵預設執行指令\nShowAsDisabledIfHidden = 被禁用時灰色顯示不隱藏\nDetails = 詳細訊息\nWebSearch = 網頁搜尋\nChangeCommand = 更改指令\nRunAsAdministrator = 提升權限\nFileProperties = 檔案屬性\nFileLocation = 檔案位置\nRegistryLocation = 註冊表位置\nExportRegistry = 匯出註冊表\nDelete = 刪除此項\nDeleteReference = 刪除引用\nHandleGuid = 處理GUID\nCopyGuid = 複製GUID\nBlockGuid = 鎖定GUID\nClsidLocation = CLSID路徑\nAddGuidDic = 新增字典\nInitialData = 編輯檔案初始資料\nBeforeSeparator = 顯示在分割線上方\nChangeGroup = 更換分組\nRestoreDefault = 還原預設\nEdit = 編輯\nSave = 儲存\n\n[Dialog]\nBrowse = 瀏覽\nProgram = 程式\nAllFiles = 所有檔案\nRegistryFile = 註冊表檔案\nItemText = 選單文字\nItemCommand = 選單指令\nCommandArguments = 指令參數\nSingleMenu = 一級\nMultiMenu = 多級\nPublic = 公有\nPrivate = 私有\nInputGuid = 輸入Guid\nAddGuidDic = 新增Guid本機字典\nDeleteGuidDic = 刪除\nNoPerceivedType = 無感知\nTextFile = 文字檔案\nDocumentFile = 文件檔案\nImageFile = 圖像檔案\nVideoFile = 影片檔案\nAudioFile = 音訊檔案\nCompressedFile = 壓縮檔案\nSystemFile = 系統檔案\nDocumentDirectory = 文件資料夾\nImageDirectory = 圖像資料夾\nVideoDirectory = 影片資料夾\nAudioDirectory = 音訊資料夾\nEditSubItems = 編輯 \"%s\" 的子選單項目\nCheckReference = 請勾選你想要引用的選單項目\nCheckCopy = 請勾選你想要複製的選單項目\nSelectExtension = 請選擇一個檔案副檔名\nSelectPerceivedType = 請選擇一個檔案感知類型\nSelectDirectoryType = 請選擇一個資料夾感知類型\nSelectGroup = 請選擇儲存分組\nSelectNewItemType = 請選擇建立選單類型\nSelectObjectType = 請選擇要分析的物件類型\nSelectDropEffect = 請選擇拖曳檔案預設指令\nDefaultDropEffect = 預設（同槽移動、異槽複製）\nCopyDropEffect = 複製(Ctrl)\nMoveDropEffect = 移動(Shift)\nCreateLinkDropEffect = 建立捷徑(Alt)\nDownloadLanguages = 下載語言檔案\nTranslateTool = 翻譯工具\nDefaultText = 預設文字\nOldTranslation = 舊譯文\nNewTranslation = 新譯文\nDonateInfo = 此名單不定期更新，上次更新：%date \\r\\n\\r\\n累計金額：%money 元，累計人次：%count 人次\n\n[Message]\nTextCannotBeEmpty = 選單文字不能為空！\nCommandCannotBeEmpty = 選單指令不能為空！\nStringParsingFailed = 本地化字串解析失敗！\nTextLengthCannotExceed80 = 選單文字過長，長度不允許超過80！\nConfirmDeletePermanently = 確認是否永久刪除此項？\\r\\n此操作無法還原，請謹慎操作！\nDeleteButCanRestore = 確認刪除此選單的註冊表項目？\\r\\n由於啟用了自動備份(預設啟用)，\\r\\n刪除後可在備份資料夾中還原。\nConfirmDeleteReference = 確認是否移除對該項目的引用？\nConfirmDelete = 確認是否刪除該項？\nConfirmDeleteReferenced = 確認是否刪除此項？\\r\\n所有引用此項的項目都會失效，請謹慎操作！\nCannotAddNewItem = 系統限制子選單數目最多為16，\\r\\n無法新增更多的子選單項目！\nVistaUnsupportedMulti = Vista系統不支援多級選單！\nCannotHideSubItem = 你的系統版本太低，不支援隱藏子級選單！\nUnsupportedFilename = 不支援的檔案名，\\r\\n可能已經存在相同檔案名的選單項目！\nNoOpenModeExtension = 此副檔名沒有關聯預設開啟檔案，\\r\\n請先為此類型檔案關聯開啟檔案！\nCannotChangePath = 不允許更改檔案路徑！\nCopiedToClipboard = 已複製到剪貼簿:\nMalformedGuid = 格式不正確的Guid\nHasBeenAdded = 此項目已被新增！\nSelectSubMenuMode = 該多級選單子項目數為0，你有兩個選擇:\\r\\n①該多級選單的所有子選單項目私有(推薦)，\\r\\n②該多級選單可與其他多級選單引用相同子項，\\r\\n請做出你的選擇……\nEditInitialData = 此程式現僅支援編輯純文字檔案的初始資料，\\r\\n其他類型檔案請自行編輯註冊表\"Data\"鍵值，\\r\\n請確認是否繼續你的操作？\nPromptIsOpenItem = 該項為檔案或資料夾的\"打開\"選單，\\n盲目操作可能會導致無法打開檔案或資料夾，\\n請確認是否繼續你的操作？(不建議)\nSelectRegPath = 操作步驟：\\r\\n① 打開登入編輯程式(自動)\\r\\n② 導航到目標註冊表路徑\\r\\n③ 關閉登入編輯程式視窗\\n請確認是否繼續？\nRestartApp = 程式將會重新啟動！\nFileNotExists = 檔案不存在！\nFolderNotExists = 資料夾不存在！\nUpdateInfo = 【檢測更新】\\r\\n目前版本：%v1\\r\\n最新版本：%v2\\r\\n是否立即下載更新？\nUpdateSucceeded = 程式更新成功！\nVersionIsLatest = 目前版本為最新版！\nAuthorityProtection = 此選單註冊表項目可能受安全軟體保護，\\r\\n無法對其進行禁用刪除和其他個人化修改。\nWinXSorted = 為最佳化排序功能已對部分項目重新編號，\\r\\n需要重啟檔案資源管理器套用效果\nRestoreDefault = 確認還原為預設選單項目？\nDeleteGroup = 確認永久刪除此組及組內所有選單項目？\nWebDataReadFailed = 網路資料讀取失敗！\n\n[Tip]\nRestartExplorer = 重啟Explorer會使桌面閃爍片刻，正常現象無需擔心，\\r\\n或者你也可以稍後重啟或登出電腦使你的操作生效\nCustomFolder = 禁用此項將會同時禁用檔案系統\\r\\n物件屬性面板中的自訂頁籤\nSendToDrive = 僅當插入可移動磁碟時有作用，\\r\\n顯示該可移動磁碟的所有分區\nBuildSendtoMenu = 禁用此項將加快主選單彈出速度\\r\\n但會延緩傳送到子選單彈出速度\nInvalidItem = 無效選單項目將導致此項以下的\\r\\n所有選單項目不可見（建議刪除）\nEditSubItems = 編輯子選單項目\nAddReference = 從公共引用項目中新增引用\nAddFromPublic = 從公共引用中複製選單項目\nAddFromParentMenu = 從母選單中複製項目\nAddSeparator = 新增分隔線\nDeleteGuidDic = 刪除使用者自行新增的該項的本機Guid字典\nLockNewMenu = 啟用後可阻止第三方程式增加項目\\r\\n且可對現有項目排序（關閉後復原）\nDropOrSelectObject = 請拖曳或透過按鈕選擇檔案或資料夾\nConfigPath = 更改設定和資料檔案儲存路徑後，\\r\\n會導致部分已啟用增強選單失效，\\r\\n可在增強選單中重新啟用一遍\nCommandFiles = 此指令依賴設定檔案，移動設定檔位置\\r\\n會導致此選單項失效，重新啟用一遍即可\nCreateGroup = 建立一個分組\n\n[Other]\nCustomFolder = 自訂此資料夾(&F)…\nBuildSendtoMenu = 快速構建傳送到子選單\nNewItem = 建立一個選單項目\nAddGuidBlockedItem = 新增GUID鎖定項目\nLockNewMenu = 鎖定建立選單並啟用排序功能\nInvalidItem = 無效選單項目:\nSeparator = >>>>>> 分割線 <<<<<<\nSelectRegPath = 請選擇註冊表項\nCurrentExtension = 你目前選擇的檔案副檔名為 %s\nCurrentPerceivedType = 你目前選擇的檔案感知類型為 %s\nCurrentDirectoryType = 你目前選擇的資料夾感知類型為 %s\nCurrentFilePath = 你目前選擇的檔案物件路徑為\nCurrentRegPath = 你目前選擇的註冊表路徑為\nWinXSortable = 啟用 WinX 選單排序功能\nShowFilePath = 狀態欄即時顯示檔案路徑\nOpenMoreRegedit = 允許登入編輯程式多開\nRestartExplorer = 目前部分操作需要重啟檔案總管生效\nUserDictionaries = 使用者字典\nDictionaryDescription = 字典說明\nGuidInfosDictionary = GUID訊息\nUwpMode = UWP模組\nTranslators = 翻譯貢獻者\nDonationList = 捐贈名單\nConfigPath = 設定和資料檔案儲存位置\nAppDataDir = AppData 資料夾\nAppDir = 程式所在資料夾\nAutoBackup = 刪除選單時自動備份註冊表\nSetUpdateFrequency = 設定自動檢測更新頻率\nOnceAWeek = 每週一次\nOnceAMonth = 每月一次\nOnceASeason = 每季一次\nNeverCheck = 從不檢查\nImmediatelyCheck = 立即檢查\nSetRequestRepo = 設定網路資料瀏覽儲存庫位置\nProtectOpenItem = 保護名稱為 \"打開\" 的選單項目\nWebSearchEngine = 設定網頁搜尋使用的搜尋引擎\nCustomEngine = 自訂\nSetCustomEngine = 設定搜尋引擎（以 %s 代替搜尋關鍵字）\nHideDisabledItems = 不顯示已禁用的選單項目\nHideSysStoreItems = 隱藏公共引用中的系統選單\nSetPerceivedType = 設定副檔名為 %s 的檔案感知類型為\nSetDefaultDropEffect = 設定檔案物件預設拖曳指令為\n\nAboutApp = [相容性]\\r\\n 1 = 適用於Win10、8.1、8、7、Vista \\r\\n 2 = 適用於 64bit、32bit CPU 作業系統\\r\\n 3 = 適用高解析螢幕，最佳縮放比為150%\\r\\n\\r\\n[程式碼開源]\\r\\n 1 = 程式碼語言：C Sharp，Winform 程式，MIT 開源協議\\r\\n 2 = Github 倉庫：https://github.com/BluePointLilac/ContextMenuManager \\r\\n 3 = Gitee 倉庫：https://gitee.com/BluePointLilac/ContextMenuManager \\r\\n\\r\\n[溫馨提醒]\\r\\n 1 = 程式需要對大量的註冊表項和檔案進行讀寫刪改操作，這些敏感的行為可能\\r\\n 會被Windows Defender等誤報為病毒，如發生此情況請自行新增進白名單。\\r\\n\\r\\n 2 = 一些特殊選單項目可能會受到其他因素影響導致不會直接顯示在右鍵選單中，\\r\\n 但是按照程式使用的通用規則在此程式中仍會顯示為啟用，這是正常的現象。\\r\\n\\r\\n 3 = 每個右鍵管理程式禁用選單方法可能不同，建議不要同時使用多個右鍵選單管理程式，\\r\\n 大部分程式使用簡單暴力的備份-刪除法，此程式盡可能使用了系統提供的鍵值進行隱藏，\\r\\n    透過其他程式禁用的選單項目，請先使用對應程式還原，不然可能無法在此程式中看到它。\\r\\n\\r\\n 4 = 此程式不用於清理未移除乾淨的程式，但可幫助你定位選單項相關註冊表和檔案位置，\\r\\n 你可根據相關內容進行你的操作，如果你不懂電腦，建議只碰啟用\\禁用開關。\n\nDictionaries = [字典說明]\\r\\n 此程式擁有幾個字典檔案，每份字典又有使用者字典(User資料夾)和網路字典(Web資料夾)\\r\\n 如果想為此程式新增字典可右鍵儲存檔案至User資料夾，並按照檔案內說明進行新增\\r\\n 你可以將你的字典傳送到我的信箱或者提交合並到Github為此項目做出你的貢獻\\n 右側頁籤中為原始字典內容，你可以切換頁籤進行查看和右鍵編輯、儲存操作\\r\\n\\r\\n[字典內容]\\r\\n 1 = 程式顯示文字語言字典 (Languages資料夾)\\r\\n 2 = ShellEx選單項GUID文字圖示字典 (GuidInfosDic.ini)\\r\\n 3 = 第三方程式選單內部設定字典 (DetailedEditDic.xml)\\r\\n 4 = 增強選單項目字典 (EnhanceMenusDic.xml)\\r\\n 5 = UWP新模組字典 (UWPModeItemsDic.xml)\n\nDonate = 此程式完全免費，如果你覺得這個軟體對你有所幫助，你可以透過掃描\\r\\n下方 QR Code (微信、支付寶、騰訊QQ)進行捐贈，金額請隨意，謝謝支持！\\r\\n也期待你在Github或者Gitee上為Star此項目 (這對我很重要！)"
  }
]