Browse Source

更新3.3.2.0版本

蓝点lilac 4 năm trước cách đây
mục cha
commit
823875a06f
66 tập tin đã thay đổi với 911 bổ sung675 xóa
  1. 4 3
      ContextMenuManager/App.config
  2. 6 0
      ContextMenuManager/AppConfig.cs
  3. 7 3
      ContextMenuManager/AppString.cs
  4. 5 3
      ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs
  5. 6 6
      ContextMenuManager/BluePointLilac.Controls/IconDialog.cs
  6. 4 3
      ContextMenuManager/BluePointLilac.Controls/InputDialog.cs
  7. 0 14
      ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs
  8. 32 29
      ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs
  9. 26 29
      ContextMenuManager/BluePointLilac.Methods/EncodingType.cs
  10. 3 1
      ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs
  11. 5 5
      ContextMenuManager/BluePointLilac.Methods/ObjectPath.cs
  12. 1 1
      ContextMenuManager/BluePointLilac.Methods/RegistryEx.cs
  13. 2 0
      ContextMenuManager/BluePointLilac.Methods/ShellLink.cs
  14. 26 17
      ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs
  15. 12 2
      ContextMenuManager/BluePointLilac.Methods/UAWebClient.cs
  16. 16 4
      ContextMenuManager/ContextMenuManager.csproj
  17. 66 19
      ContextMenuManager/Controls/AboutApp.cs
  18. 25 10
      ContextMenuManager/Controls/DonateListDialog.cs
  19. 25 12
      ContextMenuManager/Controls/EnhanceMenusItem.cs
  20. 2 0
      ContextMenuManager/Controls/EnhanceMenusList.cs
  21. 18 4
      ContextMenuManager/Controls/GuidBlockedItem.cs
  22. 1 1
      ContextMenuManager/Controls/Interfaces/IBtnDeleteItem.cs
  23. 5 1
      ContextMenuManager/Controls/Interfaces/ITsiCommandItem.cs
  24. 1 1
      ContextMenuManager/Controls/Interfaces/ITsiDeleteItem.cs
  25. 8 7
      ContextMenuManager/Controls/Interfaces/ITsiGuidItem.cs
  26. 1 0
      ContextMenuManager/Controls/Interfaces/ITsiIconItem.cs
  27. 6 1
      ContextMenuManager/Controls/Interfaces/ITsiRegExportItem.cs
  28. 4 0
      ContextMenuManager/Controls/Interfaces/ITsiShortcutCommandItem.cs
  29. 7 6
      ContextMenuManager/Controls/Interfaces/ITsiTextItem.cs
  30. 11 16
      ContextMenuManager/Controls/NewShellDialog.cs
  31. 5 5
      ContextMenuManager/Controls/SendToList.cs
  32. 2 1
      ContextMenuManager/Controls/ShellExItem.cs
  33. 10 82
      ContextMenuManager/Controls/ShellItem.cs
  34. 30 3
      ContextMenuManager/Controls/ShellList.cs
  35. 10 7
      ContextMenuManager/Controls/ShellNewList.cs
  36. 25 20
      ContextMenuManager/Controls/ShellStoreDialog.cs
  37. 19 23
      ContextMenuManager/Controls/ShellSubMenuDialog.cs
  38. 1 1
      ContextMenuManager/Controls/UwpModeItem.cs
  39. 6 8
      ContextMenuManager/Controls/WinXGroupItem.cs
  40. 24 20
      ContextMenuManager/Controls/WinXList.cs
  41. 25 5
      ContextMenuManager/GuidInfo.cs
  42. 14 12
      ContextMenuManager/MainForm.cs
  43. 2 2
      ContextMenuManager/Program.cs
  44. 2 2
      ContextMenuManager/Properties/AssemblyInfo.cs
  45. 3 3
      ContextMenuManager/Properties/Resources.resx
  46. BIN
      ContextMenuManager/Properties/Resources/Images/AddExisting.png
  47. BIN
      ContextMenuManager/Properties/Resources/Images/AddSeparator.png
  48. BIN
      ContextMenuManager/Properties/Resources/Images/Donate.png
  49. 6 0
      ContextMenuManager/Properties/Resources/ShellNew/0.c
  50. 9 0
      ContextMenuManager/Properties/Resources/ShellNew/0.html
  51. BIN
      ContextMenuManager/Properties/Resources/ShellNew/0.rar
  52. BIN
      ContextMenuManager/Properties/Resources/ShellNew/0.reg
  53. 1 0
      ContextMenuManager/Properties/Resources/ShellNew/0.rtf
  54. BIN
      ContextMenuManager/Properties/Resources/ShellNew/0.xlsx
  55. 1 0
      ContextMenuManager/Properties/Resources/ShellNew/0.xml
  56. BIN
      ContextMenuManager/Properties/Resources/ShellNew/0.zip
  57. 30 26
      ContextMenuManager/Properties/Resources/Texts/AppLanguageDic.ini
  58. 80 75
      ContextMenuManager/Properties/Resources/Texts/EnhanceMenusDic.xml
  59. 77 62
      ContextMenuManager/Properties/Resources/Texts/GuidInfosDic.ini
  60. 1 0
      ContextMenuManager/Properties/Resources/Texts/ThirdRulesDic.xml
  61. 90 34
      ContextMenuManager/Updater.cs
  62. 69 56
      Donate.md
  63. 1 1
      README-en.md
  64. 3 3
      README.md
  65. BIN
      Screenshot/AppImage.png
  66. 30 26
      languages/zh-CN.ini

+ 4 - 3
ContextMenuManager/App.config

@@ -1,10 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <startup>
-    
-  <supportedRuntime version="v2.0.50727"/></startup>
+    <supportedRuntime version="v2.0.50727"/>
+    <supportedRuntime version="v4.0"/>
+  </startup>
   <runtime>
     <legacyCorruptedStateExceptionsPolicy enabled="true"/>
     <EnableWindowsFormsHighDpiAutoResizing enabled="true"/>
   </runtime>
-</configuration>
+</configuration>

+ 6 - 0
ContextMenuManager/AppConfig.cs

@@ -144,6 +144,12 @@ namespace ContextMenuManager
             set => SetGeneralValue("HideDisabledItems", value ? 1 : 0);
         }
 
+        public static bool HideSysStoreItems
+        {
+            get => GetGeneralValue("HideSysStoreItems") != "0";
+            set => SetGeneralValue("HideSysStoreItems", value ? 1 : 0);
+        }
+
         public static bool RequestUseGithub
         {
             get

+ 7 - 3
ContextMenuManager/AppString.cs

@@ -144,6 +144,7 @@ namespace ContextMenuManager
             public static string CopyGuid => GetValue("CopyGuid");
             public static string BlockGuid => GetValue("BlockGuid");
             public static string AddGuidDic => GetValue("AddGuidDic");
+            public static string ClsidLocation => GetValue("ClsidLocation");
             public static string InitialData => GetValue("InitialData");
             public static string BeforeSeparator => GetValue("BeforeSeparator");
             public static string ChangeGroup => GetValue("ChangeGroup");
@@ -160,6 +161,8 @@ namespace ContextMenuManager
             public static string Cancel => GetValue("Cancel");
             public static string Browse => GetValue("Browse");
             public static string Program => GetValue("Program");
+            public static string AllFiles => GetValue("AllFiles");
+            public static string RegistryFile => GetValue("RegistryFile");
             public static string ItemText => GetValue("ItemText");
             public static string ItemCommand => GetValue("ItemCommand");
             public static string CommandArguments => GetValue("CommandArguments");
@@ -189,7 +192,6 @@ namespace ContextMenuManager
             public static string SelectPerceivedType => GetValue("SelectPerceivedType");
             public static string SelectDirectoryType => GetValue("SelectDirectoryType");
             public static string SelectNewItemType => GetValue("SelectNewItemType");
-            public static string RegistryFile => GetValue("RegistryFile");
             public static string SelectGroup => GetValue("SelectGroup");
             public static string SelectObjectType => GetValue("SelectObjectType");
             public static string SelectDropEffect => GetValue("SelectDropEffect");
@@ -241,7 +243,7 @@ namespace ContextMenuManager
             public static string WinXSorted => GetValue("WinXSorted");
             public static string RestoreDefault => GetValue("RestoreDefault");
             public static string DeleteGroup => GetValue("DeleteGroup");
-            public static string NetworkDtaReadFailed => GetValue("NetworkDtaReadFailed");
+            public static string WebDataReadFailed => GetValue("WebDataReadFailed");
         }
 
         /// <summary>其他文本</summary>
@@ -278,7 +280,7 @@ namespace ContextMenuManager
             public static string UserDictionaries => GetValue("UserDictionaries");
             public static string DictionaryDescription => GetValue("DictionaryDescription");
             public static string GuidInfosDictionary => GetValue("GuidInfosDictionary");
-            public static string UWPMode => GetValue("UWPMode");
+            public static string UwpMode => GetValue("UWPMode");
             public static string Translators => GetValue("Translators");
             public static string AboutApp => GetValue("AboutApp");
             public static string Dictionaries => GetValue("Dictionaries");
@@ -303,6 +305,7 @@ namespace ContextMenuManager
             public static string ShowFilePath => GetValue("ShowFilePath");
             public static string OpenMoreRegedit => GetValue("OpenMoreRegedit");
             public static string HideDisabledItems => GetValue("HideDisabledItems");
+            public static string HideSysStoreItems => GetValue("HideSysStoreItems");
             public static string SetPerceivedType => GetValue("SetPerceivedType");
             public static string SetDefaultDropEffect => GetValue("SetDefaultDropEffect");
         }
@@ -319,6 +322,7 @@ namespace ContextMenuManager
             public static string InvalidItem => GetValue("InvalidItem");
             public static string AddSeparator => GetValue("AddSeparator");
             public static string AddReference => GetValue("AddReference");
+            public static string AddFromPublic => GetValue("AddFromPublic");
             public static string AddFromParentMenu => GetValue("AddFromParentMenu");
             public static string DeleteGuidDic => GetValue("DeleteGuidDic");
             public static string LockNewMenu => GetValue("LockNewMenu");

+ 5 - 3
ContextMenuManager/BluePointLilac.Controls/DownloadDialog.cs

@@ -1,6 +1,7 @@
 using BluePointLilac.Methods;
 using ContextMenuManager;
 using System;
+using System.Diagnostics;
 using System.Drawing;
 using System.IO;
 using System.Windows.Forms;
@@ -15,10 +16,11 @@ namespace BluePointLilac.Controls
 
         protected override bool RunDialog(IntPtr hwndOwner)
         {
-            using(DownloadForm frm = new DownloadForm())
+            using(Process process = Process.GetCurrentProcess())
+            using(DownloadForm frm = new DownloadForm { Url = this.Url, FilePath = this.FilePath })
             {
-                frm.Url = this.Url;
-                frm.FilePath = this.FilePath;
+                bool isAsyn = hwndOwner == process.MainWindowHandle;
+                frm.StartPosition = isAsyn ? FormStartPosition.CenterParent : FormStartPosition.CenterScreen;
                 return frm.ShowDialog() == DialogResult.OK;
             }
         }

+ 6 - 6
ContextMenuManager/BluePointLilac.Controls/IconDialog.cs

@@ -7,11 +7,16 @@ namespace BluePointLilac.Controls
 {
     public sealed class IconDialog : CommonDialog
     {
-        const int MAXLENGTH = 260;//文件名最大长度
+        [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "#62", SetLastError = true)]
+        private static extern bool PickIconDlg(IntPtr hWnd, StringBuilder pszFileName, int cchFileNameMax, ref int pnIconIndex);
+
+        private const int MAXLENGTH = 260;
         private int iconIndex;
         public int IconIndex { get => iconIndex; set => iconIndex = value; }
         public string IconPath { get; set; }
 
+        public override void Reset() { }
+
         protected override bool RunDialog(IntPtr hwndOwner)
         {
             StringBuilder sb = new StringBuilder(IconPath, MAXLENGTH);
@@ -19,10 +24,5 @@ namespace BluePointLilac.Controls
             IconPath = flag ? sb.ToString() : null;
             return flag;
         }
-
-        public override void Reset() { }
-
-        [DllImport("shell32.dll", CharSet = CharSet.Unicode, EntryPoint = "#62", SetLastError = true)]
-        private static extern bool PickIconDlg(IntPtr hWnd, StringBuilder pszFileName, int cchFileNameMax, ref int pnIconIndex);
     }
 }

+ 4 - 3
ContextMenuManager/BluePointLilac.Controls/InputDialog.cs

@@ -12,18 +12,19 @@ namespace BluePointLilac.Controls
         public string Title { get; set; } = AppString.General.AppName;
         /// <summary>输入对话框文本框文本</summary>
         public string Text { get; set; }
+        public Size Size { get; set; }
 
-        private static Size LastSize = new Size();
         public override void Reset() { }
 
         protected override bool RunDialog(IntPtr hwndOwner)
         {
-            using(InputBox frm = new InputBox { Text = Title, Size = LastSize })
+            using(InputBox frm = new InputBox())
             {
+                frm.Text = Title;
                 frm.InputedText = this.Text;
+                frm.Size = this.Size;
                 bool flag = frm.ShowDialog() == DialogResult.OK;
                 this.Text = flag ? frm.InputedText : null;
-                LastSize = frm.Size;
                 return flag;
             }
         }

+ 0 - 14
ContextMenuManager/BluePointLilac.Methods/ComboBoxExtension.cs

@@ -17,20 +17,6 @@ namespace BluePointLilac.Methods
                 maxWidth = Math.Max(maxWidth, box.Width);
                 box.DropDownWidth = maxWidth;
             };
-            //ToolTip toolTip = new ToolTip() { AutoPopDelay = 0, InitialDelay = 0, ReshowDelay = 0, ShowAlways = true, };
-            //box.DrawMode = DrawMode.OwnerDrawFixed;
-            //box.DrawItem += (s, e) =>
-            //{
-            //    e.DrawBackground();
-            //    string text = box.GetItemText(box.Items[e.Index]);
-            //    using(SolidBrush br = new SolidBrush(e.ForeColor))
-            //        e.Graphics.DrawString(text, e.Font, br, e.Bounds);
-            //    if((e.State & DrawItemState.Selected) == DrawItemState.Selected && box.DroppedDown)
-            //        toolTip.Show(text, box, e.Bounds.Right, e.Bounds.Bottom + 4);
-            //    e.DrawFocusRectangle();
-            //};
-            //box.DropDownClosed += (s, e) =>
-            //    toolTip.Hide(box);
         }
     }
 }

+ 32 - 29
ContextMenuManager/BluePointLilac.Methods/ElevatedFileDroper.cs

@@ -12,11 +12,11 @@ namespace BluePointLilac.Methods
     /// 代码来源2:https://github.com/volschin/sdimager/blob/master/ElevatedDragDropManager.cs
     /// 代码作者:雨少主(知乎)、volschin(Github)、蓝点lilac(转载、修改)
     /// 调用方法:var droper = new ElevatedFileDroper(control);
-    /// control.DragDrop += (sender, e) => MessageBox.Show(droper.DropFilePaths[0]);
+    /// droper.DragDrop += (sender, e) => MessageBox.Show(droper.DropFilePaths[0]);
+    /// 备注:此类只能生效一个实例,不能将control.AllowDrop设为true,droper.DragDrop与control.DragDrop不共存
 
     public sealed class ElevatedFileDroper : IMessageFilter
     {
-        #region native members
         [DllImport("user32.dll", SetLastError = true)]
         [return: MarshalAs(UnmanagedType.Bool)]
         private static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint message, ChangeFilterAction action, in ChangeFilterStruct pChangeFilterStruct);
@@ -68,19 +68,32 @@ namespace BluePointLilac.Methods
         const uint WM_COPYGLOBALDATA = 0x0049;
         const uint WM_COPYDATA = 0x004A;
         const uint WM_DROPFILES = 0x0233;
-        #endregion
 
-        public Control ContainerControl { get; private set; }
+        public event EventHandler DragDrop;
         public string[] DropFilePaths { get; private set; }
         public Point DropPoint { get; private set; }
 
         public ElevatedFileDroper(Control ctr)
         {
-            this.ContainerControl = ctr;
-            ctr.DragDrop += (sender, e) => DropFilePaths = (string[])e.Data.GetData(typeof(string[]));
-            ctr.DragEnter += (sender, e) => e.Effect = DragDropEffects.All;
+            ctr.AllowDrop = false;
+            DragAcceptFiles(ctr.Handle, true);
+            Application.AddMessageFilter(this);
             ctr.Disposed += (sender, e) => Application.RemoveMessageFilter(this);
 
+            if(ctr is Form frm)
+            {
+                double opacity = frm.Opacity;
+                frm.Paint += (sender, e) =>
+                {
+                    if(frm.Opacity != opacity)
+                    {
+                        //窗体透明度变化时需要重新注册接受文件拖拽标识符
+                        DragAcceptFiles(ctr.Handle, true);
+                        opacity = frm.Opacity;
+                    }
+                };
+            }
+
             Version ver = Environment.OSVersion.Version;
             bool isVistaOrHigher = ver >= new Version(6, 0);
             bool isWin7OrHigher = ver >= new Version(6, 1);
@@ -101,35 +114,25 @@ namespace BluePointLilac.Methods
                     if(error) throw new Win32Exception(Marshal.GetLastWin32Error());
                 }
             }
-            DragAcceptFiles(ctr.Handle, true);
-            Application.AddMessageFilter(this);
         }
 
         public bool PreFilterMessage(ref Message m)
         {
             if(m.Msg != WM_DROPFILES) return false;
-            if(ContainerControl.AllowDrop)
+            IntPtr handle = m.WParam;
+            uint fileCount = DragQueryFile(handle, uint.MaxValue, null, 0);
+            string[] filePaths = new string[fileCount];
+            for(uint i = 0; i < fileCount; i++)
             {
-                DropPoint = ContainerControl.PointToClient(Cursor.Position);
-            }
-            else
-            {
-                IntPtr handle = m.WParam;
-                uint fileCount = DragQueryFile(handle, uint.MaxValue, null, 0);
-                string[] fileNames = new string[fileCount];
-                for(uint i = 0; i < fileCount; i++)
-                {
-                    StringBuilder sb = new StringBuilder(260);
-                    uint result = DragQueryFile(handle, i, sb, sb.Capacity);
-                    if(result > 0) fileNames[i] = sb.ToString();
-                }
-                DragQueryPoint(handle, out Point point);
-                DragFinish(handle);
-                DropPoint = point;
-                ContainerControl.AllowDrop = true;
-                ContainerControl.DoDragDrop(fileNames, DragDropEffects.All);
+                StringBuilder sb = new StringBuilder(260);
+                uint result = DragQueryFile(handle, i, sb, sb.Capacity);
+                if(result > 0) filePaths[i] = sb.ToString();
             }
-            ContainerControl.AllowDrop = false;
+            DragQueryPoint(handle, out Point point);
+            DragFinish(handle);
+            DropPoint = point;
+            DropFilePaths = filePaths;
+            DragDrop?.Invoke(null, null);
             return true;
         }
     }

+ 26 - 29
ContextMenuManager/BluePointLilac.Methods/EncodingType.cs

@@ -1,48 +1,45 @@
-using System;
-using System.IO;
+using System.IO;
 using System.Text;
 
 namespace BluePointLilac.Methods
 {
-    /// 获取文本文件编码类型
-    /// 代码主要为转载,仅做简单改动
-    /// 代码作者:Napoléon
-    /// 代码原文:https://www.cnblogs.com/guyun/p/4262587.html
+    /* 获取文本文件编码类型
+     * 代码参考:https://www.cnblogs.com/guyun/p/4262587.html (Napoléon)
+
+     * 各种带BOM的编码BOM值
+     * UTF-7 : 2B 2F 76
+     * UTF-8 : EF BB BF
+     * UTF-16LE : FF FE
+     * UTF-16BE : FE FF
+     * UTF-32LE : FF FE 00 00
+     * UTF-32BE : 00 00 FE FF
+     */
     public static class EncodingType
     {
-        /// <summary>给定文件的路径,读取文件的二进制数据,判断文件的编码类型</summary> 
+        /// <summary>获取给定的文件的编码类型</summary> 
         /// <param name=“filePath“>文件路径</param> 
         /// <returns>文件的编码类型</returns> 
         public static Encoding GetType(string filePath)
         {
-            using(FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
-                return GetType(fs);
-        }
-
-        /// <summary> 通过给定的文件流,判断文件的编码类型</summary>
-        /// <param name=“fs“>文件流</param> 
-        /// <returns>文件的编码类型</returns> 
-        public static Encoding GetType(FileStream fs)
-        {
-            byte[] ss;
-            int.TryParse(fs.Length.ToString(), out int i);
-            using(BinaryReader reader = new BinaryReader(fs, Encoding.Default))
-                ss = reader.ReadBytes(i);
-            if(IsUTF8Bytes(ss)) return Encoding.UTF8;
-            if(ss[0] == 0xEF && ss[1] == 0xBB && ss[2] == 0xBF) return Encoding.UTF8;//带BOM 
-            if(ss[0] == 0xFE && ss[1] == 0xFF) return Encoding.BigEndianUnicode;     //UTF-16BE
-            if(ss[0] == 0xFF && ss[1] == 0xFE) return Encoding.Unicode;              //UTF-16LE
+            byte[] bytes = File.ReadAllBytes(filePath);
+            if(bytes.Length >= 3 && bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) return Encoding.UTF8;//UTF-8
+            else if(bytes.Length >= 4 && bytes[0] == 0xFF && bytes[1] == 0xFE && bytes[2] == 0x00 && bytes[3] == 0x00) return Encoding.UTF32;//UTF-32LE
+            else if(bytes.Length >= 2 && bytes[0] == 0xFF && bytes[1] == 0xFE) return Encoding.Unicode; //UTF-16LE
+            else if(bytes.Length >= 2 && bytes[0] == 0xFE && bytes[1] == 0xFF) return Encoding.BigEndianUnicode; //UTF-16BE
+            else if(bytes.Length >= 3 && bytes[0] == 0x2B && bytes[1] == 0x2F && bytes[2] == 0x76) return Encoding.UTF7; //UTF-7
+            else if(bytes.Length >= 4 && bytes[0] == 0x00 && bytes[1] == 0x00 && bytes[2] == 0xFE && bytes[3] == 0xFF) return new UTF32Encoding(true, true);//UTF-32BE
+            else if(IsUTF8Bytes(bytes)) return Encoding.UTF8; //不带BOM的UTF-8
             return Encoding.Default;
         }
 
         /// <summary>判断是否是不带 BOM 的 UTF8 格式</summary> 
-        /// <param name=“data“></param> 
-        private static bool IsUTF8Bytes(byte[] data)
+        /// <param name=“bytes“></param> 
+        private static bool IsUTF8Bytes(byte[] bytes)
         {
             int count = 1; //计算当前正分析的字符应还有的字节数 
-            for(int i = 0; i < data.Length; i++)
+            for(int i = 0; i < bytes.Length; i++)
             {
-                byte curByte = data[i];//当前分析的字节. 
+                byte curByte = bytes[i];//当前分析的字节. 
                 if(count == 1)
                 {
                     if(curByte >= 0x80)
@@ -60,7 +57,7 @@ namespace BluePointLilac.Methods
                     else count--;
                 }
             }
-            if(count > 1) throw new Exception("非预期的byte格式");
+            //if(count > 1) throw new Exception("非预期的byte格式");
             return true;
         }
     }

+ 3 - 1
ContextMenuManager/BluePointLilac.Methods/ExternalProgram.cs

@@ -12,6 +12,7 @@ namespace BluePointLilac.Methods
     {
         public static void JumpRegEdit(string regPath, string valueName = null, bool moreOpen = false)
         {
+            if(regPath == null) return;
             Process process;
             IntPtr hMain = FindWindow("RegEdit_RegEdit", null);
             if(hMain != IntPtr.Zero && !moreOpen)
@@ -72,9 +73,10 @@ namespace BluePointLilac.Methods
 
         public static void JumpExplorer(string filePath)
         {
+            if(filePath == null) return;
             using(Process process = new Process())
             {
-                if(File.Exists(filePath) || filePath.StartsWith("shell:AppsFolder"))
+                if(File.Exists(filePath) || filePath.StartsWith("shell:AppsFolder", StringComparison.OrdinalIgnoreCase))
                 {
                     process.StartInfo.FileName = "explorer.exe";
                     process.StartInfo.Arguments = $"/select, {filePath}";

+ 5 - 5
ContextMenuManager/BluePointLilac.Methods/ObjectPath.cs

@@ -62,17 +62,17 @@ namespace BluePointLilac.Methods
                     if(arr.Length > 0)
                     {
                         string fileName = arr[0];
+                        if(GetFullFilePath(fileName, out filePath))
+                        {
+                            FilePathDic.Add(command, filePath);
+                            return filePath;
+                        }
                         if(arr.Length > 1)
                         {
                             string arguments = arr[1];
                             filePath = ExtractFilePath(arguments);
                             if(filePath != null) return filePath;
                         }
-                        if(GetFullFilePath(fileName, out filePath))
-                        {
-                            FilePathDic.Add(command, filePath);
-                            return filePath;
-                        }
                     }
                 }
 

+ 1 - 1
ContextMenuManager/BluePointLilac.Methods/RegistryEx.cs

@@ -159,7 +159,7 @@ namespace BluePointLilac.Methods
 
         public static void Export(string regPath, string filePath)
         {
-            if(File.Exists(filePath)) File.Delete(filePath);
+            File.Delete(filePath);
             using(Process process = Process.Start("regedit.exe", $"/e \"{filePath}\" \"{regPath}\""))
                 process.WaitForExit();
         }

+ 2 - 0
ContextMenuManager/BluePointLilac.Methods/ShellLink.cs

@@ -298,6 +298,8 @@ namespace BluePointLilac.Methods
             PersistFile.Save(lnkPath, true);
         }
 
+        public void Load() { Load(this.ShortcutPath); }
+
         public void Load(string lnkPath)
         {
             this.ShortcutPath = lnkPath;

+ 26 - 17
ContextMenuManager/BluePointLilac.Methods/SingleInstance.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Collections.Generic;
 using System.Diagnostics;
 using System.IO;
 using System.Runtime.InteropServices;
@@ -48,26 +49,34 @@ namespace BluePointLilac.Methods
             {
                 string command = Application.ExecutablePath;
                 if(args != null && args.Length > 0) command += "," + string.Join(" ", args);
-                string contents =
-                    "Dim wsh, fso\r\n" +
-                    "Set wsh = CreateObject(\"WScript.Shell\")\r\n" +
-                    "Set fso = CreateObject(\"Scripting.FileSystemObject\")\r\n" +
-                    "fso.DeleteFile(WScript.ScriptFullName)\r\n" +  //vbs自删命令
-                    $"wsh.Run \"taskkill /pid {pApp.Id} -f\",0\r\n" +
-                    "WScript.Sleep 1000\r\n";
+                List<string> contents = new List<string>();
+                contents.AddRange(new[]{
+                    "Dim wsh, fso",
+                    "Set wsh = CreateObject(\"WScript.Shell\")",
+                    "Set fso = CreateObject(\"Scripting.FileSystemObject\")",
+                    "fso.DeleteFile(WScript.ScriptFullName)",//vbs自删命令
+                    $"wsh.Run \"taskkill /pid {pApp.Id} -f\",0",//杀死当前进程
+                    "WScript.Sleep 1000"
+                });
 
-                if(updatePath != null) contents +=
-                    $"fso.DeleteFile \"{Application.ExecutablePath}\"\r\n" +
-                    "WScript.Sleep 1000\r\n" +
-                    $"fso.MoveFile \"{updatePath}\",\"{Application.ExecutablePath}\"\r\n";
-
-                contents +=
-                    $"wsh.Run \"{command}\"\r\n" +
-                    "Set wsh = Nothing\r\n" +
-                    "Set fso = Nothing\r\n";
+                if(File.Exists(updatePath))
+                {
+                    contents.AddRange(new[]
+                    {
+                        $"fso.DeleteFile \"{Application.ExecutablePath}\"",
+                        "WScript.Sleep 1000",
+                        $"fso.MoveFile \"{updatePath}\",\"{Application.ExecutablePath}\""//更新文件
+                    });
+                }
+                contents.AddRange(new[]
+                {
+                    $"wsh.Run \"{command}\"",
+                    "Set wsh = Nothing",
+                    "Set fso = Nothing"
+                });
 
                 string vbsPath = Path.GetTempPath() + "Restart.vbs";
-                File.WriteAllText(vbsPath, contents, Encoding.Unicode);
+                File.WriteAllLines(vbsPath, contents.ToArray(), Encoding.Unicode);
                 using(Process pVbs = new Process())
                 {
                     pVbs.StartInfo.FileName = "wscript.exe";

+ 12 - 2
ContextMenuManager/BluePointLilac.Methods/UAWebClient.cs

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

+ 16 - 4
ContextMenuManager/ContextMenuManager.csproj

@@ -34,7 +34,7 @@
     <PlatformTarget>AnyCPU</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
-    <Optimize>true</Optimize>
+    <Optimize>false</Optimize>
     <OutputPath>bin\Debug\</OutputPath>
     <DefineConstants>DEBUG;TRACE</DefineConstants>
     <ErrorReport>prompt</ErrorReport>
@@ -367,12 +367,20 @@
     <Compile Include="Updater.cs" />
     <None Include="App.config" />
     <None Include="Properties\App.manifest" />
+    <None Include="Properties\Resources\ShellNew\0.rar" />
+    <None Include="Properties\Resources\ShellNew\0.reg" />
+    <None Include="Properties\Resources\ShellNew\0.rtf" />
+    <None Include="Properties\Resources\ShellNew\0.xlsx" />
+    <None Include="Properties\Resources\ShellNew\0.zip" />
     <None Include="Properties\Resources\Texts\AppLanguageDic.ini" />
     <None Include="Properties\Resources\Texts\GuidInfosDic.ini" />
     <Content Include="Properties\Resources\Images\DownLoad.png" />
     <Content Include="Properties\Resources\Images\Jump.png" />
     <Content Include="Properties\Resources\Images\Translate.png" />
     <Content Include="Properties\Resources\Images\User.png" />
+    <Content Include="Properties\Resources\ShellNew\0.c" />
+    <Content Include="Properties\Resources\ShellNew\0.html" />
+    <Content Include="Properties\Resources\ShellNew\0.xml" />
     <Content Include="Properties\Resources\Texts\UwpModeItemsDic.xml" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
@@ -428,14 +436,18 @@
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
     </EmbeddedResource>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
     <PreBuildEvent>
     </PreBuildEvent>
   </PropertyGroup>
   <PropertyGroup>
-    <PostBuildEvent>mkdir $(TargetDir)\Config\languages
-xcopy $(ProjectDir)\Properties\Resources\Texts\AppLanguageDic.ini $(SolutionDir)\languages\zh-CN.ini /y
-xcopy $(SolutionDir)\languages $(TargetDir)\config\languages /y</PostBuildEvent>
+    <PostBuildEvent>mkdir $(TargetDir)\Config\Languages
+mkdir $(TargetDir)\Config\Dictionaries\Web
+xcopy $(ProjectDir)\Properties\Resources\Texts\AppLanguageDic.ini $(SolutionDir)\Languages\zh-CN.ini /y
+xcopy $(SolutionDir)\Languages $(TargetDir)\config\Languages /y
+xcopy $(ProjectDir)\Properties\Resources\Texts $(TargetDir)\Config\Dictionaries\Web /y
+del $(TargetDir)\Config\Dictionaries\Web\AppLanguageDic.ini</PostBuildEvent>
   </PropertyGroup>
 </Project>

+ 66 - 19
ContextMenuManager/Controls/AboutApp.cs

@@ -13,43 +13,81 @@ namespace ContextMenuManager.Controls
     {
         public DonateBox()
         {
+            this.AutoScroll = true;
             this.Dock = DockStyle.Fill;
             this.BackColor = Color.White;
-            this.AutoScroll = true;
             this.Font = new Font(SystemFonts.MenuFont.FontFamily, 10F);
-            this.Controls.AddRange(new Control[] { lblInfo, picQR, llbDonationList });
-            llbDonationList.LinkClicked += (sender, e) => Updater.ShowDonateDialog();
+            this.Controls.AddRange(new Control[] { lblInfo, picQR, lblList });
+            lblList.Click += (sender, e) => Updater.ShowDonateDialog();
+            picQR.Resize += (sender, e) => this.OnResize(null);
+            picQR.MouseDown += SwitchQR;
         }
 
         readonly Label lblInfo = new Label
         {
+            BorderStyle = BorderStyle.FixedSingle,
             Text = AppString.Other.Donate,
             AutoSize = true
         };
 
-        readonly LinkLabel llbDonationList = new LinkLabel
+        readonly Label lblList = new Label
         {
+            ForeColor = Color.FromArgb(85, 145, 215),
+            BorderStyle = BorderStyle.FixedSingle,
             Text = AppString.Other.DonationList,
+            Cursor = Cursors.Hand,
             AutoSize = true
         };
 
         readonly PictureBox picQR = new PictureBox
         {
-            Image = Properties.Resources.Donate,
-            SizeMode = PictureBoxSizeMode.Zoom,
-            Size = new Size(600, 200).DpiZoom()
+            SizeMode = PictureBoxSizeMode.AutoSize,
+            BorderStyle = BorderStyle.FixedSingle,
+            Cursor = Cursors.Hand,
+            Image = AllQR,
         };
 
+        static readonly Image AllQR = Properties.Resources.Donate;
+        static readonly Image WechatQR = GetSingleQR(0);
+        static readonly Image AlipayQR = GetSingleQR(1);
+        static readonly Image QQQR = GetSingleQR(2);
+
         protected override void OnResize(EventArgs e)
         {
             int a = 60.DpiZoom();
             base.OnResize(e);
             picQR.Left = (this.Width - picQR.Width) / 2;
             lblInfo.Left = (this.Width - lblInfo.Width) / 2;
-            llbDonationList.Left = (this.Width - llbDonationList.Width) / 2;
+            lblList.Left = (this.Width - lblList.Width) / 2;
             lblInfo.Top = a;
             picQR.Top = lblInfo.Bottom + a;
-            llbDonationList.Top = picQR.Bottom + a;
+            lblList.Top = picQR.Bottom + a;
+        }
+
+        private static Image GetSingleQR(int index)
+        {
+            Bitmap bitmap = new Bitmap(200, 200);
+            using(Graphics g = Graphics.FromImage(bitmap))
+            {
+                Rectangle destRect = new Rectangle(0, 0, 200, 200);
+                Rectangle srcRect = new Rectangle(index * 200, 0, 200, 200);
+                g.DrawImage(AllQR, destRect, srcRect, GraphicsUnit.Pixel);
+            }
+            return bitmap;
+        }
+
+        private void SwitchQR(object sender, MouseEventArgs e)
+        {
+            if(picQR.Image == AllQR)
+            {
+                if(e.X < 200) picQR.Image = WechatQR;
+                else if(e.X < 400) picQR.Image = AlipayQR;
+                else picQR.Image = QQQR;
+            }
+            else
+            {
+                picQR.Image = AllQR;
+            }
         }
     }
 
@@ -82,7 +120,7 @@ namespace ContextMenuManager.Controls
             new TabPage(AppString.Other.GuidInfosDictionary),
             new TabPage(AppString.SideBar.ThirdRules),
             new TabPage(AppString.SideBar.EnhanceMenu),
-            new TabPage(AppString.Other.UWPMode)
+            new TabPage(AppString.Other.UwpMode)
         };
         readonly ReadOnlyRichTextBox[] boxs = new ReadOnlyRichTextBox[6];
         readonly PictureButton btnOpenDir = new PictureButton(AppImage.Open)
@@ -279,6 +317,7 @@ namespace ContextMenuManager.Controls
             mliShowFilePath.AddCtr(chkShowFilePath);
             mliOpenMoreRegedit.AddCtr(chkOpenMoreRegedit);
             mliHideDisabledItems.AddCtr(chkHideDisabledItems);
+            mliHideSysStoreItems.AddCtr(chkHideSysStoreItems);
             cmbConfigDir.AutosizeDropDownWidth();
             cmbEngine.AutosizeDropDownWidth();
             cmbRepo.AutosizeDropDownWidth();
@@ -301,6 +340,7 @@ namespace ContextMenuManager.Controls
             chkWinXSortable.MouseDown += (sender, e) => AppConfig.WinXSortable = chkWinXSortable.Checked = !chkWinXSortable.Checked;
             chkOpenMoreRegedit.MouseDown += (sender, e) => AppConfig.OpenMoreRegedit = chkOpenMoreRegedit.Checked = !chkOpenMoreRegedit.Checked;
             chkHideDisabledItems.MouseDown += (sender, e) => AppConfig.HideDisabledItems = chkHideDisabledItems.Checked = !chkHideDisabledItems.Checked;
+            chkHideSysStoreItems.MouseDown += (sender, e) => AppConfig.HideSysStoreItems = chkHideSysStoreItems.Checked = !chkHideSysStoreItems.Checked;
             cmbConfigDir.SelectionChangeCommitted += (sender, e) =>
             {
                 string newPath = (cmbConfigDir.SelectedIndex == 0) ? AppConfig.AppDataConfigDir : AppConfig.AppConfigDir;
@@ -429,14 +469,6 @@ namespace ContextMenuManager.Controls
             Width = 120.DpiZoom()
         };
 
-        readonly MyListItem mliWinXSortable = new MyListItem
-        {
-            Text = AppString.Other.WinXSortable,
-            Visible = WindowsOsVersion.ISAfterOrEqual8,
-            HasImage = false
-        };
-        readonly MyCheckBox chkWinXSortable = new MyCheckBox();
-
         readonly MyListItem mliShowFilePath = new MyListItem
         {
             Text = AppString.Other.ShowFilePath
@@ -455,10 +487,24 @@ namespace ContextMenuManager.Controls
         };
         readonly MyCheckBox chkHideDisabledItems = new MyCheckBox();
 
+        readonly MyListItem mliWinXSortable = new MyListItem
+        {
+            Text = AppString.Other.WinXSortable,
+            Visible = WindowsOsVersion.ISAfterOrEqual8
+        };
+        readonly MyCheckBox chkWinXSortable = new MyCheckBox();
+
+        readonly MyListItem mliHideSysStoreItems = new MyListItem
+        {
+            Text = AppString.Other.HideSysStoreItems,
+            Visible = WindowsOsVersion.ISAfterOrEqual7
+        };
+        readonly MyCheckBox chkHideSysStoreItems = new MyCheckBox();
+
         public void LoadItems()
         {
             this.AddItems(new[] { mliUpdate, mliConfigDir, mliRepo, mliEngine, mliBackup, mliProtect,
-                mliWinXSortable, mliShowFilePath, mliOpenMoreRegedit, mliHideDisabledItems });
+                mliShowFilePath, mliOpenMoreRegedit, mliHideDisabledItems,mliHideSysStoreItems,mliWinXSortable });
             foreach(MyListItem item in this.Controls) item.HasImage = false;
             cmbConfigDir.SelectedIndex = AppConfig.SaveToAppDir ? 1 : 0;
             cmbRepo.SelectedIndex = AppConfig.RequestUseGithub ? 0 : 1;
@@ -468,6 +514,7 @@ namespace ContextMenuManager.Controls
             chkShowFilePath.Checked = AppConfig.ShowFilePath;
             chkOpenMoreRegedit.Checked = AppConfig.OpenMoreRegedit;
             chkHideDisabledItems.Checked = AppConfig.HideDisabledItems;
+            chkHideSysStoreItems.Checked = AppConfig.HideSysStoreItems;
 
             int index = 1;
             switch(AppConfig.UpdateFrequency)

+ 25 - 10
ContextMenuManager/Controls/DonateListDialog.cs

@@ -2,6 +2,7 @@
 using System;
 using System.ComponentModel;
 using System.Drawing;
+using System.Linq;
 using System.Windows.Forms;
 
 namespace ContextMenuManager.Controls
@@ -17,6 +18,9 @@ namespace ContextMenuManager.Controls
             using(DonateListForm frm = new DonateListForm())
             {
                 frm.ShowDonateList(DanateData);
+                MainForm mainForm = (MainForm)Control.FromHandle(hwndOwner);
+                frm.Left = mainForm.Left + (mainForm.Width + mainForm.GetSideBarWidth() - frm.Width) / 2;
+                frm.Top = mainForm.Top + 150.DpiZoom();
                 frm.ShowDialog();
             }
             return true;
@@ -28,11 +32,12 @@ namespace ContextMenuManager.Controls
             {
                 this.Text = AppString.Other.DonationList;
                 this.SizeGripStyle = SizeGripStyle.Hide;
-                this.StartPosition = FormStartPosition.CenterParent;
+                this.StartPosition = FormStartPosition.Manual;
                 this.MinimizeBox = this.MaximizeBox = this.ShowInTaskbar = false;
                 this.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
                 this.Font = new Font(SystemFonts.DialogFont.FontFamily, 9F);
-                this.ClientSize = new Size(520, 378).DpiZoom();
+                this.ClientSize = new Size(520, 355).DpiZoom();
+                this.MinimumSize = this.Size;
                 dgvDonate.ColumnHeadersDefaultCellStyle.Alignment
                     = dgvDonate.RowsDefaultCellStyle.Alignment
                     = DataGridViewContentAlignment.BottomCenter;
@@ -42,7 +47,7 @@ namespace ContextMenuManager.Controls
 
             readonly DataGridView dgvDonate = new DataGridView
             {
-                ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing,
+                ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize,
                 AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells,
                 SelectionMode = DataGridViewSelectionMode.FullRowSelect,
                 BackgroundColor = SystemColors.Control,
@@ -70,25 +75,35 @@ namespace ContextMenuManager.Controls
             {
                 string[] lines = contents.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                 int index = Array.FindIndex(lines, line => line == "|:--:|:--:|:--:|:--:|:--:");
+                if(index == -1) return;
                 string[] heads = lines[index - 1].Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                 dgvDonate.ColumnCount = heads.Length;
+                dgvDonate.Columns[4].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                 for(int m = 0; m < heads.Length; m++)
                 {
                     dgvDonate.Columns[m].HeaderText = heads[m];
                 }
                 for(int n = index + 1; n < lines.Length; n++)
                 {
-                    string[] values = lines[n].Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+                    string[] strs = lines[n].Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+                    object[] values = new object[strs.Length];
+                    for(int k = 0; k < strs.Length; k++)
+                    {
+                        switch(k)
+                        {
+                            case 3:
+                                values[k] = Convert.ToSingle(strs[k]);
+                                break;
+                            default:
+                                values[k] = strs[k];
+                                break;
+                        }
+                    }
                     dgvDonate.Rows.Add(values);
                 }
                 dgvDonate.Sort(dgvDonate.Columns[0], ListSortDirection.Descending);
                 DateTime date = Convert.ToDateTime(dgvDonate.Rows[0].Cells[0].Value);
-                float money = 0;
-                foreach(DataGridViewRow row in dgvDonate.Rows)
-                {
-                    money += Convert.ToSingle(row.Cells[3].Value);
-                }
-                dgvDonate.Columns[4].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
+                float money = dgvDonate.Rows.Cast<DataGridViewRow>().Sum(row => (float)row.Cells[3].Value);
                 lblDonate.Text = AppString.Dialog.DonateInfo.Replace("%date", date.ToLongDateString())
                     .Replace("%money", money.ToString()).Replace("%count", dgvDonate.RowCount.ToString());
             }

+ 25 - 12
ContextMenuManager/Controls/EnhanceMenusItem.cs

@@ -123,18 +123,31 @@ namespace ContextMenuManager.Controls
 
         private static string CreateCommandFile(XmlElement xe)
         {
-            if(xe == null) return string.Empty;
-            XmlElement cfXE = (XmlElement)xe.SelectSingleNode("CreateFile");
-            if(cfXE == null) return string.Empty;
-            string fileName = cfXE.GetAttribute("FileName");
-            string content = cfXE.GetAttribute("Content");
-            string extension = Path.GetExtension(fileName).ToLower();
-            string filePath = $@"{AppConfig.ProgramsDir}\{fileName}";
-            Encoding encoding = Encoding.Unicode;
-            if(extension == ".bat" || extension == ".cmd") encoding = Encoding.Default;
-            if(File.Exists(filePath)) File.Delete(filePath);
-            File.WriteAllText(filePath, content, encoding);
-            return filePath;
+            string path = string.Empty;
+            if(xe == null) return path;
+            foreach(XmlElement cfXE in xe.SelectNodes("CreateFile"))
+            {
+                string fileName = cfXE.GetAttribute("FileName");
+                string content = cfXE.GetAttribute("Content");
+                string extension = Path.GetExtension(fileName).ToLower();
+                string filePath = $@"{AppConfig.ProgramsDir}\{fileName}";
+                if(path == string.Empty) path = filePath;
+                Encoding encoding;
+                switch(extension)
+                {
+                    case ".bat":
+                    case ".cmd":
+                        encoding = Encoding.Default;
+                        break;
+                    default:
+                        encoding = Encoding.Unicode;
+                        break;
+                }
+                File.Delete(filePath);
+                File.WriteAllText(filePath, content, encoding);
+
+            }
+            return path;
         }
     }
 

+ 2 - 0
ContextMenuManager/Controls/EnhanceMenusList.cs

@@ -198,6 +198,7 @@ namespace ContextMenuManager.Controls
 
         public static bool JudgeOSVersion(XmlElement itemXE)
         {
+            //return true;//测试用
             bool JudgeOne(XmlElement osXE)
             {
                 Version ver = new Version(osXE.InnerText);
@@ -230,6 +231,7 @@ namespace ContextMenuManager.Controls
 
         private static bool FileExists(XmlElement itemXE)
         {
+            //return true;//测试用
             foreach(XmlElement feXE in itemXE.SelectNodes("FileExists"))
             {
                 string path = Environment.ExpandEnvironmentVariables(feXE.InnerText);

+ 18 - 4
ContextMenuManager/Controls/GuidBlockedItem.cs

@@ -2,6 +2,7 @@
 using BluePointLilac.Methods;
 using ContextMenuManager.Controls.Interfaces;
 using System;
+using System.Linq;
 using System.Windows.Forms;
 
 namespace ContextMenuManager.Controls
@@ -28,8 +29,23 @@ namespace ContextMenuManager.Controls
 
         public string Value { get; set; }
         public Guid Guid { get; set; }
+        public string SearchText => Value;
         public string ValueName => Value;
-        public string RegPath => GuidBlockedList.HKLMBLOCKED;
+        public string RegPath
+        {
+            get
+            {
+                foreach(string path in GuidBlockedList.BlockedPaths)
+                {
+                    using(var key = RegistryEx.GetRegistryKey(path))
+                    {
+                        if(key == null) continue;
+                        if(key.GetValueNames().Contains(Value, StringComparer.OrdinalIgnoreCase)) return path;
+                    }
+                }
+                return null;
+            }
+        }
 
         public string ItemText
         {
@@ -49,8 +65,6 @@ namespace ContextMenuManager.Controls
             }
         }
 
-
-        public string SearchText => Value;
         public string ItemFilePath { get; set; }
         public DeleteButton BtnDelete { get; set; }
         public ObjectPathButton BtnOpenPath { get; set; }
@@ -71,7 +85,7 @@ namespace ContextMenuManager.Controls
             TsiFileProperties = new FilePropertiesMenuItem(this);
             TsiFileLocation = new FileLocationMenuItem(this);
             TsiRegLocation = new RegLocationMenuItem(this);
-            TsiHandleGuid = new HandleGuidMenuItem(this, false);
+            TsiHandleGuid = new HandleGuidMenuItem(this);
 
             ContextMenuStrip.Items.AddRange(new ToolStripItem[] {TsiHandleGuid,
                 new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDelete });

+ 1 - 1
ContextMenuManager/Controls/Interfaces/IBtnDeleteItem.cs

@@ -23,7 +23,7 @@ namespace ContextMenuManager.Controls.Interfaces
                 {
                     MyList list = (MyList)listItem.Parent;
                     int index = list.GetItemIndex(listItem);
-                    index -= (index < list.Controls.Count) ? 0 : 1;
+                    index -= (index < list.Controls.Count - 1) ? 0 : 1;
                     item.DeleteMe();
                     list.HoveredItem = (MyListItem)list.Controls[index];
                 }

+ 5 - 1
ContextMenuManager/Controls/Interfaces/ITsiCommandItem.cs

@@ -1,5 +1,6 @@
 using BluePointLilac.Controls;
 using BluePointLilac.Methods;
+using System.Drawing;
 using System.Windows.Forms;
 
 namespace ContextMenuManager.Controls.Interfaces
@@ -25,8 +26,11 @@ namespace ContextMenuManager.Controls.Interfaces
 
         private string ChangeCommand(string command)
         {
-            using(InputDialog dlg = new InputDialog { Text = command, Title = AppString.Menu.ChangeCommand })
+            using(InputDialog dlg = new InputDialog())
             {
+                dlg.Text = command;
+                dlg.Title = AppString.Menu.ChangeCommand;
+                dlg.Size = new Size(500, 270).DpiZoom();
                 if(dlg.ShowDialog() != DialogResult.OK) return null;
                 if(!CommandCanBeEmpty && string.IsNullOrEmpty(dlg.Text))
                 {

+ 1 - 1
ContextMenuManager/Controls/Interfaces/ITsiDeleteItem.cs

@@ -40,7 +40,7 @@ namespace ContextMenuManager.Controls.Interfaces
                 MyListItem listItem = (MyListItem)item;
                 MyList list = (MyList)listItem.Parent;
                 int index = list.GetItemIndex(listItem);
-                index -= (index < list.Controls.Count) ? 0 : 1;
+                index -= (index < list.Controls.Count - 1) ? 0 : 1;
                 item.DeleteMe();
                 list.HoveredItem = (MyListItem)list.Controls[index];
             };

+ 8 - 7
ContextMenuManager/Controls/Interfaces/ITsiGuidItem.cs

@@ -15,17 +15,17 @@ namespace ContextMenuManager.Controls.Interfaces
 
     sealed class HandleGuidMenuItem : ToolStripMenuItem
     {
-        public HandleGuidMenuItem(ITsiGuidItem item, bool isShellExItem) : base(AppString.Menu.HandleGuid)
+        public HandleGuidMenuItem(ITsiGuidItem item) : base(AppString.Menu.HandleGuid)
         {
             this.Item = item;
-            this.DropDownItems.Add(TsiCopyGuid);
-            if(isShellExItem)
+            this.DropDownItems.AddRange(new ToolStripItem[] {
+                TsiAddGuidDic, new ToolStripSeparator(), TsiCopyGuid });
+            if(item is ShellExItem shellExItem)
             {
-                this.DropDownItems.Add(new ToolStripSeparator());
-                this.DropDownItems.Add(TsiBlockGuid);
+                this.DropDownItems.AddRange(new ToolStripItem[] { TsiBlockGuid, TsiClsidLocation });
+                shellExItem.ContextMenuStrip.Opening += (sender, e) => TsiClsidLocation.Visible = shellExItem.ClsidPath != null;
+                TsiClsidLocation.Click += (sender, e) => ExternalProgram.JumpRegEdit(shellExItem.ClsidPath);
             }
-            this.DropDownItems.Add(new ToolStripSeparator());
-            this.DropDownItems.Add(TsiAddGuidDic);
             TsiCopyGuid.Click += (sender, e) => CopyGuid();
             TsiBlockGuid.Click += (sender, e) => BlockGuid();
             TsiAddGuidDic.Click += (sender, e) => AddGuidDic();
@@ -49,6 +49,7 @@ namespace ContextMenuManager.Controls.Interfaces
         readonly ToolStripMenuItem TsiCopyGuid = new ToolStripMenuItem(AppString.Menu.CopyGuid);
         readonly ToolStripMenuItem TsiBlockGuid = new ToolStripMenuItem(AppString.Menu.BlockGuid);
         readonly ToolStripMenuItem TsiAddGuidDic = new ToolStripMenuItem(AppString.Menu.AddGuidDic);
+        readonly ToolStripMenuItem TsiClsidLocation = new ToolStripMenuItem(AppString.Menu.ClsidLocation);
 
         public ITsiGuidItem Item { get; set; }
 

+ 1 - 0
ContextMenuManager/Controls/Interfaces/ITsiIconItem.cs

@@ -39,6 +39,7 @@ namespace ContextMenuManager.Controls.Interfaces
             listItem.Disposed += (sender, e) => item.ItemIcon?.Dispose();
             listItem.ImageDoubleClick += (sender, e) =>
             {
+                if(listItem.FindForm() is ShellStoreDialog.ShellStoreForm) return;
                 if(this.Enabled) this.OnClick(null);
             };
         }

+ 6 - 1
ContextMenuManager/Controls/Interfaces/ITsiRegExportItem.cs

@@ -17,6 +17,11 @@ namespace ContextMenuManager.Controls.Interfaces
     {
         public RegExportMenuItem(ITsiRegExportItem item) : base(AppString.Menu.ExportRegistry)
         {
+            item.ContextMenuStrip.Opening += (sender, e) =>
+            {
+                using(var key = RegistryEx.GetRegistryKey(item.RegPath))
+                    this.Visible = key != null;
+            };
             this.Click += (sender, e) =>
             {
                 using(SaveFileDialog dlg = new SaveFileDialog())
@@ -34,7 +39,7 @@ namespace ContextMenuManager.Controls.Interfaces
                     {
                         RegistryEx.Export(item.RegPath, dlg.FileName);
                     }
-                    if(Directory.GetFiles(dirPath).Length == 0 && Directory.GetDirectories(dirPath).Length == 0)
+                    if(Directory.GetFileSystemEntries(dirPath).Length == 0)
                     {
                         Directory.Delete(dirPath);
                     }

+ 4 - 0
ContextMenuManager/Controls/Interfaces/ITsiShortcutCommandItem.cs

@@ -42,15 +42,19 @@ namespace ContextMenuManager.Controls.Interfaces
             public string Command { get; set; }
             public string Arguments { get; set; }
 
+            private static Size LastSize = new Size();
+
             public override void Reset() { }
 
             protected override bool RunDialog(IntPtr hwndOwner)
             {
                 using(CommandForm frm = new CommandForm())
                 {
+                    frm.Size = LastSize;
                     frm.Command = this.Command;
                     frm.Arguments = this.Arguments;
                     bool flag = frm.ShowDialog() == DialogResult.OK;
+                    LastSize = frm.Size;
                     if(flag)
                     {
                         this.Command = frm.Command;

+ 7 - 6
ContextMenuManager/Controls/Interfaces/ITsiTextItem.cs

@@ -1,5 +1,6 @@
 using BluePointLilac.Controls;
 using BluePointLilac.Methods;
+using System;
 using System.Windows.Forms;
 
 namespace ContextMenuManager.Controls.Interfaces
@@ -20,13 +21,13 @@ namespace ContextMenuManager.Controls.Interfaces
                 string name = ChangeText(item.Text);
                 if(name != null) item.ItemText = name;
             };
-            if(item is IFoldGroupItem == false)
+            MyListItem listItem = (MyListItem)item;
+            listItem.TextDoubleClick += (sender, e) =>
             {
-                ((MyListItem)item).TextDoubleClick += (sender, e) =>
-                {
-                    if(this.Enabled) this.OnClick(null);
-                };
-            }
+                if(listItem is IFoldGroupItem) return;
+                if(listItem.FindForm() is ShellStoreDialog.ShellStoreForm) return;
+                if(this.Enabled) this.OnClick(null);
+            };
         }
 
         private string ChangeText(string text)

+ 11 - 16
ContextMenuManager/Controls/NewShellDialog.cs

@@ -108,7 +108,7 @@ namespace ContextMenuManager.Controls
                 using(OpenFileDialog dlg = new OpenFileDialog())
                 {
                     dlg.DereferenceLinks = false;
-                    dlg.Filter = $"{AppString.Dialog.Program}|*.exe;*.bat;*.cmd;*.vbs;*.vbe;*.js;*.jse;*.wsf";
+                    dlg.Filter = $"{AppString.Dialog.Program}|*.exe|{AppString.Dialog.AllFiles}|*";
                     if(dlg.ShowDialog() != DialogResult.OK) return;
                     string filePath = dlg.FileName;
                     string arguments = "";
@@ -123,22 +123,17 @@ namespace ContextMenuManager.Controls
                             extension = Path.GetExtension(filePath);
                         }
                     }
-                    switch(extension)
+                    string exePath = FileExtension.GetExecutablePath(extension);
+                    if(File.Exists(exePath))
                     {
-                        case ".vbs":
-                        case ".vbe":
-                        case ".js":
-                        case ".jse":
-                        case ".wsf":
-                            chkSE.Checked = true;
-                            ItemFilePath = "wscript.exe";
-                            Arguments = filePath;
-                            if(!arguments.IsNullOrWhiteSpace()) Arguments += " " + arguments;
-                            break;
-                        default:
-                            Arguments = arguments;
-                            ItemFilePath = filePath;
-                            break;
+                        ItemFilePath = exePath;
+                        Arguments = filePath;
+                        if(!arguments.IsNullOrWhiteSpace()) Arguments += " " + arguments;
+                    }
+                    else
+                    {
+                        ItemFilePath = filePath;
+                        Arguments = arguments;
                     }
                     if(Array.FindIndex(DirScenePaths, path
                        => ScenePath.StartsWith(path, StringComparison.OrdinalIgnoreCase)) != -1)

+ 5 - 5
ContextMenuManager/Controls/SendToList.cs

@@ -8,15 +8,15 @@ namespace ContextMenuManager.Controls
 {
     sealed class SendToList : MyList
     {
-        public static readonly string SendToPath = Environment.ExpandEnvironmentVariables(@"%AppData%\Microsoft\Windows\SendTo");
+        private static readonly string SendToPath = Environment.ExpandEnvironmentVariables(@"%AppData%\Microsoft\Windows\SendTo");
 
         public void LoadItems()
         {
-            Array.ForEach(Directory.GetFiles(SendToPath), path =>
+            foreach(string path in Directory.GetFileSystemEntries(SendToPath))
             {
-                if(Path.GetFileName(path).ToLower() != "desktop.ini")
-                    this.AddItem(new SendToItem(path));
-            });
+                if(Path.GetFileName(path).ToLower() == "desktop.ini") continue;
+                this.AddItem(new SendToItem(path));
+            }
             this.SortItemByText();
             this.AddNewItem();
             this.AddDirItem();

+ 2 - 1
ContextMenuManager/Controls/ShellExItem.cs

@@ -66,6 +66,7 @@ namespace ContextMenuManager.Controls
         public Guid Guid { get; set; }
         public string ValueName => null;
         public string SearchText => Text;
+        public string ClsidPath => GuidInfo.GetClsidPath(Guid);
         public string ItemFilePath => GuidInfo.GetFilePath(Guid);
         private string KeyName => RegistryEx.GetKeyName(RegPath);
         private string ParentPath => RegistryEx.GetParentPath(RegPath);
@@ -131,7 +132,7 @@ namespace ContextMenuManager.Controls
             TsiRegLocation = new RegLocationMenuItem(this);
             TsiRegExport = new RegExportMenuItem(this);
             TsiDeleteMe = new DeleteMeMenuItem(this);
-            TsiHandleGuid = new HandleGuidMenuItem(this, true);
+            TsiHandleGuid = new HandleGuidMenuItem(this);
 
             ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiHandleGuid, new ToolStripSeparator(),
                 TsiDetails, new ToolStripSeparator(), TsiDeleteMe });

+ 10 - 82
ContextMenuManager/Controls/ShellItem.cs

@@ -18,76 +18,6 @@ namespace ContextMenuManager.Controls
 
         private const string OpenInNewWindowPath = @"HKEY_CLASSES_ROOT\Folder\shell\opennewwindow";
 
-        /// <summary>系统原有Shell公共子菜单项名</summary>
-        public static readonly string[] SysStoreItemNames = { "Windows.aboutWindows", "Windows.AddColumns",
-                "Windows.AddDevice", "Windows.AddMediaServer", "Windows.AddNetworkLocation", "Windows.AddPrinter",
-                "Windows.AddRemovePrograms", "Windows.AddToFavorites", "Windows.Autoplay", "Windows.Backup",
-                "Windows.BitLocker", "Windows.BitLocker.Encrypt", "Windows.BitLocker.Manage",
-                "Windows.BitLocker.ResetPasswordPin", "Windows.burn", "Windows.Burn.Action", "Windows.change-passphrase",
-                "Windows.change-pin", "Windows.ChangeIndexedLocations", "Windows.ChooseColumns", "Windows.CleanUp",
-                "Windows.ClearAddressBarHistory", "Windows.ClearFrequentHistory", "Windows.clearRecentDocs",
-                "Windows.closewindow", "Windows.cmd", "Windows.cmdPromptAsAdministrator", "Windows.CompressedFile.extract",
-                "Windows.CompressedFile.ExtractTo", "Windows.CompressedFolder.extract", "Windows.CompressedItem.extract",
-                "Windows.Computer.Manage", "Windows.connectNetworkDrive", "Windows.copy", "Windows.copyaspath",
-                "Windows.CopyToBrowser", "Windows.CopyToMenu", "Windows.CscSync", "Windows.CscWorkOfflineOnline",
-                "Windows.cut", "Windows.Defragment", "Windows.delete", "Windows.Dialog.DisconnectNetworkDrive",
-                "Windows.DiscImage.burn", "Windows.DisconnectNetworkDrive", "Windows.DiskFormat",
-                "Windows.DriveFolder.DisconnectNetworkDrive", "Windows.edit", "Windows.Eject", "Windows.email",
-                "Windows.encrypt-bde", "Windows.encrypt-bde-elev", "Windows.Enqueue", "Windows.EraseDisc",
-                "Windows.EraseDisc.Action", "Windows.fax", "Windows.FinishBurn", "Windows.folderoptions",
-                "Windows.GroupByColumn", "Windows.help", "Windows.HideSelected", "Windows.HistoryVaultRestore",
-                "Windows.HomeGroupCPL", "Windows.HomeGroupJoin", "Windows.HomeGroupPassword", "Windows.HomeGroupSharing",
-                "Windows.HomeGroupTroubleshooter", "Windows.IconSize", "Windows.includeinlibrary", "Windows.invertselection",
-                "Windows.layout", "Windows.LibraryChangeIcon", "Windows.LibraryDefaultSaveLocation",
-                "Windows.LibraryIncludeInLibrary", "Windows.LibraryManageLibrary", "Windows.LibraryOptimizeLibraryFor",
-                "Windows.LibraryPublicSaveLocation", "Windows.LibraryRestoreDefaults", "Windows.LibrarySelChangeIcon",
-                "Windows.LibrarySelDefaultSaveLocation", "Windows.LibrarySelManageLibrary", "Windows.LibrarySelOptimizeLibraryFor",
-                "Windows.LibrarySelPublicSaveLocation", "Windows.LibrarySelRestoreDefaults", "Windows.LibrarySelShowInNavPane",
-                "Windows.LibraryShowInNavPane", "Windows.location.cmd", "Windows.location.cmdPromptAsAdministrator",
-                "Windows.location.opennewprocess", "Windows.location.opennewtab", "Windows.location.opennewwindow",
-                "Windows.location.Powershell", "Windows.location.PowershellAsAdmin", "Windows.manage-bde",
-                "Windows.manage-bde-elev", "Windows.MapNetworkDrive", "Windows.menubar", "Windows.ModernShare",
-                "Windows.mount", "Windows.MoveToBrowser", "Windows.MoveToMenu", "Windows.MultiVerb.cmd",
-                "Windows.MultiVerb.cmdPromptAsAdministrator", "Windows.MultiVerb.opennewprocess", "Windows.MultiVerb.opennewtab",
-                "Windows.MultiVerb.opennewwindow", "Windows.MultiVerb.Powershell", "Windows.MultiVerb.PowershellAsAdmin",
-                "Windows.navpane", "Windows.NavPaneExpandToCurrentFolder", "Windows.NavPaneShowAllFolders",
-                "Windows.NavPaneShowLibraries", "Windows.NetworkAndSharing", "Windows.NetworkViewDeviceWebpage",
-                "Windows.newfolder", "Windows.newitem", "Windows.open", "Windows.OpenContainingFolder.opencontaining",
-                "Windows.OpenControlPanel", "Windows.opennewprocess", "Windows.opennewtab", "Windows.opennewwindow",
-                "Windows.OpenPrinterServerProperty", "Windows.OpenPrintQueue", "Windows.OpenSearch.openfilelocation",
-                "Windows.OpenSearchViewSite", "Windows.OpenWith", "Windows.organize", "Windows.paste", "Windows.pastelink",
-                "Windows.PermanentDelete", "Windows.PinToHome", "Windows.pintostartscreen", "Windows.play", "Windows.playall",
-                "Windows.playmusic", "Windows.PowershellAsAdmin", "Windows.previewpane", "Windows.print", "Windows.properties",
-                "Windows.readingpane", "Windows.recycle", "Windows.RecycleBin.Empty", "Windows.RecycleBin.Location.properties",
-                "Windows.RecycleBin.properties", "Windows.RecycleBin.RestoreAll", "Windows.RecycleBin.RestoreItems",
-                "Windows.RecycleBin.Selection.properties", "Windows.redo", "Windows.remotedesktop", "Windows.RemoveMediaServer",
-                "Windows.removeproperties", "Windows.rename", "Windows.RibbonDelete", "Windows.RibbonPermissionsDialog",
-                "Windows.RibbonShare", "Windows.RibbonSync.MakeAvailableOffline", "Windows.RibbonSync.SyncThisFolder",
-                "Windows.RibbonSync.WorkOfflineOnline", "Windows.rotate270", "Windows.rotate90", "Windows.runas",
-                "Windows.runasuser", "Windows.SearchActiveDirectory", "Windows.SearchClearMru", "Windows.SearchCloseTab",
-                "Windows.SearchFilterDate", "Windows.SearchFilterKind", "Windows.SearchFilterMoreProperties",
-                "Windows.SearchFilterSize", "Windows.SearchMru", "Windows.SearchOpenLocation", "Windows.SearchOptionCompressed",
-                "Windows.SearchOptionContents", "Windows.SearchOptionDeep", "Windows.SearchOptionShallow",
-                "Windows.SearchOptionSystem", "Windows.SearchSave", "Windows.SearchSendTo", "Windows.SearchSendToComputer",
-                "Windows.selectall", "Windows.SelectionCheckboxes", "Windows.selectMode", "Windows.selectnone",
-                "Windows.separator", "Windows.setdesktopwallpaper", "Windows.Share", "Windows.SharePrivate",
-                "Windows.ShareSpecificUsers", "Windows.Shortcut.opencontaining", "Windows.ShowFileExtensions",
-                "Windows.ShowHiddenFiles", "Windows.SizeAllColumns", "Windows.slideshow", "Windows.SortAscending",
-                "Windows.SortByColumn", "Windows.SortDescending", "Windows.SortGroupsAscending", "Windows.SortGroupsDescending",
-                "Windows.StartScan", "Windows.statusbar", "Windows.Sync", "Windows.SystemProperties", "Windows.taskbarpin",
-                "Windows.ToggleRecycleConfirmations", "Windows.topviewrestoredefault", "Windows.Troubleshoot", "Windows.undo",
-                "Windows.UpdatePrinterDriver", "Windows.v2.Powershell", "Windows.View.OptionsGallery",
-                "Windows.ViewRemotePrinters", "Windows.zip", "Windows.Zip.Action",
-                
-                //Win8.1
-                "Windows.ManageDefaultPrinters", "Windows.NavPaneShowFavorites", "Windows.playto", "Windows.Powershell",
-                "Windows.ShareHomegroupFullAccess", "Windows.ShareHomegroupNoAccess", "Windows.ShareHomegroupReadAccess",
-                //Win8
-                "Windows.SearchOptionPartial",
-                //Win7
-                "Windows.librarypane"
-            };
-
         /// <summary>Shell类型菜单特殊注册表项名默认名称</summary>
         private static readonly Dictionary<string, string> DefaultNames
             = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) {
@@ -127,7 +57,6 @@ namespace ContextMenuManager.Controls
         public string KeyName => RegistryEx.GetKeyName(RegPath);
         protected virtual bool IsSubItem => false;
         private bool IsOpenItem => KeyName.ToLower() == "open";
-
         public string ItemFilePath => GuidInfo.GetFilePath(Guid) ?? ObjectPath.ExtractFilePath(ItemCommand);
         private bool HasIcon => !IconLocation.IsNullOrWhiteSpace() || HasLUAShield;
 
@@ -198,6 +127,7 @@ namespace ContextMenuManager.Controls
             {
                 if(value) Registry.SetValue(RegPath, "ShowAsDisabledIfHidden", "");
                 else RegistryEx.DeleteValue(RegPath, "ShowAsDisabledIfHidden");
+                if(value && !ItemVisible) ItemVisible = false;
             }
         }
 
@@ -387,13 +317,14 @@ namespace ContextMenuManager.Controls
                 if(IconLocation != null)
                 {
                     icon = ResourceIcon.GetIcon(IconLocation, out iconPath, out iconIndex);
-                    if(icon == null && Path.GetExtension(iconPath)?.ToLower() == ".exe")
-                        icon = ResourceIcon.GetIcon(iconPath = "imageres.dll", iconIndex = -15);//文件为不存在的或没有图标的exe文件,不含图标的默认exe图标
+                    if(icon == null && Path.GetExtension(iconPath)?.ToLower() == ".exe")//文件不存在,或为没有图标的exe文件
+                        icon = ResourceIcon.GetIcon(iconPath = "imageres.dll", iconIndex = -15);//不含图标的默认exe图标
                 }
                 else if(HasLUAShield)
                     icon = ResourceIcon.GetIcon(iconPath = "imageres.dll", iconIndex = -78);//管理员小盾牌图标
                 else icon = ResourceIcon.GetIcon(iconPath = ItemFilePath, iconIndex = 0);//文件第一个图标
-                if(icon == null) icon = ResourceIcon.GetIcon(iconPath = "imageres.dll", iconIndex = -2);//图标资源不存在,白纸图标
+                if(icon == null) icon = ResourceIcon.GetExtensionIcon(iconPath = ItemFilePath)//文件类型图标
+                        ?? ResourceIcon.GetIcon(iconPath = "imageres.dll", iconIndex = -2);//图标资源不存在,白纸图标
                 IconPath = iconPath;
                 IconIndex = iconIndex;
                 return icon;
@@ -441,6 +372,7 @@ namespace ContextMenuManager.Controls
         readonly ToolStripMenuItem TsiNeverDefault = new ToolStripMenuItem(AppString.Menu.NeverDefault);
         readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);
         readonly ToolStripMenuItem TsiShowAsDisabled = new ToolStripMenuItem(AppString.Menu.ShowAsDisabledIfHidden);
+        readonly ToolStripMenuItem TsiClsidLocation = new ToolStripMenuItem(AppString.Menu.ClsidLocation);
 
         private void InitializeComponents()
         {
@@ -467,7 +399,7 @@ namespace ContextMenuManager.Controls
                 TsiNoWorkDir, TsiNeverDefault, TsiShowAsDisabled });
 
             TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),
-                TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport});
+                TsiChangeCommand, TsiFileProperties, TsiFileLocation, TsiRegLocation, TsiRegExport, TsiClsidLocation});
 
             TsiDeleteIcon.Click += (sender, e) => DeleteIcon();
             TsiSetTop.Click += (sender, e) => this.ItemPosition = Positions.Top;
@@ -477,7 +409,8 @@ namespace ContextMenuManager.Controls
             TsiOnlyWithShift.Click += (sender, e) => this.OnlyWithShift = !TsiOnlyWithShift.Checked;
             TsiNoWorkDir.Click += (sender, e) => this.NoWorkingDirectory = !TsiNoWorkDir.Checked;
             TsiNeverDefault.Click += (sender, e) => this.NeverDefault = !TsiNeverDefault.Checked;
-            TsiShowAsDisabled.Click += (sender, e) => SetDisabled(!TsiShowAsDisabled.Checked);
+            TsiShowAsDisabled.Click += (sender, e) => this.ShowAsDisabledIfHidden = !TsiShowAsDisabled.Checked;
+            TsiClsidLocation.Click += (sender, e) => ExternalProgram.JumpRegEdit(GuidInfo.GetClsidPath(Guid));
             ContextMenuStrip.Opening += (sender, e) => RefreshMenuItem();
             BtnSubItems.MouseDown += (sender, e) => ShowSubItems();
             TsiShieldIcon.Click += (sender, e) => UseShieldIcon();
@@ -510,12 +443,6 @@ namespace ContextMenuManager.Controls
             }
         }
 
-        private void SetDisabled(bool flag)
-        {
-            this.ShowAsDisabledIfHidden = flag;
-            if(!ItemVisible && flag) ItemVisible = false;
-        }
-
         private void RefreshMenuItem()
         {
             TsiOnlyWithShift.Visible = !IsSubItem;
@@ -524,6 +451,7 @@ namespace ContextMenuManager.Controls
             TsiShowAsDisabled.Visible = WindowsOsVersion.IsAfterOrEqualWin10_1703;
             TsiShowAsDisabled.Checked = this.ShowAsDisabledIfHidden;
             TsiChangeCommand.Visible = !IsMultiItem && Guid.Equals(Guid.Empty);
+            TsiClsidLocation.Visible = GuidInfo.GetClsidPath(Guid) != null;
             if(!this.IsSubItem) TsiOnlyWithShift.Checked = this.OnlyWithShift;
 
             if(WindowsOsVersion.IsAfterVista)

+ 30 - 3
ContextMenuManager/Controls/ShellList.cs

@@ -381,7 +381,12 @@ namespace ContextMenuManager.Controls
 
         private void AddNewItem(string scenePath)
         {
+            string shellPath = GetShellPath(scenePath);
             NewItem newItem = new NewItem { Visible = scenePath != null };
+            PictureButton btnAddExisting = new PictureButton(AppImage.AddExisting);
+            MyToolTip.SetToolTip(btnAddExisting, AppString.Tip.AddFromPublic);
+            btnAddExisting.Visible = Scene != Scenes.DragDrop && !string.Equals(shellPath, ShellItem.CommandStorePath, StringComparison.OrdinalIgnoreCase);
+            newItem.AddCtr(btnAddExisting);
             this.AddItem(newItem);
             newItem.AddNewItem += (sender, e) =>
             {
@@ -401,6 +406,25 @@ namespace ContextMenuManager.Controls
                 if(isShell) this.AddNewShellItem(scenePath);
                 else this.AddNewShellExItem(scenePath);
             };
+            btnAddExisting.MouseDown += (sender, e) =>
+            {
+                using(ShellStoreDialog dlg = new ShellStoreDialog())
+                {
+                    dlg.IsReference = false;
+                    dlg.ShellPath = ShellItem.CommandStorePath;
+                    dlg.Filter = new Func<string, bool>(itemName => !(AppConfig.HideSysStoreItems
+                        && itemName.StartsWith("Windows.", StringComparison.OrdinalIgnoreCase)));
+                    if(dlg.ShowDialog() != DialogResult.OK) return;
+                    foreach(string keyName in dlg.SelectedKeyNames)
+                    {
+                        string srcPath = $@"{dlg.ShellPath}\{keyName}";
+                        string dstPath = ObjectPath.GetNewPathWithIndex($@"{shellPath}\{keyName}", ObjectPath.PathType.Registry);
+
+                        RegistryEx.CopyTo(srcPath, dstPath);
+                        this.AddItem(new ShellItem(dstPath));
+                    }
+                }
+            };
         }
 
         private void AddNewShellItem(string scenePath)
@@ -503,9 +527,12 @@ namespace ContextMenuManager.Controls
         {
             using(var shellKey = RegistryEx.GetRegistryKey(ShellItem.CommandStorePath))
             {
-                Array.ForEach(Array.FindAll(shellKey.GetSubKeyNames(), itemName =>
-                    !ShellItem.SysStoreItemNames.Contains(itemName, StringComparer.OrdinalIgnoreCase)), itemName =>
-                        this.AddItem(new StoreShellItem($@"{ShellItem.CommandStorePath}\{itemName}", true, false)));
+                bool flag = AppConfig.HideSysStoreItems;
+                foreach(string itemName in shellKey.GetSubKeyNames())
+                {
+                    if(flag && itemName.StartsWith("Windows.", StringComparison.OrdinalIgnoreCase)) continue;
+                    this.AddItem(new StoreShellItem($@"{ShellItem.CommandStorePath}\{itemName}", true, false));
+                }
             }
         }
 

+ 10 - 7
ContextMenuManager/Controls/ShellNewList.cs

@@ -144,8 +144,11 @@ namespace ContextMenuManager.Controls
                     string openMode = FileExtension.GetOpenMode(extension);
                     if(string.IsNullOrEmpty(openMode))
                     {
-                        MessageBoxEx.Show(AppString.Message.NoOpenModeExtension);
-                        ExternalProgram.ShowOpenWithDialog(extension);
+                        if(MessageBoxEx.Show(AppString.Message.NoOpenModeExtension,
+                            MessageBoxButtons.OKCancel) == DialogResult.OK)
+                        {
+                            ExternalProgram.ShowOpenWithDialog(extension);
+                        }
                         return;
                     }
                     foreach(Control ctr in this.Controls)
@@ -165,12 +168,12 @@ namespace ContextMenuManager.Controls
                     using(RegistryKey snKey = exKey.CreateSubKey("ShellNew", true))
                     {
                         string defaultOpenMode = exKey.GetValue("")?.ToString();
-                        if(string.IsNullOrEmpty(defaultOpenMode))
-                        {
-                            exKey.SetValue("", openMode);
-                        }
+                        if(string.IsNullOrEmpty(defaultOpenMode)) exKey.SetValue("", openMode);
+
+                        byte[] bytes = Updater.GetShellNewData(extension);
+                        if(bytes != null) snKey.SetValue("Data", bytes, RegistryValueKind.Binary);
+                        else snKey.SetValue("NullFile", "", RegistryValueKind.String);
 
-                        snKey.SetValue("NullFile", string.Empty);
                         ShellNewItem item = new ShellNewItem(this, snKey.Name);
                         this.AddItem(item);
                         item.Focus();

+ 25 - 20
ContextMenuManager/Controls/ShellStoreDialog.cs

@@ -3,22 +3,22 @@ using BluePointLilac.Methods;
 using System;
 using System.Collections.Generic;
 using System.Drawing;
-using System.Linq;
 using System.Windows.Forms;
 
 namespace ContextMenuManager.Controls
 {
     sealed class ShellStoreDialog : CommonDialog
     {
-        public List<string> SelectedKeyNames { get; private set; }
-        public List<string> IgnoredKeyNames { get; set; }
+        public string[] SelectedKeyNames { get; private set; }
+        public Func<string, bool> Filter { get; set; }
         public string ShellPath { get; set; }
+        public bool IsReference { get; set; }
 
         public override void Reset() { }
 
         protected override bool RunDialog(IntPtr hwndOwner)
         {
-            using(ShellStoreForm frm = new ShellStoreForm(this.ShellPath, this.IgnoredKeyNames))
+            using(ShellStoreForm frm = new ShellStoreForm(this.ShellPath, this.Filter, this.IsReference))
             {
                 bool flag = frm.ShowDialog() == DialogResult.OK;
                 if(flag) this.SelectedKeyNames = frm.SelectedKeyNames;
@@ -29,25 +29,26 @@ namespace ContextMenuManager.Controls
         public sealed class ShellStoreForm : Form
         {
             public string ShellPath { get; private set; }
-            public List<string> IgnoredKeyNames { get; private set; }
-            public List<string> SelectedKeyNames { get; private set; } = new List<string>();
-            private bool IsPublic => ShellPath.Equals(ShellItem.CommandStorePath, StringComparison.OrdinalIgnoreCase);
+            public Func<string, bool> Filter { get; private set; }
+            public string[] SelectedKeyNames { get; private set; }
 
-            public ShellStoreForm(string shellPath, List<string> ignoredKeyNames)
+            public ShellStoreForm(string shellPath, Func<string, bool> filter, bool isReference)
             {
                 this.ShellPath = shellPath;
-                this.IgnoredKeyNames = ignoredKeyNames;
+                this.Filter = filter;
                 this.AcceptButton = btnOk;
                 this.CancelButton = btnCancel;
                 this.Font = SystemFonts.MessageBoxFont;
+                this.SizeGripStyle = SizeGripStyle.Hide;
                 this.ShowIcon = this.ShowInTaskbar = false;
+                this.MinimizeBox = this.MaximizeBox = false;
                 this.StartPosition = FormStartPosition.CenterParent;
                 this.MinimumSize = this.Size = new Size(652, 425).DpiZoom();
-                this.Text = IsPublic ? AppString.Dialog.CheckReference : AppString.Dialog.CheckCopy;
+                this.Text = isReference ? AppString.Dialog.CheckReference : AppString.Dialog.CheckCopy;
                 btnOk.Click += (sender, e) => GetSelectedItems();
                 list.Owner = listBox;
                 InitializeComponents();
-                LoadItems();
+                LoadItems(isReference);
             }
 
             readonly MyList list = new MyList();
@@ -92,23 +93,25 @@ namespace ContextMenuManager.Controls
                 pnlBorder.Height = listBox.Height + 2;
             }
 
-            private void LoadItems()
+            private void LoadItems(bool isReference)
             {
                 using(var shellKey = RegistryEx.GetRegistryKey(ShellPath))
                 {
-                    Array.ForEach(Array.FindAll(shellKey.GetSubKeyNames(), itemName =>
-                        !IgnoredKeyNames.Contains(itemName, StringComparer.OrdinalIgnoreCase)), itemName =>
-                        {
-                            string regPath = $@"{ShellPath}\{itemName}";
-                            list.AddItem(new StoreShellItem(regPath, IsPublic));
-                        });
+                    foreach(string itemName in shellKey.GetSubKeyNames())
+                    {
+                        if(Filter != null && !Filter(itemName)) continue;
+                        string regPath = $@"{ShellPath}\{itemName}";
+                        list.AddItem(new StoreShellItem(regPath, isReference));
+                    }
                 }
             }
 
             private void GetSelectedItems()
             {
+                List<string> names = new List<string>();
                 foreach(StoreShellItem item in list.Controls)
-                    if(item.IsSelected) SelectedKeyNames.Add(item.KeyName);
+                    if(item.IsSelected) names.Add(item.KeyName);
+                SelectedKeyNames = names.ToArray();
             }
         }
     }
@@ -126,8 +129,10 @@ namespace ContextMenuManager.Controls
             }
             RegTrustedInstaller.TakeRegTreeOwnerShip(regPath);
         }
-        public bool IsSelected => chkSelected.Checked;
+
         public bool IsPublic { get; set; }
+        public bool IsSelected => chkSelected.Checked;
+
         readonly CheckBox chkSelected = new CheckBox { AutoSize = true };
 
         public override void DeleteMe()

+ 19 - 23
ContextMenuManager/Controls/ShellSubMenuDialog.cs

@@ -5,7 +5,6 @@ using System;
 using System.Collections.Generic;
 using System.Drawing;
 using System.IO;
-using System.Linq;
 using System.Reflection;
 using System.Windows.Forms;
 using static Microsoft.Win32.Registry;
@@ -199,12 +198,10 @@ namespace ContextMenuManager.Controls
                 private void AddNewItem()
                 {
                     if(!SubShellTypeItem.CanAddMore(this)) return;
-                    using(NewShellDialog dlg = new NewShellDialog
-                    {
-                        ScenePath = this.ScenePath,
-                        ShellPath = ShellItem.CommandStorePath
-                    })
+                    using(NewShellDialog dlg = new NewShellDialog())
                     {
+                        dlg.ScenePath = this.ScenePath;
+                        dlg.ShellPath = ShellItem.CommandStorePath;
                         if(dlg.ShowDialog() != DialogResult.OK) return;
                         SubKeyNames.Add(dlg.NewItemKeyName);
                         SaveSorting();
@@ -215,20 +212,20 @@ namespace ContextMenuManager.Controls
                 private void AddReference()
                 {
                     if(!SubShellTypeItem.CanAddMore(this)) return;
-                    using(ShellStoreDialog dlg = new ShellStoreDialog
-                    {
-                        ShellPath = ShellItem.CommandStorePath,
-                        IgnoredKeyNames = ShellItem.SysStoreItemNames.ToList()
-                    })
+                    using(ShellStoreDialog dlg = new ShellStoreDialog())
                     {
+                        dlg.IsReference = true;
+                        dlg.ShellPath = ShellItem.CommandStorePath;
+                        dlg.Filter = new Func<string, bool>(itemName => !(AppConfig.HideSysStoreItems 
+                            && itemName.StartsWith("Windows.", StringComparison.OrdinalIgnoreCase)));
                         if(dlg.ShowDialog() != DialogResult.OK) return;
-                        dlg.SelectedKeyNames.ForEach(keyName =>
+                        foreach(string keyName in dlg.SelectedKeyNames)
                         {
                             if(!SubShellTypeItem.CanAddMore(this)) return;
                             this.AddItem(new SubShellItem(this, keyName));
                             this.SubKeyNames.Add(keyName);
                             SaveSorting();
-                        });
+                        }
                     }
                 }
 
@@ -386,7 +383,7 @@ namespace ContextMenuManager.Controls
                     {
                         if(shellKey == null) return;
                         RegTrustedInstaller.TakeRegTreeOwnerShip(shellKey.Name);
-                        Array.ForEach(shellKey.GetSubKeyNames(), keyName =>
+                        foreach(string keyName in shellKey.GetSubKeyNames())
                         {
                             string regPath = $@"{ShellPath}\{keyName}";
                             int value = Convert.ToInt32(GetValue(regPath, "CommandFlags", 0));
@@ -398,7 +395,7 @@ namespace ContextMenuManager.Controls
                             {
                                 this.AddItem(new SubShellItem(this, regPath));
                             }
-                        });
+                        }
                     }
                 }
 
@@ -418,7 +415,7 @@ namespace ContextMenuManager.Controls
 
                 private void AddSeparator()
                 {
-                    string regPath = null;
+                    string regPath;
                     if(this.Controls.Count > 1)
                     {
                         regPath = GetItemRegPath((MyListItem)Controls[Controls.Count - 1]);
@@ -435,14 +432,13 @@ namespace ContextMenuManager.Controls
                 private void AddFromParentMenu()
                 {
                     if(!SubShellTypeItem.CanAddMore(this)) return;
-                    using(ShellStoreDialog dlg = new ShellStoreDialog
-                    {
-                        ShellPath = this.ParentShellPath,
-                        IgnoredKeyNames = new List<string> { this.ParentKeyName }
-                    })
+                    using(ShellStoreDialog dlg = new ShellStoreDialog())
                     {
+                        dlg.IsReference = false;
+                        dlg.ShellPath = this.ParentShellPath;
+                        dlg.Filter = new Func<string, bool>(itemName => !itemName.Equals(this.ParentKeyName, StringComparison.OrdinalIgnoreCase));
                         if(dlg.ShowDialog() != DialogResult.OK) return;
-                        dlg.SelectedKeyNames.ForEach(keyName =>
+                        foreach(string keyName in dlg.SelectedKeyNames)
                         {
                             if(!SubShellTypeItem.CanAddMore(this)) return;
                             string srcPath = $@"{dlg.ShellPath}\{keyName}";
@@ -450,7 +446,7 @@ namespace ContextMenuManager.Controls
 
                             RegistryEx.CopyTo(srcPath, dstPath);
                             this.AddItem(new SubShellItem(this, dstPath));
-                        });
+                        }
                     }
                 }
 

+ 1 - 1
ContextMenuManager/Controls/UwpModeItem.cs

@@ -132,7 +132,7 @@ namespace ContextMenuManager.Controls
             TsiRegLocation = new RegLocationMenuItem(this);
             TsiDeleteMe = new DeleteMeMenuItem(this);
             TsiRegExport = new RegExportMenuItem(this);
-            TsiHandleGuid = new HandleGuidMenuItem(this, false);
+            TsiHandleGuid = new HandleGuidMenuItem(this);
             this.ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiHandleGuid,
                 new ToolStripSeparator(), TsiDetails, new ToolStripSeparator(), TsiDeleteMe });
             TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),

+ 6 - 8
ContextMenuManager/Controls/WinXGroupItem.cs

@@ -74,16 +74,14 @@ namespace ContextMenuManager.Controls
         {
             if(MessageBoxEx.Show(AppString.Message.RestoreDefault, MessageBoxButtons.OKCancel) == DialogResult.OK)
             {
+                File.SetAttributes(TargetPath, FileAttributes.Normal);
+                Directory.Delete(TargetPath, true);
+                Directory.CreateDirectory(TargetPath);
                 File.SetAttributes(TargetPath, File.GetAttributes(DefaultGroupPath));
-                string[] paths = Directory.GetFiles(TargetPath);
-                foreach(string path in paths)
+                foreach(string srcPath in Directory.GetFiles(DefaultGroupPath))
                 {
-                    File.Delete(path);
-                }
-                paths = Directory.GetFiles(DefaultGroupPath);
-                foreach(string path in paths)
-                {
-                    File.Copy(path, $@"{TargetPath}\{Path.GetFileName(path)}");
+                    string dstPath = $@"{TargetPath}\{Path.GetFileName(srcPath)}";
+                    File.Copy(srcPath, dstPath);
                 }
                 WinXList list = (WinXList)this.Parent;
                 list.ClearItems();

+ 24 - 20
ContextMenuManager/Controls/WinXList.cs

@@ -76,34 +76,38 @@ namespace ContextMenuManager.Controls
                         dlg2.Title = AppString.Dialog.SelectGroup;
                         dlg2.Items = GetGroupNames();
                         if(dlg2.ShowDialog() != DialogResult.OK) return;
-                        string dirPath = $@"{WinXPath}\{dlg2.Selected}";
-                        string extension = Path.GetExtension(dlg1.ItemFilePath).ToLower();
-                        string fileName = Path.GetFileNameWithoutExtension(dlg1.ItemFilePath);
+                        string dirName = dlg2.Selected;
+                        string dirPath = $@"{WinXPath}\{dirName}";
+                        string itemText = dlg1.ItemText;
+                        string targetPath = dlg1.ItemFilePath;
+                        string arguments = dlg1.Arguments;
+                        string workDir = Path.GetDirectoryName(targetPath);
+                        string extension = Path.GetExtension(targetPath).ToLower();
+                        string fileName = Path.GetFileNameWithoutExtension(targetPath);
                         int count = Directory.GetFiles(dirPath, "*.lnk").Length;
                         string index = (count + 1).ToString().PadLeft(2, '0');
                         string lnkName = $"{index} - {fileName}.lnk";
                         string lnkPath = $@"{dirPath}\{lnkName}";
-                        ShellLink shellLink;
-                        if(extension == ".lnk")
+                        using(ShellLink shellLink = new ShellLink(lnkPath))
                         {
-                            File.Copy(dlg1.ItemFilePath, lnkPath);
-                            shellLink = new ShellLink(lnkPath);
-                        }
-                        else
-                        {
-                            shellLink = new ShellLink(lnkPath)
+                            if(extension == ".lnk")
                             {
-                                TargetPath = dlg1.ItemFilePath,
-                                Arguments = dlg1.Arguments,
-                            };
-                            shellLink.WorkingDirectory = Path.GetDirectoryName(shellLink.TargetPath);
+                                File.Copy(targetPath, lnkPath);
+                                shellLink.Load();
+                            }
+                            else
+                            {
+                                shellLink.TargetPath = targetPath;
+                                shellLink.Arguments = arguments;
+                                shellLink.WorkingDirectory = workDir;
+                            }
+                            shellLink.Description = itemText;
+                            shellLink.Save();
                         }
-                        shellLink.Description = dlg1.ItemText;
-                        shellLink.Save();
-                        DesktopIni.SetLocalizedFileNames(lnkPath, dlg1.ItemText);
+                        DesktopIni.SetLocalizedFileNames(lnkPath, itemText);
                         foreach(MyListItem ctr in this.Controls)
                         {
-                            if(ctr is WinXGroupItem groupItem && groupItem.Text == dlg2.Selected)
+                            if(ctr is WinXGroupItem groupItem && groupItem.Text == dirName)
                             {
                                 WinXItem item = new WinXItem(lnkPath, groupItem) { Visible = !groupItem.IsFold };
                                 item.BtnMoveDown.Visible = item.BtnMoveUp.Visible = AppConfig.WinXSortable;
@@ -133,7 +137,7 @@ namespace ContextMenuManager.Controls
         {
             List<string> items = new List<string>();
             DirectoryInfo winxDi = new DirectoryInfo(WinXPath);
-            Array.ForEach(winxDi.GetDirectories(), di => items.Add(di.Name));
+            foreach(DirectoryInfo di in winxDi.GetDirectories()) items.Add(di.Name);
             items.Reverse();
             return items.ToArray();
         }

+ 25 - 5
ContextMenuManager/GuidInfo.cs

@@ -30,9 +30,10 @@ namespace ContextMenuManager
         private static readonly IniReader AppDic = new IniReader(new StringBuilder(Properties.Resources.GuidInfosDic));
         public static readonly Dictionary<Guid, IconLocation> IconLocationDic = new Dictionary<Guid, IconLocation>();
         private static readonly Dictionary<Guid, string> FilePathDic = new Dictionary<Guid, string>();
+        private static readonly Dictionary<Guid, string> ClsidPathDic = new Dictionary<Guid, string>();
         public static readonly Dictionary<Guid, string> ItemTextDic = new Dictionary<Guid, string>();
-        public static readonly Dictionary<Guid, Image> ItemImageDic = new Dictionary<Guid, Image>();
         public static readonly Dictionary<Guid, string> UwpNameDic = new Dictionary<Guid, string>();
+        public static readonly Dictionary<Guid, Image> ItemImageDic = new Dictionary<Guid, Image>();
 
         private static bool TryGetValue(Guid guid, string key, out string value)
         {
@@ -83,7 +84,12 @@ namespace ContextMenuManager
                                     }
                                 }
                             }
-                            if(File.Exists(filePath)) break;
+                            if(File.Exists(filePath))
+                            {
+                                if(ClsidPathDic.ContainsKey(guid)) ClsidPathDic[guid] = guidKey.Name;
+                                else ClsidPathDic.Add(guid, guidKey.Name);
+                                break;
+                            }
                         }
                     }
                 }
@@ -92,6 +98,19 @@ namespace ContextMenuManager
             return filePath;
         }
 
+        public static string GetClsidPath(Guid guid)
+        {
+            if(ClsidPathDic.ContainsKey(guid)) return ClsidPathDic[guid];
+            foreach(string path in ClsidPaths)
+            {
+                using(RegistryKey key = RegistryEx.GetRegistryKey($@"{path}\{guid:B}"))
+                {
+                    if(key != null) return key.Name;
+                }
+            }
+            return null;
+        }
+
         public static string GetText(Guid guid)
         {
             string itemText = null;
@@ -200,11 +219,12 @@ namespace ContextMenuManager
             string absStr = relStr;
             if(isName)
             {
-                if(!relStr.StartsWith("@")) return absStr;
-                else absStr = relStr.Substring(1);
+                if(!absStr.StartsWith("@")) return absStr;
+                else absStr = absStr.Substring(1);
             }
+
             string filePath = GetFilePath(guid);
-            if(filePath == null) return absStr;
+            if(filePath == null) return relStr;
             string dirPath = Path.GetDirectoryName(filePath);
             if(absStr.StartsWith("*"))
             {

+ 14 - 12
ContextMenuManager/MainForm.cs

@@ -14,13 +14,15 @@ namespace ContextMenuManager
     {
         public MainForm()
         {
-            this.SetSideBarWidth();
+            SideBar.Width = GetSideBarWidth();
             this.Text = AppString.General.AppName;
             this.ForeColor = Color.FromArgb(80, 80, 80);
             this.Controls.Add(new ExplorerRestarter());
-            appSettingBox.Owner = shellList.Owner = shellNewList.Owner = sendToList.Owner = openWithList.Owner
-                = winXList.Owner = guidBlockedList.Owner = enhanceMenusList.Owner = thirdRuleList.Owner = iEList.Owner = MainBody;
-            donateBox.Parent = aboutMeBox.Parent = dictionariesBox.Parent = languagesBox.Parent = MainBody;
+            donateBox.Parent = aboutMeBox.Parent = dictionariesBox.Parent 
+                = languagesBox.Parent = appSettingBox.Owner = shellList.Owner 
+                = shellNewList.Owner = sendToList.Owner = openWithList.Owner 
+                = winXList.Owner = guidBlockedList.Owner = enhanceMenusList.Owner 
+                = thirdRuleList.Owner = iEList.Owner = MainBody;
             ToolBar.SelectedButtonChanged += (sender, e) => SwitchTab(ToolBar.SelectedIndex);
             SideBar.HoverIndexChanged += (sender, e) => ShowItemInfo();
             SideBar.SelectIndexChanged += (sender, e) => SwitchItem();
@@ -29,7 +31,7 @@ namespace ContextMenuManager
             ToolBar.SelectedIndex = 0;
             if(AppConfig.ShowFilePath) ShowFilePath();
             var droper = new ElevatedFileDroper(this);
-            this.DragDrop += (sender, e) =>
+            droper.DragDrop += (sender, e) =>
             {
                 ShellList.CurrentFileObjectPath = droper.DropFilePaths[0];
                 SwitchTab(1, 9);
@@ -37,11 +39,11 @@ namespace ContextMenuManager
         }
 
         readonly MyToolBarButton[] ToolBarButtons = new MyToolBarButton[] {
-            new MyToolBarButton(AppImage.Home, AppString.ToolBar.Home),//主页
-            new MyToolBarButton(AppImage.Type, AppString.ToolBar.Type),//文件类型
-            new MyToolBarButton(AppImage.Star, AppString.ToolBar.Rule),//其他规则
-            new MyToolBarButton(AppImage.Refresh,AppString.ToolBar.Refresh){ CanBeSelected = false },//刷新
-            new MyToolBarButton(AppImage.About, AppString.ToolBar.About)//关于
+            new MyToolBarButton(AppImage.Home, AppString.ToolBar.Home),
+            new MyToolBarButton(AppImage.Type, AppString.ToolBar.Type),
+            new MyToolBarButton(AppImage.Star, AppString.ToolBar.Rule),
+            new MyToolBarButton(AppImage.Refresh,AppString.ToolBar.Refresh){ CanBeSelected = false },
+            new MyToolBarButton(AppImage.About, AppString.ToolBar.About)
         };
         readonly ShellList shellList = new ShellList();
         readonly ShellNewList shellNewList = new ShellNewList();
@@ -352,12 +354,12 @@ namespace ContextMenuManager
             }
         }
 
-        private void SetSideBarWidth()
+        public int GetSideBarWidth()
         {
             int maxWidth = 0;
             string[] strs = GeneralItems.Concat(TypeItems).Concat(OtherRuleItems).Concat(AboutItems).ToArray();
             Array.ForEach(strs, str => maxWidth = Math.Max(maxWidth, SideBar.GetItemWidth(str)));
-            SideBar.Width = maxWidth;
+            return maxWidth;
         }
     }
 }

+ 2 - 2
ContextMenuManager/Program.cs

@@ -15,10 +15,10 @@ namespace ContextMenuManager
         [STAThread]
         static void Main()
         {
-            if(SingleInstance.IsRunning()) return;
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
-            new Action(Updater.PeriodicUpdate).BeginInvoke(null, null);
+            if(SingleInstance.IsRunning()) return;
+            Updater.PeriodicUpdate();
             Application.Run(new MainForm());
         }
     }

+ 2 - 2
ContextMenuManager/Properties/AssemblyInfo.cs

@@ -11,5 +11,5 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyCulture("")]
 [assembly: ComVisible(false)]
 [assembly: Guid("35190ec1-2515-488d-a2e9-825d6ff67aa2")]
-[assembly: AssemblyVersion("3.3.1.0")]
-[assembly: AssemblyFileVersion("3.3.1.0")]
+[assembly: AssemblyVersion("3.3.2.0")]
+[assembly: AssemblyFileVersion("3.3.2.0")]

+ 3 - 3
ContextMenuManager/Properties/Resources.resx

@@ -112,12 +112,12 @@
     <value>2.0</value>
   </resheader>
   <resheader name="reader">
-    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
   <resheader name="writer">
-    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
   </resheader>
-  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <data name="About" type="System.Resources.ResXFileRef, System.Windows.Forms">
     <value>resources\images\about.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
   </data>

BIN
ContextMenuManager/Properties/Resources/Images/AddExisting.png


BIN
ContextMenuManager/Properties/Resources/Images/AddSeparator.png


BIN
ContextMenuManager/Properties/Resources/Images/Donate.png


+ 6 - 0
ContextMenuManager/Properties/Resources/ShellNew/0.c

@@ -0,0 +1,6 @@
+#include <stdio.h>
+ 
+int main()
+{
+    return 0;
+}

+ 9 - 0
ContextMenuManager/Properties/Resources/ShellNew/0.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title></title>
+  </head>
+  <body>
+  </body>
+</html>

BIN
ContextMenuManager/Properties/Resources/ShellNew/0.rar


BIN
ContextMenuManager/Properties/Resources/ShellNew/0.reg


+ 1 - 0
ContextMenuManager/Properties/Resources/ShellNew/0.rtf

@@ -0,0 +1 @@
+{\rtf1}

BIN
ContextMenuManager/Properties/Resources/ShellNew/0.xlsx


+ 1 - 0
ContextMenuManager/Properties/Resources/ShellNew/0.xml

@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?>

BIN
ContextMenuManager/Properties/Resources/ShellNew/0.zip


+ 30 - 26
ContextMenuManager/Properties/Resources/Texts/AppLanguageDic.ini

@@ -116,9 +116,10 @@ RegistryLocation = 注册表位置
 ExportRegistry = 导出注册表
 Delete = 删除此项
 DeleteReference = 删除引用
-HandleGuid = 处理guid
-CopyGuid = 复制guid
-BlockGuid = 锁定guid
+HandleGuid = 处理GUID
+CopyGuid = 复制GUID
+BlockGuid = 锁定GUID
+ClsidLocation = CLSID路径
 AddGuidDic = 添加字典
 InitialData = 编辑文件初始数据
 BeforeSeparator = 显示在分割线上方
@@ -132,6 +133,7 @@ Ok = 确认
 Cancel = 取消
 Browse = 浏览
 Program = 程序
+AllFiles = 所有文件
 RegistryFile = 注册表文件
 ItemText = 菜单文本
 ItemCommand = 菜单命令
@@ -174,30 +176,30 @@ TranslateTool = 翻译工具
 DefaultText = 默认文本
 OldTranslation = 旧译文
 NewTranslation = 新译文
-SelectSubMenuMode = 该多级菜单子项目数为0, 你有两个选择:\r\n①该多级菜单的所有子菜单项目私有(推荐),\r\n②该多级菜单可与其他多级菜单引用相同子项,\r\n请做出你的选择......
-DonateInfo = 此名单不定期更新, 上次更新:%date \r\n\r\n累计金额:%money 元, 累计人次:%count 人次
+SelectSubMenuMode = 该多级菜单子项目数为0,你有两个选择:\r\n①该多级菜单的所有子菜单项目私有(推荐),\r\n②该多级菜单可与其他多级菜单引用相同子项,\r\n请做出你的选择......
+DonateInfo = 此名单不定期更新,上次更新:%date \r\n\r\n累计金额:%money 元,累计人次:%count 人次
 
 [Message]
 TextCannotBeEmpty = 菜单文本不能为空!
 CommandCannotBeEmpty = 菜单命令不能为空!
 StringParsingFailed = 本地化字符串解析失败!
-TextLengthCannotExceed80 = 菜单文本过长, 长度不允许超过80!
-ConfirmDeletePermanently = 确认是否永久删除此项?\r\n此操作无法还原,请谨慎操作!
-DeleteButCanRestore = 确认删除此菜单的注册表项目?\r\n由于启用了自动备份(默认启用),\r\n删除后可在备份文件夹中还原。
+TextLengthCannotExceed80 = 菜单文本过长长度不允许超过80!
+ConfirmDeletePermanently = 确认是否永久删除此项?\r\n此操作无法还原请谨慎操作!
+DeleteButCanRestore = 确认删除此菜单的注册表项目?\r\n由于启用了自动备份(默认启用)\r\n删除后可在备份文件夹中还原。
 ConfirmDeleteReference = 确认是否移除对该项目的引用?
 ConfirmDelete = 确认是否删除该项?
-ConfirmDeleteReferenced = 确认是否删除此项?\r\n所有引用此项的项目都会失效,请谨慎操作!
-CannotAddNewItem = 系统限制子菜单数目最多为16,\r\n无法添加更多的子菜单项目!
+ConfirmDeleteReferenced = 确认是否删除此项?\r\n所有引用此项的项目都会失效请谨慎操作!
+CannotAddNewItem = 系统限制子菜单数目最多为16\r\n无法添加更多的子菜单项目!
 VistaUnsupportedMulti = Vista系统不支持多级菜单!
 CannotHideSubItem = 你的系统版本太低,不支持隐藏子级菜单!
-UnsupportedFilename = 不支持的文件名,\r\n可能已经存在相同文件名的菜单项目!
-NoOpenModeExtension = 此扩展名没有关联默认打开方式,\r\n请先为此类型文件关联打开方式!
+UnsupportedFilename = 不支持的文件名\r\n可能已经存在相同文件名的菜单项目!
+NoOpenModeExtension = 此扩展名没有关联默认打开方式\r\n请先为此类型文件关联打开方式!
 CannotChangePath = 不允许更改文件路径!
 CopiedToClipboard = 已复制到剪切板:
 MalformedGuid = 格式不正确的Guid
 HasBeenAdded = 此项目已被添加!
-EditInitialData = 此程序现仅支持编辑纯文本文件的初始数据,\r\n其他类型文件请自行编辑注册表"Data"键值,\r\n请确认是否继续你的操作?
-PromptIsOpenItem = 该项为文件或文件夹的"打开"菜单,\n盲目操作可能会导致无法打开文件或文件夹,\n请确认是否继续你的操作?(不建议)
+EditInitialData = 此程序现仅支持编辑纯文本文件的初始数据,\r\n其他类型文件请自行编辑注册表"Data"键值,\r\n请确认是否继续你的操作?
+PromptIsOpenItem = 该项为文件或文件夹的"打开"菜单,\n盲目操作可能会导致无法打开文件或文件夹,\n请确认是否继续你的操作?(不建议)
 SelectRegPath = 操作步骤:\r\n① 打开注册表编辑器(自动)\r\n② 导航到目标注册表路径\r\n③ 关闭注册表编辑器窗口\n请确认是否继续?
 RestartApp = 程序将会重新启动!
 FileNotExists = 文件不存在!
@@ -205,26 +207,27 @@ FolderNotExists = 文件夹不存在!
 UpdateInfo = 【检测更新】\r\n当前版本:%v1\r\n最新版本:%v2\r\n是否立即下载更新?
 UpdateSucceeded = 程序更新成功!
 VersionIsLatest = 当前版本为最新版!
-AuthorityProtection = 此菜单注册表项目可能受安全软件保护,\r\n无法对其进行禁用删除和其他个性化修改。
+AuthorityProtection = 此菜单注册表项目可能受安全软件保护\r\n无法对其进行禁用删除和其他个性化修改。
 WinXSorted = 为优化排序功能已对部分项目重新编号,\r\n需要重启文件资源管理器应用效果
 RestoreDefault = 确认还原为默认菜单项目?
 DeleteGroup = 确认永久删除此组及组内所有菜单项目?
-NetworkDtaReadFailed = 网络数据读取失败!
+WebDataReadFailed = 网络数据读取失败!
 
 [Tip]
-RestartExplorer = 重启Explorer会使桌面闪烁片刻, 正常现象无需担心,\r\n或者你也可以稍后重启或注销计算机使你的操作生效
+RestartExplorer = 重启Explorer会使桌面闪烁片刻,正常现象无需担心,\r\n或者你也可以稍后重启或注销计算机使你的操作生效
 CustomFolder = 禁用此项将会同时禁用文件系统\r\n对象属性面板中的自定义选项卡
-SendToDrive = 仅当插入可移动磁盘时有作用,\r\n显示该可移动磁盘的所有分区
+SendToDrive = 仅当插入可移动磁盘时有作用\r\n显示该可移动磁盘的所有分区
 BuildSendtoMenu = 禁用此项将加快主菜单弹出速度\r\n但会延缓发送到子菜单弹出速度
 InvalidItem = 无效菜单项目将导致此项以下的\r\n所有菜单项目不可见(建议删除)
 EditSubItems = 编辑子菜单项目
 AddReference = 从公共引用项目中添加引用
+AddFromPublic = 从公共引用中复制菜单项目
 AddFromParentMenu = 从母菜单中复制项目
 AddSeparator = 添加分隔线
 DeleteGuidDic = 删除用户自行添加的该项的本地Guid字典
 LockNewMenu = 启用后可阻止第三方程序增加项目\r\n且可对现有项目排序(关闭后复原)
 DropOrSelectObject = 请拖拽或通过按钮选择文件或目录
-ConfigPath = 更改配置和数据文件保存路径后,\r\n会导致部分已启用增强菜单失效,\r\n可在增强菜单中重新启用一遍
+ConfigPath = 更改配置和数据文件保存路径后,\r\n会导致部分已启用增强菜单失效,\r\n可在增强菜单中重新启用一遍
 CommandFiles = 此命令依赖配置文件,移动配置文件位置\r\n会导致此菜单项失效,重新启用一遍即可
 CreateGroup = 新建一个分组
 
@@ -246,7 +249,7 @@ BuildSendtoMenu = 快速构建发送到子菜单
 UseStoreOpenWith = 在Microsoft Store中查找应用
 NewItem = 新建一个菜单项目
 AddGuidBlockedItem = 添加GUID锁定项目
-LockNewMenu = 锁定新建菜单
+LockNewMenu = 锁定新建菜单并启用排序功能
 InvalidItem = 无效菜单项目:
 Separator = >>>>>> 分割线 <<<<<<
 SelectRegPath = 请选择注册表项
@@ -262,7 +265,7 @@ RestartExplorer = 当前部分操作需要重启文件资源管理器生效
 UserDictionaries = 用户字典
 DictionaryDescription = 字典说明
 GuidInfosDictionary = GUID信息
-UWPMode = UWP模块
+UwpMode = UWP模块
 Translators = 翻译贡献者
 DonationList = 捐赠名单
 ConfigPath = 配置和数据文件保存位置
@@ -275,17 +278,18 @@ OnceAMonth = 每月一次
 OnceASeason = 每季一次
 NeverCheck = 从不检查
 ImmediatelyCheck = 立即检查
-SetRequestRepo = 设置程序访问的存储库站点
-ProtectOpenItem = 保护 "打开" 菜单项目
+SetRequestRepo = 设置网络数据访问存储库站点
+ProtectOpenItem = 保护名称为 "打开" 菜单项目
 WebSearchEngine = 设置网页搜索使用的搜索引擎
 CustomEngine = 自定义
 SetCustomEngine = 设置搜索引擎 (以 %s 代替搜索关键词)
 HideDisabledItems = 不显示已禁用的菜单项目
+HideSysStoreItems = 隐藏公共引用中的系统菜单
 SetPerceivedType = 设置扩展名为 %s 的文件感知类型为
 SetDefaultDropEffect = 设置文件对象默认拖拽命令为
 
-AboutApp = 【主要功能】\r\n 1.管理常见位置右键菜单\r\n 2.自定义添加右键菜单\r\n\r\n【兼容性能】\r\n 1.适用于Win7、8、8.1、10、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    但是按照程序使用的通用规则在此程序中仍会显示为启用,这是正常的现象。\r\n 2.每个右键管理程序禁用菜单方法可能不同, 建议不要同时使用多个右键菜单管理程序,\r\n    大部分程序使用简单暴力的备份-删除法, 此程序尽可能使用了系统提供的键值进行隐藏操作,\r\n    若之前使用过其他程序禁用菜单项,请先使用对应程序还原, 不然可能无法在此程序中看到它。\r\n 3.此程序不用于清理未卸载干净的程序,但可帮助你定位菜单项相关注册表和文件位置,\r\n    你可根据相关内容进行你的操作,如果你是一个电脑小白,建议只碰启用\禁用开关。
+AboutApp = 【兼容性能】\r\n 1.适用于Win7、8、8.1、10、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    你可根据相关内容进行你的操作,如果你是一个电脑小白,建议只碰启用\禁用开关。
 
-Dictionaries = 【字典说明】\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.第三方程序菜单内部设置字典 (ThirdRulesDic.xml)\r\n 4.增强菜单项目字典 (EnhanceMenusDic.xml)\r\n 5.UWP新模块字典 (UWPModeItemsDic.xml)
+Dictionaries = 【字典说明】\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.第三方程序菜单内部设置字典 (ThirdRulesDic.xml)\r\n 4.增强菜单项目字典 (EnhanceMenusDic.xml)\r\n 5.UWP新模块字典 (UWPModeItemsDic.xml)
 
-Donate = 此程序完全免费,如果你觉得这个软件对你有所帮助, 你可以通过扫描\r\n下方二维码(微信、支付宝、腾讯QQ)进行捐赠, 金额请随意, 谢谢支持!\r\n也期待你在Github或者Gitee上为此程序项目点亮Star (这对我很重要!)
+Donate = 此程序完全免费,如果你觉得这个软件对你有所帮助,你可以通过扫描\r\n下方二维码(微信、支付宝、腾讯QQ)进行捐赠,金额请随意,谢谢支持!\r\n也期待你在Github或者Gitee上为此程序项目点亮Star (这对我很重要!)

+ 80 - 75
ContextMenuManager/Properties/Resources/Texts/EnhanceMenusDic.xml

@@ -3,6 +3,7 @@
 Tip属性为鼠标悬浮在开关上时的提示信息,从每个Item节点开始, 子元素Value表示该项的注册表键值,目前仅支持REG_SZ、REG_DWORD、REG_EXPAND_SZ、REG_BINARY的键值类型,
 子元素SubKey的所有子元素是该项的子项,项名即为元素名; 每一Item项和SubKey的所有子元素的属性Default为该注册表项默认值,不放在Value\REG_SZ元素里面是为了防止与可能存在的键名为Default的键产生冲突
 由于Shell项太过复杂,程序只根据注册表项名判断存在即启用,故同一场景下不允许有相同KeyName属性的Shell项目,ShellEx项只要Guid符合则为启用-->
+
 <Data>
   <File>
     <Shell>
@@ -32,7 +33,11 @@ Tip属性为鼠标悬浮在开关上时的提示信息,从每个Item节点开
           <REG_SZ MUIVerb='获取哈希值'/>
         </Value>
         <SubKey>
-          <Command Default='powershell -noexit get-filehash -literalpath "%1" -algorithm SHA1 | format-list;get-filehash -literalpath "%1" -algorithm SHA256 | format-list;get-filehash -literalpath "%1" -algorithm SHA384 | format-list;get-filehash -literalpath "%1" -algorithm SHA512 | format-list;get-filehash -literalpath "%1" -algorithm MACTripleDES | format-list;get-filehash -literalpath "%1" -algorithm MD5 | format-list;get-filehash -literalpath "%1" -algorithm RIPEMD160 | format-list'/>
+          <Command>
+            <ShellExecute Verb='open' WindowStyle='3'/>
+            <FileName>powershell.exe</FileName>
+            <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>
+          </Command>
         </SubKey>
       </Item>
     </Shell>
@@ -418,76 +423,6 @@ Tip属性为鼠标悬浮在开关上时的提示信息,从每个Item节点开
           </Shell>
         </SubKey>
       </Item>
-      <Item KeyName='VirtualMode' Tip='解决 Hyper-V 和 VirtualBox 不能共存的问题'>
-        <OSVersion Compare=">=">10.0</OSVersion>
-        <Value>
-          <REG_SZ MUIVerb='虚拟模式' Icon='imageres.dll,-109' SubCommands='' Position='bottom'/>
-        </Value>
-        <SubKey>
-          <Shell>
-            <SubKey>
-              <Item0>
-                <Value>
-                  <REG_SZ MUIVerb='Hyper-V'/>
-                </Value>
-                <SubKey>
-                  <Command>
-                    <FileName>wscript.exe</FileName>
-                    <Arguments>
-                      <CreateFile
-                        FileName='HyperVMode.vbs'
-                        Content='
-                        Dim sap, wsh
-                        Set sap = CreateObject("Shell.Application")
-                        sap.ShellExecute "bcdedit", "/set hypervisorlaunchtype auto", "" ,"runas", 0
-                        msg = "你当前切换的模式为 Hyper-V," &amp; VbCrlf
-                        msg = msg &amp; "该模式可使用 Windows SandBox 和 Hyper-V," &amp; VbCrlf
-                        msg = msg &amp; "不可使用 VirtualBox 和 VMware 等虚拟机程序," &amp; VbCrlf
-                        msg = msg &amp; "是否立即重启计算机应用该模式?" &amp; VbCrlf
-                        msg = msg &amp; "你也可稍后自行重启,请保存好工作!"
-                        If Msgbox(msg, VbYesNo + VbInformation, "虚拟模式") = VbYes Then
-                            Set wsh = CreateObject("WScript.Shell")
-                            wsh.Run("shutdown -r -f -t 00")
-                            Set wsh = Nothing
-                        End If
-                        Set sap = Nothing'/>
-                    </Arguments>
-                  </Command>
-                </SubKey>
-              </Item0>
-              <Item1>
-                <Value>
-                  <REG_SZ MUIVerb='VirtualBox'/>
-                </Value>
-                <SubKey>
-                  <Command>
-                    <FileName>wscript.exe</FileName>
-                    <Arguments>
-                      <CreateFile
-                        FileName='VirtualBoxMode.vbs'
-                        Content='
-                        Dim sap, wsh
-                        Set sap = CreateObject("Shell.Application")
-                        sap.ShellExecute "bcdedit", "/set hypervisorlaunchtype off", "", "runas", 0
-                        msg = "你当前切换的模式为 VirtualBox," &amp; VbCrlf
-                        msg = msg &amp; "该模式可使用 VirtualBox 和 VMware 等虚拟机程序," &amp; VbCrlf
-                        msg = msg &amp; "不可使用 Windows SandBox 和 Hyper-V," &amp; VbCrlf
-                        msg = msg &amp; "是否立即重启计算机应用该模式?" &amp; VbCrlf
-                        msg = msg &amp; "你也可稍后自行重启,请保存好工作!"
-                        If Msgbox(msg, VbYesNo + VbInformation, "虚拟模式") = VbYes Then
-                            Set wsh = CreateObject("WScript.Shell")
-                            wsh.Run("shutdown -r -f -t 00")
-                            Set wsh = Nothing
-                        End If
-                        Set sap = Nothing'/>
-                    </Arguments>
-                  </Command>
-                </SubKey>
-              </Item1>
-            </SubKey>
-          </Shell>
-        </SubKey>
-      </Item>
       <Item KeyName='WallPaperLocation'>
         <Value>
           <REG_SZ MUIVerb='壁纸位置' Icon='imageres.dll,-5346' Position='bottom'/>
@@ -774,6 +709,76 @@ Tip属性为鼠标悬浮在开关上时的提示信息,从每个Item节点开
           <Command Default='explorer shell:::{ED7BA470-8E54-465E-825C-99712043E01C}'/>
         </SubKey>
       </Item>
+      <Item KeyName='VirtualMode' Tip='解决 Hyper-V 和 VirtualBox 不能共存的问题'>
+        <OSVersion Compare=">=">10.0</OSVersion>
+        <Value>
+          <REG_SZ MUIVerb='虚拟模式' Icon='imageres.dll,-109' SubCommands='' Position='bottom'/>
+        </Value>
+        <SubKey>
+          <Shell>
+            <SubKey>
+              <Item0>
+                <Value>
+                  <REG_SZ MUIVerb='Hyper-V'/>
+                </Value>
+                <SubKey>
+                  <Command>
+                    <FileName>wscript.exe</FileName>
+                    <Arguments>
+                      <CreateFile
+                        FileName='HyperVMode.vbs'
+                        Content='
+                        Dim sap, wsh
+                        Set sap = CreateObject("Shell.Application")
+                        sap.ShellExecute "bcdedit", "/set hypervisorlaunchtype auto", "" ,"runas", 0
+                        msg = "你当前切换的模式为 Hyper-V," &amp; VbCrlf
+                        msg = msg &amp; "该模式可使用 Windows SandBox 和 Hyper-V," &amp; VbCrlf
+                        msg = msg &amp; "不可使用 VirtualBox 和 VMware 等虚拟机程序," &amp; VbCrlf
+                        msg = msg &amp; "是否立即重启计算机应用该模式?" &amp; VbCrlf
+                        msg = msg &amp; "你也可稍后自行重启,请保存好工作!"
+                        If Msgbox(msg, VbYesNo + VbInformation, "虚拟模式") = VbYes Then
+                            Set wsh = CreateObject("WScript.Shell")
+                            wsh.Run("shutdown -r -f -t 00")
+                            Set wsh = Nothing
+                        End If
+                        Set sap = Nothing'/>
+                    </Arguments>
+                  </Command>
+                </SubKey>
+              </Item0>
+              <Item1>
+                <Value>
+                  <REG_SZ MUIVerb='VirtualBox'/>
+                </Value>
+                <SubKey>
+                  <Command>
+                    <FileName>wscript.exe</FileName>
+                    <Arguments>
+                      <CreateFile
+                        FileName='VirtualBoxMode.vbs'
+                        Content='
+                        Dim sap, wsh
+                        Set sap = CreateObject("Shell.Application")
+                        sap.ShellExecute "bcdedit", "/set hypervisorlaunchtype off", "", "runas", 0
+                        msg = "你当前切换的模式为 VirtualBox," &amp; VbCrlf
+                        msg = msg &amp; "该模式可使用 VirtualBox 和 VMware 等虚拟机程序," &amp; VbCrlf
+                        msg = msg &amp; "不可使用 Windows SandBox 和 Hyper-V," &amp; VbCrlf
+                        msg = msg &amp; "是否立即重启计算机应用该模式?" &amp; VbCrlf
+                        msg = msg &amp; "你也可稍后自行重启,请保存好工作!"
+                        If Msgbox(msg, VbYesNo + VbInformation, "虚拟模式") = VbYes Then
+                            Set wsh = CreateObject("WScript.Shell")
+                            wsh.Run("shutdown -r -f -t 00")
+                            Set wsh = Nothing
+                        End If
+                        Set sap = Nothing'/>
+                    </Arguments>
+                  </Command>
+                </SubKey>
+              </Item1>
+            </SubKey>
+          </Shell>
+        </SubKey>
+      </Item>
       <Item KeyName='EditHosts'>
         <Value>
           <REG_SZ MUIVerb='编辑 Hosts'/>
@@ -782,7 +787,7 @@ Tip属性为鼠标悬浮在开关上时的提示信息,从每个Item节点开
           <Command>
             <ShellExecute Verb='runas'/>
             <FileName>notepad.exe</FileName>
-            <Arguments>"%systemroot%\system32\drivers\etc\hosts"</Arguments>
+            <Arguments>%systemroot%\system32\drivers\etc\hosts</Arguments>
           </Command>
         </SubKey>
       </Item>
@@ -870,10 +875,10 @@ Tip属性为鼠标悬浮在开关上时的提示信息,从每个Item节点开
                 Content='
                 @echo off
                 taskkill /f /im explorer.exe
-                del /a "%LocalAppData%\IconCache.db"
+                del /f /s /q /a "%LocalAppData%\IconCache.db"
                 cd /d "%LocalAppData%\Microsoft\Windows\Explorer"
-                for /r %%f in (iconcache_*.db) do del %%f
-                for /r %%f in (thumbcache_*.db) do del %%f
+                del /f /s /q /a thumbcache_*.db
+                del /f /s /q /a iconcache_*.db
                 reg delete "HKCR\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v IconStreams /f
                 reg delete "HKCR\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify" /v PastIconsStream /f
                 start explorer'/>

+ 77 - 62
ContextMenuManager/Properties/Resources/Texts/GuidInfosDic.ini

@@ -34,69 +34,83 @@
 ;中其他文件中;相对<GUID文件路径>,当前目录用".\"代替,父目录用"..\"代替,文件为其本身用"*"代替
 
 ;----------------系统------------------
-;打开(快捷方式)
 [00021401-0000-0000-c000-000000000046]
 Text = 打开(&O)
 en-US-Text = &Open
 Icon = shell32.dll,-16769
 [37ea3a21-7493-4208-a011-7f9ea79ce9f5]
-ResText = @*,-1033
+ResText = @shell32.dll,-1033
 Text = 打开文件所在的位置(&I)
 Icon = explorer.exe
-[1d27f844-3a1f-4410-85ac-14651078412d]
-ResText = @*,-2022
-Text = 兼容性疑难解答(&Y)
-Icon = msdt.exe
-[7ad84985-87b4-4a16-be58-8b72a5b390f7]
-ResText = @playtomenu.dll,-101
-Text = 播放到设备
-[ffe2a43c-56b9-4bf5-9a79-cc6d4285608a]
-Text = 向左、向右旋转
 [ff609cc7-d34d-4049-a1aa-2293517ffcc6]
 ResText = @stobject.dll,-417
 Text = 设置为桌面背景(&B)
 Icon = imageres.dll,-5346
-[90aa3a4e-1cba-4233-b8bb-535773d48449]
-ResText = @*,-5386
-Text = 固定到任务栏(&K)
-Icon = imageres.dll,-5354
-[09799afb-ad67-11d1-abcd-00c04fc30936]
-ResText = @*,-5376
-Text = 打开方式(&H)
-Icon = imageres.dll,-5340
-[f3d06e7c-1e45-4a26-847e-f9fcdee59be0]
-ResText = @*,-30328
-Text = 复制为路径(&A)
-Icon = imageres.dll,-5302
-[3dad6c5d-2167-4cae-9914-f99e41c12cfa]
-Text = 包含到库中(&I)
-Icon = imageres.dll,-1001
+[0bf754aa-c967-445c-ab3d-d8fda9bae7ef]
+ResText = @stobject.dll,-416
+Text = 下一个桌面背景(&N)
+Icon = imageres.dll,-5346
+[3080f90e-d7ad-11d9-bd98-0000947b0257]
+ResText = @shell32.dll,-12715
+Text = 窗口转换程序
+Icon = imageres.dll
 [470c0ebd-5d73-4d58-9ced-e91e22e23282]
 ResText = @shell32.dll,-51201
 Text = 固定到"开始"屏幕(&P)
 Icon = imageres.dll,-5376
 [a2a9545d-a0c2-42b4-9708-a0b2badd77c8]
+ResText = @shell32.dll,-30608
 Text = 附到「开始」菜单(&U)
 Icon = imageres.dll,-80
+[90aa3a4e-1cba-4233-b8bb-535773d48449]
+ResText = @shell32.dll,-5386
+Text = 固定到任务栏(&K)
+Icon = imageres.dll,-5354
 [7ba4c740-9e81-11cf-99d3-00aa004ae837]
-ResText = @*,-30312
+ResText = @shell32.dll,-30312
 Text = 发送到(&N)
 Icon = imageres.dll,-185
-[0bf754aa-c967-445c-ab3d-d8fda9bae7ef]
-ResText = @*,-416
-Text = 下一个桌面背景(&N)
-Icon = imageres.dll,-5346
+[f3d06e7c-1e45-4a26-847e-f9fcdee59be0]
+ResText = @shell32.dll,-30328
+Text = 复制为路径(&A)
+Icon = imageres.dll,-5302
+[c2fbb630-2971-11d1-a18c-00c04fd75d13]
+ResText = @shell32.dll,-30304
+Text = 复制到文件夹(&F)...
+Icon = imageres.dll,-5304
+[c2fbb631-2971-11d1-a18c-00c04fd75d13]
+ResText = @shell32.dll,-30305
+Text = 移动到文件夹(&V)...
+Icon = imageres.dll,-5303
+[b8cdcb65-b1bf-4b42-9428-1dfdb7ee92af]
+ResText = @shell32.dll,-37514
+Text = 全部解压缩(&T)...
+[09799afb-ad67-11d1-abcd-00c04fc30936]
+ResText = @shell32.dll,-5376
+Text = 打开方式(&H)
+Icon = imageres.dll,-5340
+[3dad6c5d-2167-4cae-9914-f99e41c12cfa]
+Text = 包含到库中(&I)
+Icon = imageres.dll,-1001
 [d969a300-e7ff-11d0-a93b-00a0c90f2719]
-ResText = @*,-95851
+ResText = @shell32.dll,-95851
 Text = 新建(&W)
 Icon = imageres.dll,-5307
-[6b9228da-9c15-419e-856c-19e768a13bdc]
-Text = Windows 小工具
 [a470f8cf-a1e8-4f65-8335-227475aa5c46]
 Text = 加密(&Y)
 Icon = imageres.dll,-59
+[1d27f844-3a1f-4410-85ac-14651078412d]
+ResText = @acppage.dll,-2022
+Text = 兼容性疑难解答(&Y)
+Icon = msdt.exe
+[7ad84985-87b4-4a16-be58-8b72a5b390f7]
+ResText = @playtomenu.dll,-101
+Text = 播放到设备
+[ffe2a43c-56b9-4bf5-9a79-cc6d4285608a]
+ResText = @*,-3050
+Text = 向右旋转(&T)​​
 [e2bf9676-5f8f-435c-97eb-11607a5bedf7]
-ResText = @*,-107
+ResText = @ntshrui.dll,-107
 Text = 共享
 Icon = ntshrui.dll,-123
 [e61bf828-5e63-4287-bef1-60b1a4fde0e3]
@@ -104,54 +118,46 @@ ResText = @WorkfoldersControl.dll,-1
 Text = 工作文件夹
 Icon = WorkFolders.exe
 [f81e9010-6ea4-11ce-a7ff-00aa003ca9f6]
-ResText = @*,-103
+ResText = @ntshrui.dll,-103
 Text = 授予访问权限(&G)
 [474c98ee-cf3d-41f5-80e3-4aab0ab04301]
-ResText = @*,-38
+ResText = @cscui.dll,-38
 Text = 始终脱机可用(&F)
 [2854f705-3548-414c-a113-93e27c808c85]
-ResText = @*,-101
+ResText = @EhStorShell.dll,-101
 Text = 增强的存储设备
 [fbeb8a05-beee-4442-804e-409d6c4515e9]
-ResText = @*,-12560
+ResText = @shell32.dll,-12560
 Text = 刻录到光盘(&T)
 Icon = imageres.dll,-30
 [59099400-57ff-11ce-bd94-0020af85b590]
 Text = 复制磁盘(&Y)...
 [d6791a63-e7e2-4fee-bf52-5ded8e86e9b8]
-ResText = @*,-511
+ResText = @wpdshext.dll,-511
 Text = 便携设备菜单
 [0af96ede-aebf-41ed-a1c8-cf7a685505b6]
-Text = 不在导航窗格中显示
+ResText = @shell32.dll,-34618
+Text = 在导航窗格中显示
 Icon = imageres.dll,-5359
 [596ab062-b4d2-4215-9f74-e9109b0a8153]
-ResText = @*,-1037
+ResText = @twext.dll,-1037
 Text = 还原以前的版本(&V)
+[6b9228da-9c15-419e-856c-19e768a13bdc]
+Text = Windows 小工具
 [85bbd920-42a0-1069-a2e4-08002b30309d]
 ResText = @shell32.dll,-22978
 Text = 公文包
 [645ff040-5081-101b-9f08-00aa002f954e]
 Text = 清空回收站(&B)
 Icon = shell32.dll,-254
-[b8cdcb65-b1bf-4b42-9428-1dfdb7ee92af]
-ResText = @shell32.dll,-37514
-Text = 全部解压缩(&T)...
 [bd472f60-27fa-11cf-b8b4-444553540000]
 Text = 提取(&E)...
-[c2fbb630-2971-11d1-a18c-00c04fd75d13]
-ResText = @*,-30304
-Text = 复制到文件夹(&F)...
-Icon = imageres.dll,-5304
-[c2fbb631-2971-11d1-a18c-00c04fd75d13]
-ResText = @*,-30305
-Text = 移动到文件夹(&V)...
-Icon = imageres.dll,-5303
-[3080f90e-d7ad-11d9-bd98-0000947b0257]
-ResText = @shell32.dll,-12715
-Text = 窗口转换程序
-Icon = imageres.dll
 [5635493f-7d77-4372-a839-8ad89f5b3726]
 Text = 卸载(&U)
+[e598560b-28d5-46aa-a14a-8a3bea34b576]
+Text = 幻灯片放映
+[8a734961-c4aa-4741-ac1e-791acebf5b39]
+Text = 联机购买音乐
 
 ;----------------显卡------------------
 [a929c4ce-fd36-4270-b4f5-34ecac5bd63c]
@@ -254,6 +260,8 @@ Text = UltraISO
 Icon = .\UltraISO.exe
 [be86f80b-eb1a-45b4-b4b6-4b12d302b6bc]
 Text = AntZip
+[9d731a0b-89e4-44e2-a6a4-3b05c80d562c]
+Text = i-Zip
 
 ;----------------杀软------------------
 [09a47860-11b0-4da5-afa5-26d86198a780]
@@ -452,16 +460,12 @@ Text = 迅捷PDF转换器
 Icon = .\pdfconverter.exe
 
 ;--------------影音图像----------------
-[8a734961-c4aa-4741-ac1e-791acebf5b39]
-Text = 联机购买音乐
 [f1b9284f-e9dc-4e68-9d7e-42362a59f0fd]
 Text = 添加到“Windows Media Player”列表(&W)
 [ce3fb1d1-02ae-4a5f-a6e9-d9f1b4073e6c]
 Text = 使用“Windows Media Player”播放(&P)
 [7d4734e6-047e-41e2-aeaa-e763b4739dc4]
 Text = 使用 Media Player 播放(&P)
-[e598560b-28d5-46aa-a14a-8a3bea34b576]
-Text = 幻灯片放映
 [9b6d38f3-8ef4-48a5-ad30-ffffffffffff]
 Text = Honeyview
 Icon = .\Honeyview.exe
@@ -496,6 +500,15 @@ Icon = ..\..\Program\APlayer.exe
 [4d2fba8d-621b-4447-af6d-5794f479c4a5]
 Text = 爱奇艺看图
 Icon = ..\QyImg.exe
+[4a34b3e3-f50e-4ff6-8979-7e4176466ff2]
+Text = SageThumbs
+[d149b06b-bc31-4425-b5bb-0e04308982ae]
+Text = 用百图秀打开
+[5add1a3c-29e2-4d18-b79a-c56e1df5486c]
+Text = 百图秀
+[1bb8f8e1-6492-4ec9-ac40-9ad0f5c01fa2]
+Text = 鲨鱼看图
+Icon = .\SharkElevate.exe
 
 ;----------------美化------------------
 [cf444751-60fc-48b8-ac0f-363063eb2a9e]
@@ -528,7 +541,7 @@ Icon = .\QMStart.exe
 Text = 开启布丁桌面
 Icon = .\PDLanuncher.exe
 [b5e436bc-642a-4bf6-b725-26038af26e89]
-Text = 开启猎豹轻桌面
+Text = 开启桌面整理(元气、猎豹轻桌面)
 Icon = .\kdesk.exe
 [5f8d079b-8ce6-4f58-bf10-55c1b68d88f3]
 Text = 选择颜色设置
@@ -636,6 +649,8 @@ Icon = .\microexcel.exe
 [0d8b46ea-7d35-4921-b88c-7e2b1e2d80f0]
 Text = WPS Office
 Icon = ..\..\wpsoffice.exe
+[53506455-e799-443f-addb-891ca6efc928]
+Text = 扫描游戏到快吧游戏
 
 ;-------------UWP新模块----------------
 [776dbc8d-7347-478c-8d71-791e12ef49d8]

+ 1 - 0
ContextMenuManager/Properties/Resources/Texts/ThirdRulesDic.xml

@@ -5,6 +5,7 @@ Item的子元素Rule为相关注册表内容,RegPath省略则默认为Group主
 ValueName为相关键名,On为启用键值,Off为禁用键值;不设置On或Off属性时,其值为null,对应注册表键值不存在;
 每个Item可能受多个注册表Rule影响,按照顺序进行键值判定;判定规则:当有多条规则时,前面的规则注册表键值匹配On则为On,匹配Off则为Off,并终止判断,都不匹配时继续往下判断,若所有规则都不匹配则为On
 ValueKind为键值类型,默认键值类型ValueKind为REG_DWORD,为默认值时可省略,目前仅支持REG_SZ、REG_DWORD、REG_EXPAND_SZ、REG_BINARY的键值类型-->
+
 <Data>
   <Group Text='System'>
     <Item Text='系统 右键菜单' RestartExplorer=''>

+ 90 - 34
ContextMenuManager/Updater.cs

@@ -2,7 +2,6 @@
 using BluePointLilac.Methods;
 using ContextMenuManager.Controls;
 using System;
-using System.Collections.Generic;
 using System.Globalization;
 using System.IO;
 using System.Linq;
@@ -18,6 +17,9 @@ namespace ContextMenuManager
         const string GithubLatest = "https://github.com/BluePointLilac/ContextMenuManager/releases/latest";
         const string GithubLatestApi = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/releases/latest";
         const string GithubLangsApi = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/contents/languages";
+        const string GithubLangsRawDir = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/languages";
+        const string GithubShellNewApi = "https://api.github.com/repos/BluePointLilac/ContextMenuManager/contents/ContextMenuManager/Properties/Resources/ShellNew";
+        const string GithubShellNewRawDir = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/ContextMenuManager/Properties/Resources/ShellNew";
         const string GithubTexts = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/ContextMenuManager/Properties/Resources/Texts";
         const string GithubDonateRaw = "https://raw.githubusercontent.com/BluePointLilac/ContextMenuManager/master/Donate.md";
         const string GithubDonate = "https://github.com/BluePointLilac/ContextMenuManager/blob/master/Donate.md";
@@ -25,6 +27,9 @@ namespace ContextMenuManager
         const string GiteeReleases = "https://gitee.com/BluePointLilac/ContextMenuManager/releases";
         const string GiteeLatestApi = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/releases/latest";
         const string GiteeLangsApi = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/contents/languages";
+        const string GiteeLangsRawDir = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/languages";
+        const string GiteeShellNewApi = "https://gitee.com/api/v5/repos/BluePointLilac/ContextMenuManager/contents/ContextMenuManager/Properties/Resources/ShellNew";
+        const string GiteeShellNewRawDir = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/ContextMenuManager/Properties/Resources/ShellNew";
         const string GiteeTexts = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/ContextMenuManager/Properties/Resources/Texts";
         const string GiteeDonateRaw = "https://gitee.com/BluePointLilac/ContextMenuManager/raw/master/Donate.md";
         const string GiteeDonate = "https://gitee.com/BluePointLilac/ContextMenuManager/blob/master/Donate.md";
@@ -35,7 +40,9 @@ namespace ContextMenuManager
             int day = AppConfig.UpdateFrequency;
             if(day == -1) return;//自动检测更新频率为-1则从不自动检查更新
             //如果上次检测更新时间加上时间间隔早于或等于今天以前就进行更新操作
-            if(AppConfig.LastCheckUpdateTime.AddDays(day) <= DateTime.Today) Update(false);
+            DateTime time = AppConfig.LastCheckUpdateTime.AddDays(day);
+            //time = DateTime.Today;//测试用
+            if(time <= DateTime.Today) new Action<bool>(Update).BeginInvoke(false, null, null);
         }
 
         /// <summary>更新程序以及程序字典</summary>
@@ -57,7 +64,7 @@ namespace ContextMenuManager
             {
                 if(isManual)
                 {
-                    MessageBoxEx.Show(AppString.Message.NetworkDtaReadFailed);
+                    MessageBoxEx.Show(AppString.Message.WebDataReadFailed);
                     url = AppConfig.RequestUseGithub ? GithubLatest : GiteeReleases;
                     ExternalProgram.OpenUrl(url);
                 }
@@ -76,7 +83,7 @@ namespace ContextMenuManager
             {
                 XmlElement bodyXE = (XmlElement)root.SelectSingleNode("body");
                 string info = AppString.Message.UpdateInfo.Replace("%v1", appVer.ToString()).Replace("%v2", webVer.ToString());
-                info += "\r\n\r\n" + MachinedInfo(bodyXE.InnerText);
+                info += Environment.NewLine + Environment.NewLine + MachinedInfo(bodyXE.InnerText);
                 if(MessageBoxEx.Show(info, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                 {
                     string netVer = Environment.Version > new Version(4, 0) ? "4.0" : "3.5";
@@ -107,57 +114,78 @@ namespace ContextMenuManager
         /// <param name="isManual">是否为手动点击更新</param>
         private static void UpdateText(bool isManual)
         {
-            bool flag = isManual;
-            string url = AppConfig.RequestUseGithub ? GithubTexts : GiteeTexts;
-            string[] fileNames = new[]
+            string error = null;
+            var func = new Func<string, string, bool>(WebStringToFile);
+            string dirUrl = AppConfig.RequestUseGithub ? GithubTexts : GiteeTexts;
+            string[] filePaths = new[]
             {
-                AppConfig.GUIDINFOSDICINI, AppConfig.ENHANCEMENUSICXML,
-                AppConfig.THIRDRULESDICXML, AppConfig.UWPMODEITEMSDICXML
+                AppConfig.WebGuidInfosDic, AppConfig.WebEnhanceMenusDic,
+                AppConfig.WebThirdRulesDic, AppConfig.WebUwpModeItemsDic
             };
-            foreach(string fileName in fileNames)
-            {
-                string fileUrl = $"{url}/{fileName}";
-                string filePath = $@"{AppConfig.WebDicsDir}\{fileName}";
-                string contents = GetWebString(fileUrl);
-                if(string.IsNullOrEmpty(contents)) { flag = false; continue; }
-                contents = contents.Replace("\n", Environment.NewLine);
-                File.WriteAllText(filePath, contents, Encoding.Unicode);
+            foreach(string filePath in filePaths)
+            {
+                bool flag = func.EndInvoke(func.BeginInvoke(filePath, dirUrl, null, null));
+                if(!flag) error += Path.GetFileName(filePath) + ", ";
+            }
+            dirUrl = AppConfig.RequestUseGithub ? GithubLangsRawDir : GiteeLangsRawDir;
+            filePaths = Directory.GetFiles(AppConfig.LangsDir, "*.ini");
+            foreach(string filePath in filePaths)
+            {
+                bool flag = func.EndInvoke(func.BeginInvoke(filePath, dirUrl, null, null));
+                if(!flag) error += Path.GetFileName(filePath) + ", ";
+            }
+            if(isManual && error != null)
+            {
+                error = error.Substring(0, error.LastIndexOf(", "));
+                MessageBoxEx.Show(error + " : " + AppString.Message.WebDataReadFailed);
             }
-            if(!flag) MessageBoxEx.Show(AppString.Message.NetworkDtaReadFailed);
+        }
+
+        /// <summary>将网络文本写入本地文件</summary>
+        /// <param name="filePath">本地文件路径</param>
+        /// <param name="dirUrl">网络文件Raw链接的目录</param>
+        private static bool WebStringToFile(string filePath, string dirUrl)
+        {
+            string fileName = Path.GetFileName(filePath);
+            string fileUrl = $"{dirUrl}/{fileName}";
+            string contents = GetWebString(fileUrl);
+            bool flag = contents != null;
+            if(flag) File.WriteAllText(filePath, contents, Encoding.Unicode);
+            return flag;
         }
 
         /// <summary>显示语言下载对话框</summary>
         /// <returns>返回值为是否下载了语言文件</returns>
         public static bool ShowLanguageDialog()
         {
-            string url = AppConfig.RequestUseGithub ? GithubLangsApi : GiteeLangsApi;
-            XmlDocument doc = GetWebJsonToXml(url);
+            string apiUrl = AppConfig.RequestUseGithub ? GithubLangsApi : GiteeLangsApi;
+            XmlDocument doc = GetWebJsonToXml(apiUrl);
             if(doc == null)
             {
-                MessageBoxEx.Show(AppString.Message.NetworkDtaReadFailed);
+                MessageBoxEx.Show(AppString.Message.WebDataReadFailed);
                 return false;
             }
-            Dictionary<string, string> langs = new Dictionary<string, string>();
-            foreach(XmlElement itemXE in doc.FirstChild.SelectNodes("item"))
+            XmlNodeList list = doc.FirstChild.ChildNodes;
+            string[] langs = new string[list.Count];
+            for(int i = 0; i < list.Count; i++)
             {
-                XmlElement nameXE = (XmlElement)itemXE.SelectSingleNode("name");
-                XmlElement urlXE = (XmlElement)itemXE.SelectSingleNode("download_url");
-                string lang = Path.GetFileNameWithoutExtension(nameXE.InnerText);
-                langs.Add(lang, urlXE.InnerText);
+                XmlNode nameXN = list.Item(i).SelectSingleNode("name");
+                langs[i] = Path.GetFileNameWithoutExtension(nameXN.InnerText);
             }
             using(SelectDialog dlg = new SelectDialog())
             {
-                dlg.Items = langs.Keys.ToArray();
+                dlg.Items = langs;
                 dlg.Title = AppString.Dialog.DownloadLanguages;
                 string lang = CultureInfo.CurrentUICulture.Name;
                 if(dlg.Items.Contains(lang)) dlg.Selected = lang;
                 else dlg.SelectedIndex = 0;
                 if(dlg.ShowDialog() == DialogResult.OK)
                 {
-                    lang = dlg.Selected;
-                    string contents = GetWebString(langs[lang]);
-                    string filePath = $@"{AppConfig.LangsDir}\{lang}.ini";
-                    File.WriteAllText(filePath, contents, Encoding.Unicode);
+                    string fileName = $"{dlg.Selected}.ini";
+                    string filePath = $@"{AppConfig.LangsDir}\{fileName}";
+                    string dirUrl = AppConfig.RequestUseGithub ? GithubLangsRawDir : GiteeLangsRawDir;
+                    bool flag = WebStringToFile(filePath, dirUrl);
+                    if(!flag) MessageBoxEx.Show(fileName + ": " + AppString.Message.WebDataReadFailed);
                     return true;
                 }
             }
@@ -172,7 +200,7 @@ namespace ContextMenuManager
             //contents = File.ReadAllText(@"..\..\..\Donate.md");//用于求和更新Donate.md文件
             if(contents == null)
             {
-                MessageBoxEx.Show(AppString.Message.NetworkDtaReadFailed);
+                MessageBoxEx.Show(AppString.Message.WebDataReadFailed);
                 url = AppConfig.RequestUseGithub ? GithubDonate : GiteeDonate;
                 ExternalProgram.OpenUrl(url);
             }
@@ -186,6 +214,32 @@ namespace ContextMenuManager
             }
         }
 
+        public static byte[] GetShellNewData(string extension)
+        {
+            string apiUrl = AppConfig.RequestUseGithub ? GithubShellNewApi : GiteeShellNewApi;
+            XmlDocument doc = GetWebJsonToXml(apiUrl);
+            if(doc == null) return null;
+            foreach(XmlNode node in doc.FirstChild.ChildNodes)
+            {
+                XmlNode nameXN = node.SelectSingleNode("name");
+                string str = Path.GetExtension(nameXN.InnerText);
+                if(string.Equals(str, extension, StringComparison.OrdinalIgnoreCase))
+                {
+                    try
+                    {
+                        using(UAWebClient client = new UAWebClient())
+                        {
+                            string dirUrl = AppConfig.RequestUseGithub ? GithubShellNewRawDir : GiteeShellNewRawDir;
+                            string fileUrl = $"{dirUrl}/{nameXN.InnerText}";
+                            return client.DownloadData(fileUrl);
+                        }
+                    }
+                    catch { return null; }
+                }
+            }
+            return null;
+        }
+
         /// <summary>加工处理更新信息,去掉标题头</summary>
         private static string MachinedInfo(string info)
         {
@@ -214,7 +268,9 @@ namespace ContextMenuManager
             {
                 using(UAWebClient client = new UAWebClient())
                 {
-                    return client.DownloadString(url);
+                    string str = client.DownloadString(url);
+                    str = str?.Replace("\n", Environment.NewLine);//换行符转换
+                    return str;
                 }
             }
             catch { return null; }

+ 69 - 56
Donate.md

@@ -4,97 +4,110 @@
 
 > ContextMenuManager完全开源免费,如果你觉得此程序帮助到了你,可以对作者进行捐赠,金额请随意,谢谢支持!
 
-> 备注:收款码平台会隐藏付款方ID,可在支付时备注昵称,已支付用户可通过[email protected]联系我更新用户ID。
+> 备注:收款码平台会隐藏付款方ID,可在支付时备注昵称,已支付用户可通过 [email protected] 联系我更新用户ID。
 
 ## 捐赠名单
 
-> 此名单不定期更新(上次更新:**2021-05-14**)
+> 此名单不定期更新(上次更新:**2021-06-08**)
 
-> 累计金额:**521.78** 元,累计人次:**84** 人次
+> 累计金额:**687.35** 元,累计人次:**97** 人次
 
 |日期|用户ID|平台|金额|备注
 |:--:|:--:|:--:|:--:|:--:
-|2020-10-20|W*t|微信|30|
+|2020-10-20|W*t|微信|30
 |2020-10-24|*远|微信|6|右键,一份迟到的支持
-|2020-10-28|*班|微信|3|
-|2020-11-03|*方|微信|5|
-|2020-11-03|m*c|微信|5|
-|2020-11-04|*海|支付宝|5|
+|2020-10-28|*班|微信|3
+|2020-11-03|*方|微信|5
+|2020-11-03|m*c|微信|5
+|2020-11-04|*海|支付宝|5
 |2020-11-06|*龙|微信|6.66|软件好,但用不了
 |2020-11-08|lty2002|QQ|1.88|右键管理好评!
 |2020-11-09|*熊|微信|1|加油
 |2020-11-09|m*s|微信|5|支持一下!CMM
-|2020-11-15|*德|微信|1|
-|2020-11-20|**骅|支付宝|1|
-|2020-11-24|*师|微信|10|
-|2020-11-25|*城|微信|1|
-|2020-11-27|*文|微信|3|
-|2020-12-05|*勋|支付宝|0.5|
-|2020-12-05|**宇|支付宝|9.9|
-|2020-12-06|*經|微信|1|
-|2020-12-07|*白|微信|1|
+|2020-11-15|*德|微信|1
+|2020-11-20|**骅|支付宝|1
+|2020-11-24|*师|微信|10
+|2020-11-25|*城|微信|1
+|2020-11-27|*文|微信|3
+|2020-12-05|*勋|支付宝|0.5
+|2020-12-05|**宇|支付宝|9.9
+|2020-12-06|*經|微信|1
+|2020-12-07|*白|微信|1
 |2020-12-11|F*n|微信|5|加油大佬
 |2020-12-11|匿名|支付宝|10|匿名捐赠
-|2020-12-12|*Y|微信|3|
+|2020-12-12|*Y|微信|3
 |2020-12-18|*烁|支付宝|5|右键管理软件很好用,感谢!
 |2020-12-18|*班|微信|5|加油
 |2020-12-25|*贵|微信|10|点赞!
 |2020-12-31|*昊|支付宝|15|支持一下,大佬继续加油
-|2021-01-03|匿名|微信|4|
-|2021-01-03|s*h|微信|2|
-|2021-01-06|*檬|微信|1|
-|2021-01-09|*。|微信|2|
+|2021-01-03|匿名|微信|4
+|2021-01-03|s*h|微信|2
+|2021-01-06|*檬|微信|1
+|2021-01-09|*。|微信|2
 |2021-01-09|**璐|支付宝|5|支持开源
-|2021-01-11|*%|微信|1|
+|2021-01-11|*%|微信|1
 |2021-01-13|*犇|微信|3|辛苦,喝瓶肥宅快乐水
-|2021-01-15|*柚|微信|1|
-|2021-01-15|**轩|支付宝|10|
+|2021-01-15|*柚|微信|1
+|2021-01-15|**轩|支付宝|10
 |2021-01-23|**政|支付宝|1.88|支持大佬
 |2021-01-26|*宁|微信|10|软件很好用,支持你
-|2021-01-28|*闯|支付宝|5|
-|2021-01-28|m*c|微信|4|
-|2021-01-28|*闯|支付宝|5|
-|2021-02-02|*强|微信|1|
-|2021-02-02|i*y|微信|5|cmm太好用了 救大命
+|2021-01-28|*闯|支付宝|5
+|2021-01-28|m*c|微信|4
+|2021-01-28|*闯|支付宝|5
+|2021-02-02|*强|微信|1
+|2021-02-04|i*y|微信|5|cmm太好用了 救大命
 |2021-02-06|F*t|微信|1|感谢作者,牛年牛牛牛
-|2021-02-10|L*g|微信|2|
+|2021-02-10|L*g|微信|2
 |2021-02-11|戴*n|微信|5|太好用了,第一次捐赠
 |2021-02-12|*奕|支付宝|2.8|真不错
 |2021-02-18|**凯|支付宝|6|方便好用,支持你
-|2021-02-24|**方|支付宝|2|
+|2021-02-24|**方|支付宝|2
 |2021-02-25|闭*g|微信|3|请大佬喝饮料🥤
-|2021-02-26|**海|支付宝|30|
-|2021-02-26|*觉|微信|1.6|
-|2021-02-28|*奇|微信|10|
-|2021-03-02|*瑜|微信|3|
-|2021-03-04|**方|支付宝|2|
-|2021-03-05|*科|支付宝|1|
-|2021-03-10|*y|微信|6.66|
-|2021-03-12|*禹|支付宝|5|
+|2021-02-26|**海|支付宝|30
+|2021-02-26|*觉|微信|1.6
+|2021-02-28|*奇|微信|10
+|2021-03-02|*瑜|微信|3
+|2021-03-04|**方|支付宝|2
+|2021-03-05|*科|支付宝|1
+|2021-03-10|*y|微信|6.66
+|2021-03-12|*禹|支付宝|5
 |2021-03-12|*游|微信|50|谢谢您的软件
 |2021-03-13|k*h|微信|6.66|右键管理强迫症福音
 |2021-03-13|*🍊|微信|10|软件好用,十分感谢!
-|2021-03-16|**骏|支付宝|0.1|
-|2021-03-16|**华|支付宝|5|
+|2021-03-16|**骏|支付宝|0.1
+|2021-03-16|**华|支付宝|5
 |2021-03-19|**阳|支付宝|1|感谢帮我移除了天翼云盘右键菜单
-|2021-03-23|*👀|微信|6.66|
-|2021-03-25|**楠|支付宝|1|
+|2021-03-23|*👀|微信|6.66
+|2021-03-25|**楠|支付宝|1
 |2021-03-29|花*.|微信|3|挺好用哒哒
-|2021-03-30|*珊|微信|10|
-|2021-04-02|**霖|支付宝|10|
-|2021-04-03|**科|支付宝|6|
-|2021-04-08|**帅|支付宝|2|
+|2021-03-30|*珊|微信|10
+|2021-04-02|**霖|支付宝|10
+|2021-04-03|**科|支付宝|6
+|2021-04-08|**帅|支付宝|2
 |2021-04-11|*财|微信|2|菜单管理工具太棒了
 |2021-04-12|**基|支付宝|5|请喝维他奶
-|2021-04-13|**方|支付宝|4|
-|2021-04-14|**明|支付宝|50|
-|2021-04-21|*。|微信|5|
+|2021-04-13|**方|支付宝|4
+|2021-04-14|**明|支付宝|50
+|2021-04-21|*。|微信|5
 |2021-04-22|生鲜鱼弱|微信|6.66|加油
 |2021-04-26|**彬|支付宝|6.66|大佬加油!!!
-|2021-04-28|*浦|微信|6.66|
+|2021-04-28|*浦|微信|6.66
 |2021-04-29|j*y|微信|0.5|清理右键菜单
-|2021-05-06|*越|支付宝|3|
-|2021-05-08|**泽|支付宝|3|
-|2021-05-10|G*H|微信|5|
+|2021-05-06|*越|支付宝|3
+|2021-05-08|**泽|支付宝|3
+|2021-05-10|G*H|微信|5
 |2021-05-11|j*k|微信|1|谢谢!
-|2021-05-14|*辰|微信|20|谢谢您的右键管理程序
+|2021-05-14|*辰|微信|20|谢谢您的右键管理程序
+|2021-05-16|L.E.T|QQ|1.59|真的好用,比电脑管家好多
+|2021-05-18|B*n|微信|10
+|2021-05-21|千年等一回|QQ|21|我很想交你这个朋友
+|2021-05-24|L*g|微信|2
+|2021-05-24|o*1|微信|3|很好用的软件
+|2021-06-02|*亮|微信|6.66
+|2021-06-05|*本|微信|100
+|2021-06-05|*ɞ|微信|6.66|希望能继续更新下去..
+|2021-06-06|**东|支付宝|1
+|2021-06-07|*扬|微信|5
+|2021-06-07|*豆|微信|6.66|非常好的软件,感谢!
+|2021-06-08|**辉|支付宝|1
+|2021-06-08|*潘|微信|1

+ 1 - 1
README-en.md

@@ -1,7 +1,7 @@
 **[简体中文](README.md)** | **English**
 # ContextMenuManager
 ------
-> A program to manage the Windows right-click context menu.
+> 🖱️ A program to manage the Windows right-click context menu.
 
 ## Key features
 * Enable and disable context menu options for files, folders, submenus (e.g. open, send to), Internet Explorer, and Win + X

+ 3 - 3
README.md

@@ -1,7 +1,7 @@
 **简体中文** | **[English](README-en.md)**
 # ContextMenuManager
 ------
-> 一个纯粹的Windows右键菜单管理程序
+> 🖱️ 一个纯粹的Windows右键菜单管理程序
 
 ## 程序下载
 * [最新版本][Latest]<br>
@@ -31,8 +31,8 @@
 * [程序按钮图标][AppImage] 主要来自于 [阿里巴巴矢量图标资源库][IconFont]<br>![](Screenshot/AppImage.png)
 
 ## 温馨提示
-* 一些特殊菜单项目(ShellEx类型,比如文件的加密(&Y))可能会受到其他因素影响,导致不会显示<br>在右键菜单中,但是按照程序使用的通用规则在此程序中仍会显示为启用,这是正常现象
-* 每个右键菜单管理程序禁用菜单方法可能不同,建议不要同时使用多个右键菜单管理程序,大部分<br>同类型程序使用简单暴力的备份-删除法,此程序尽可能使用了系统提供的键值进行隐藏操作;如果<br>之前使用过其他程序禁用右键菜单项目,建议先使用对应软件还原,不然可能无法在此程序中显示
+* 程序需要对大量的注册表项和文件进行读写删改操作,这些敏感的行为可能<br>会被 Windows Defender 等误报为病毒,如发生此情况请自行添加进白名单
+* 一些特殊菜单项可能会受到其他因素影响导致不会直接显示在右键菜单中,<br>但是按照程序使用的通用规则在此程序中仍会显示为启用,这是正常的现象
 * 此程序不用于清理未卸载干净的程序,但是可以帮助你快速定位菜单项相关注册表位置和文件位置,<br>你可以根据相关内容进行你的操作。如果你是一个电脑小白,建议只使用启用\禁用功能。
 
 ## 联系作者

BIN
Screenshot/AppImage.png


+ 30 - 26
languages/zh-CN.ini

@@ -116,9 +116,10 @@ RegistryLocation = 注册表位置
 ExportRegistry = 导出注册表
 Delete = 删除此项
 DeleteReference = 删除引用
-HandleGuid = 处理guid
-CopyGuid = 复制guid
-BlockGuid = 锁定guid
+HandleGuid = 处理GUID
+CopyGuid = 复制GUID
+BlockGuid = 锁定GUID
+ClsidLocation = CLSID路径
 AddGuidDic = 添加字典
 InitialData = 编辑文件初始数据
 BeforeSeparator = 显示在分割线上方
@@ -132,6 +133,7 @@ Ok = 确认
 Cancel = 取消
 Browse = 浏览
 Program = 程序
+AllFiles = 所有文件
 RegistryFile = 注册表文件
 ItemText = 菜单文本
 ItemCommand = 菜单命令
@@ -174,30 +176,30 @@ TranslateTool = 翻译工具
 DefaultText = 默认文本
 OldTranslation = 旧译文
 NewTranslation = 新译文
-SelectSubMenuMode = 该多级菜单子项目数为0, 你有两个选择:\r\n①该多级菜单的所有子菜单项目私有(推荐),\r\n②该多级菜单可与其他多级菜单引用相同子项,\r\n请做出你的选择......
-DonateInfo = 此名单不定期更新, 上次更新:%date \r\n\r\n累计金额:%money 元, 累计人次:%count 人次
+SelectSubMenuMode = 该多级菜单子项目数为0,你有两个选择:\r\n①该多级菜单的所有子菜单项目私有(推荐),\r\n②该多级菜单可与其他多级菜单引用相同子项,\r\n请做出你的选择......
+DonateInfo = 此名单不定期更新,上次更新:%date \r\n\r\n累计金额:%money 元,累计人次:%count 人次
 
 [Message]
 TextCannotBeEmpty = 菜单文本不能为空!
 CommandCannotBeEmpty = 菜单命令不能为空!
 StringParsingFailed = 本地化字符串解析失败!
-TextLengthCannotExceed80 = 菜单文本过长, 长度不允许超过80!
-ConfirmDeletePermanently = 确认是否永久删除此项?\r\n此操作无法还原,请谨慎操作!
-DeleteButCanRestore = 确认删除此菜单的注册表项目?\r\n由于启用了自动备份(默认启用),\r\n删除后可在备份文件夹中还原。
+TextLengthCannotExceed80 = 菜单文本过长长度不允许超过80!
+ConfirmDeletePermanently = 确认是否永久删除此项?\r\n此操作无法还原请谨慎操作!
+DeleteButCanRestore = 确认删除此菜单的注册表项目?\r\n由于启用了自动备份(默认启用)\r\n删除后可在备份文件夹中还原。
 ConfirmDeleteReference = 确认是否移除对该项目的引用?
 ConfirmDelete = 确认是否删除该项?
-ConfirmDeleteReferenced = 确认是否删除此项?\r\n所有引用此项的项目都会失效,请谨慎操作!
-CannotAddNewItem = 系统限制子菜单数目最多为16,\r\n无法添加更多的子菜单项目!
+ConfirmDeleteReferenced = 确认是否删除此项?\r\n所有引用此项的项目都会失效请谨慎操作!
+CannotAddNewItem = 系统限制子菜单数目最多为16\r\n无法添加更多的子菜单项目!
 VistaUnsupportedMulti = Vista系统不支持多级菜单!
 CannotHideSubItem = 你的系统版本太低,不支持隐藏子级菜单!
-UnsupportedFilename = 不支持的文件名,\r\n可能已经存在相同文件名的菜单项目!
-NoOpenModeExtension = 此扩展名没有关联默认打开方式,\r\n请先为此类型文件关联打开方式!
+UnsupportedFilename = 不支持的文件名\r\n可能已经存在相同文件名的菜单项目!
+NoOpenModeExtension = 此扩展名没有关联默认打开方式\r\n请先为此类型文件关联打开方式!
 CannotChangePath = 不允许更改文件路径!
 CopiedToClipboard = 已复制到剪切板:
 MalformedGuid = 格式不正确的Guid
 HasBeenAdded = 此项目已被添加!
-EditInitialData = 此程序现仅支持编辑纯文本文件的初始数据,\r\n其他类型文件请自行编辑注册表"Data"键值,\r\n请确认是否继续你的操作?
-PromptIsOpenItem = 该项为文件或文件夹的"打开"菜单,\n盲目操作可能会导致无法打开文件或文件夹,\n请确认是否继续你的操作?(不建议)
+EditInitialData = 此程序现仅支持编辑纯文本文件的初始数据,\r\n其他类型文件请自行编辑注册表"Data"键值,\r\n请确认是否继续你的操作?
+PromptIsOpenItem = 该项为文件或文件夹的"打开"菜单,\n盲目操作可能会导致无法打开文件或文件夹,\n请确认是否继续你的操作?(不建议)
 SelectRegPath = 操作步骤:\r\n① 打开注册表编辑器(自动)\r\n② 导航到目标注册表路径\r\n③ 关闭注册表编辑器窗口\n请确认是否继续?
 RestartApp = 程序将会重新启动!
 FileNotExists = 文件不存在!
@@ -205,26 +207,27 @@ FolderNotExists = 文件夹不存在!
 UpdateInfo = 【检测更新】\r\n当前版本:%v1\r\n最新版本:%v2\r\n是否立即下载更新?
 UpdateSucceeded = 程序更新成功!
 VersionIsLatest = 当前版本为最新版!
-AuthorityProtection = 此菜单注册表项目可能受安全软件保护,\r\n无法对其进行禁用删除和其他个性化修改。
+AuthorityProtection = 此菜单注册表项目可能受安全软件保护\r\n无法对其进行禁用删除和其他个性化修改。
 WinXSorted = 为优化排序功能已对部分项目重新编号,\r\n需要重启文件资源管理器应用效果
 RestoreDefault = 确认还原为默认菜单项目?
 DeleteGroup = 确认永久删除此组及组内所有菜单项目?
-NetworkDtaReadFailed = 网络数据读取失败!
+WebDataReadFailed = 网络数据读取失败!
 
 [Tip]
-RestartExplorer = 重启Explorer会使桌面闪烁片刻, 正常现象无需担心,\r\n或者你也可以稍后重启或注销计算机使你的操作生效
+RestartExplorer = 重启Explorer会使桌面闪烁片刻,正常现象无需担心,\r\n或者你也可以稍后重启或注销计算机使你的操作生效
 CustomFolder = 禁用此项将会同时禁用文件系统\r\n对象属性面板中的自定义选项卡
-SendToDrive = 仅当插入可移动磁盘时有作用,\r\n显示该可移动磁盘的所有分区
+SendToDrive = 仅当插入可移动磁盘时有作用\r\n显示该可移动磁盘的所有分区
 BuildSendtoMenu = 禁用此项将加快主菜单弹出速度\r\n但会延缓发送到子菜单弹出速度
 InvalidItem = 无效菜单项目将导致此项以下的\r\n所有菜单项目不可见(建议删除)
 EditSubItems = 编辑子菜单项目
 AddReference = 从公共引用项目中添加引用
+AddFromPublic = 从公共引用中复制菜单项目
 AddFromParentMenu = 从母菜单中复制项目
 AddSeparator = 添加分隔线
 DeleteGuidDic = 删除用户自行添加的该项的本地Guid字典
 LockNewMenu = 启用后可阻止第三方程序增加项目\r\n且可对现有项目排序(关闭后复原)
 DropOrSelectObject = 请拖拽或通过按钮选择文件或目录
-ConfigPath = 更改配置和数据文件保存路径后,\r\n会导致部分已启用增强菜单失效,\r\n可在增强菜单中重新启用一遍
+ConfigPath = 更改配置和数据文件保存路径后,\r\n会导致部分已启用增强菜单失效,\r\n可在增强菜单中重新启用一遍
 CommandFiles = 此命令依赖配置文件,移动配置文件位置\r\n会导致此菜单项失效,重新启用一遍即可
 CreateGroup = 新建一个分组
 
@@ -246,7 +249,7 @@ BuildSendtoMenu = 快速构建发送到子菜单
 UseStoreOpenWith = 在Microsoft Store中查找应用
 NewItem = 新建一个菜单项目
 AddGuidBlockedItem = 添加GUID锁定项目
-LockNewMenu = 锁定新建菜单
+LockNewMenu = 锁定新建菜单并启用排序功能
 InvalidItem = 无效菜单项目:
 Separator = >>>>>> 分割线 <<<<<<
 SelectRegPath = 请选择注册表项
@@ -262,7 +265,7 @@ RestartExplorer = 当前部分操作需要重启文件资源管理器生效
 UserDictionaries = 用户字典
 DictionaryDescription = 字典说明
 GuidInfosDictionary = GUID信息
-UWPMode = UWP模块
+UwpMode = UWP模块
 Translators = 翻译贡献者
 DonationList = 捐赠名单
 ConfigPath = 配置和数据文件保存位置
@@ -275,17 +278,18 @@ OnceAMonth = 每月一次
 OnceASeason = 每季一次
 NeverCheck = 从不检查
 ImmediatelyCheck = 立即检查
-SetRequestRepo = 设置程序访问的存储库站点
-ProtectOpenItem = 保护 "打开" 菜单项目
+SetRequestRepo = 设置网络数据访问存储库站点
+ProtectOpenItem = 保护名称为 "打开" 菜单项目
 WebSearchEngine = 设置网页搜索使用的搜索引擎
 CustomEngine = 自定义
 SetCustomEngine = 设置搜索引擎 (以 %s 代替搜索关键词)
 HideDisabledItems = 不显示已禁用的菜单项目
+HideSysStoreItems = 隐藏公共引用中的系统菜单
 SetPerceivedType = 设置扩展名为 %s 的文件感知类型为
 SetDefaultDropEffect = 设置文件对象默认拖拽命令为
 
-AboutApp = 【主要功能】\r\n 1.管理常见位置右键菜单\r\n 2.自定义添加右键菜单\r\n\r\n【兼容性能】\r\n 1.适用于Win7、8、8.1、10、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    但是按照程序使用的通用规则在此程序中仍会显示为启用,这是正常的现象。\r\n 2.每个右键管理程序禁用菜单方法可能不同, 建议不要同时使用多个右键菜单管理程序,\r\n    大部分程序使用简单暴力的备份-删除法, 此程序尽可能使用了系统提供的键值进行隐藏操作,\r\n    若之前使用过其他程序禁用菜单项,请先使用对应程序还原, 不然可能无法在此程序中看到它。\r\n 3.此程序不用于清理未卸载干净的程序,但可帮助你定位菜单项相关注册表和文件位置,\r\n    你可根据相关内容进行你的操作,如果你是一个电脑小白,建议只碰启用\禁用开关。
+AboutApp = 【兼容性能】\r\n 1.适用于Win7、8、8.1、10、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    你可根据相关内容进行你的操作,如果你是一个电脑小白,建议只碰启用\禁用开关。
 
-Dictionaries = 【字典说明】\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.第三方程序菜单内部设置字典 (ThirdRulesDic.xml)\r\n 4.增强菜单项目字典 (EnhanceMenusDic.xml)\r\n 5.UWP新模块字典 (UWPModeItemsDic.xml)
+Dictionaries = 【字典说明】\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.第三方程序菜单内部设置字典 (ThirdRulesDic.xml)\r\n 4.增强菜单项目字典 (EnhanceMenusDic.xml)\r\n 5.UWP新模块字典 (UWPModeItemsDic.xml)
 
-Donate = 此程序完全免费,如果你觉得这个软件对你有所帮助, 你可以通过扫描\r\n下方二维码(微信、支付宝、腾讯QQ)进行捐赠, 金额请随意, 谢谢支持!\r\n也期待你在Github或者Gitee上为此程序项目点亮Star (这对我很重要!)
+Donate = 此程序完全免费,如果你觉得这个软件对你有所帮助,你可以通过扫描\r\n下方二维码(微信、支付宝、腾讯QQ)进行捐赠,金额请随意,谢谢支持!\r\n也期待你在Github或者Gitee上为此程序项目点亮Star (这对我很重要!)