ShellExItem.cs 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. using BulePointLilac.Controls;
  2. using BulePointLilac.Methods;
  3. using ContextMenuManager.Controls.Interfaces;
  4. using Microsoft.Win32;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Windows.Forms;
  9. namespace ContextMenuManager.Controls
  10. {
  11. sealed class ShellExItem : MyListItem, IChkVisibleItem, IBtnShowMenuItem,
  12. ITsiWebSearchItem, ITsiFilePathItem, ITsiRegPathItem, ITsiDeleteItem
  13. {
  14. public static Dictionary<string, Guid> GetPathAndGuids(string shellExPath)
  15. {
  16. Dictionary<string, Guid> dic = new Dictionary<string, Guid>();
  17. foreach(string cmhPart in CmhParts)
  18. {
  19. using(RegistryKey cmKey = RegistryEx.GetRegistryKey($@"{shellExPath}\{cmhPart}"))
  20. {
  21. if(cmKey == null) continue;
  22. foreach(string keyName in cmKey.GetSubKeyNames())
  23. {
  24. using(RegistryKey key = cmKey.OpenSubKey(keyName))
  25. {
  26. if(!GuidInfo.TryGetGuid(key.GetValue("")?.ToString(), out Guid guid))
  27. GuidInfo.TryGetGuid(keyName, out guid);
  28. if(!guid.Equals(Guid.Empty))
  29. dic.Add(key.Name, guid);
  30. }
  31. }
  32. }
  33. }
  34. return dic;
  35. }
  36. public static readonly string[] CmhParts = { "ContextMenuHandlers", "-ContextMenuHandlers" };
  37. private const string LnkOpenGuid = "00021401-0000-0000-c000-000000000046";
  38. public ShellExItem(Guid guid, string regPath)
  39. {
  40. InitializeComponents();
  41. this.Guid = guid;
  42. this.RegPath = regPath;
  43. }
  44. private string regPath;
  45. public string RegPath
  46. {
  47. get => regPath;
  48. set
  49. {
  50. regPath = value;
  51. this.Text = this.ItemText;
  52. this.Image = GuidInfo.GetImage(Guid);
  53. ChkVisible.Checked = this.ItemVisible;
  54. }
  55. }
  56. public Guid Guid { get; set; }
  57. public string SearchText => Text;
  58. public string ItemFilePath => GuidInfo.GetFilePath(Guid);
  59. private string KeyName => RegistryEx.GetKeyName(RegPath);
  60. private string ShellExPath => RegistryEx.GetParentPath(RegistryEx.GetParentPath(RegPath));
  61. private string CmhKeyName => RegistryEx.GetKeyName(RegistryEx.GetParentPath(RegPath));
  62. private string DefaultValue => Registry.GetValue(RegPath, "", null)?.ToString();
  63. private string ItemText => GuidInfo.GetText(Guid) ?? ((Guid.ToString("B") == KeyName) ? DefaultValue : KeyName);
  64. private string BuckupPath => $@"{ShellExPath}\{(ItemVisible ? CmhParts[1] : CmhParts[0])}\{KeyName}";
  65. private GuidInfo.IconLocation IconLocation => GuidInfo.GetIconLocation(this.Guid);
  66. private bool IsOpenLnkItem => Guid.ToString() == LnkOpenGuid;
  67. private bool TryProtectOpenItem => IsOpenLnkItem && MessageBoxEx.Show
  68. (AppString.MessageBox.PromptIsOpenItem, MessageBoxButtons.YesNo) != DialogResult.Yes;
  69. public bool ItemVisible
  70. {
  71. get => CmhKeyName.Equals(CmhParts[0], StringComparison.OrdinalIgnoreCase);
  72. set
  73. {
  74. if(!value && TryProtectOpenItem) return;
  75. using(RegistryKey srcKey = RegistryEx.GetRegistryKey(RegPath))
  76. using(RegistryKey dstKey = RegistryEx.GetRegistryKey(BuckupPath, true, true))
  77. srcKey?.CopyTo(dstKey);
  78. RegistryEx.DeleteKeyTree(RegPath);
  79. RegPath = BuckupPath;
  80. }
  81. }
  82. public VisibleCheckBox ChkVisible { get; set; }
  83. public MenuButton BtnShowMenu { get; set; }
  84. public WebSearchMenuItem TsiSearch { get; set; }
  85. public FilePropertiesMenuItem TsiFileProperties { get; set; }
  86. public FileLocationMenuItem TsiFileLocation { get; set; }
  87. public RegLocationMenuItem TsiRegLocation { get; set; }
  88. public DeleteMeMenuItem TsiDeleteMe { get; set; }
  89. readonly ToolStripMenuItem TsiDetails = new ToolStripMenuItem(AppString.Menu.Details);
  90. readonly ToolStripMenuItem TsiHandleGuid = new ToolStripMenuItem(AppString.Menu.HandleGuid);
  91. readonly ToolStripMenuItem TsiCopyGuid = new ToolStripMenuItem(AppString.Menu.CopyGuid);
  92. readonly ToolStripMenuItem TsiBlockGuid = new ToolStripMenuItem(AppString.Menu.BlockGuid);
  93. readonly ToolStripMenuItem TsiAddGuidDic = new ToolStripMenuItem(AppString.Menu.AddGuidDic);
  94. private void InitializeComponents()
  95. {
  96. BtnShowMenu = new MenuButton(this);
  97. ChkVisible = new VisibleCheckBox(this);
  98. TsiSearch = new WebSearchMenuItem(this);
  99. TsiFileLocation = new FileLocationMenuItem(this);
  100. TsiFileProperties = new FilePropertiesMenuItem(this);
  101. TsiRegLocation = new RegLocationMenuItem(this);
  102. TsiDeleteMe = new DeleteMeMenuItem(this);
  103. ContextMenuStrip.Items.AddRange(new ToolStripItem[] { TsiHandleGuid, new ToolStripSeparator(),
  104. TsiDetails, new ToolStripSeparator(), TsiDeleteMe });
  105. TsiHandleGuid.DropDownItems.AddRange(new ToolStripItem[] { TsiCopyGuid, new ToolStripSeparator(),
  106. TsiBlockGuid, new ToolStripSeparator(), TsiAddGuidDic });
  107. TsiDetails.DropDownItems.AddRange(new ToolStripItem[] { TsiSearch, new ToolStripSeparator(),
  108. TsiFileProperties, TsiFileLocation, TsiRegLocation});
  109. ContextMenuStrip.Opening += (sender, e) => RefreshMenuItem();
  110. TsiCopyGuid.Click += (sender, e) => CopyGuid();
  111. TsiBlockGuid.Click += (sender, e) => BlockGuid();
  112. TsiAddGuidDic.Click += (sender, e) => AddGuidDic();
  113. }
  114. private void CopyGuid()
  115. {
  116. Clipboard.SetText(Guid.ToString());
  117. MessageBoxEx.Show($"{AppString.MessageBox.CopiedToClipboard}:\n{Guid}",
  118. MessageBoxButtons.OK, MessageBoxIcon.Information);
  119. }
  120. private void BlockGuid()
  121. {
  122. foreach(string path in GuidBlockedItem.BlockedPaths)
  123. {
  124. if(TsiBlockGuid.Checked)
  125. {
  126. RegistryEx.DeleteValue(path, this.Guid.ToString("B"));
  127. }
  128. else
  129. {
  130. Registry.SetValue(path, this.Guid.ToString("B"), string.Empty);
  131. }
  132. }
  133. ExplorerRestarter.NeedRestart = true;
  134. }
  135. private void AddGuidDic()
  136. {
  137. using(AddGuidDicDialog dlg = new AddGuidDicDialog())
  138. {
  139. dlg.ItemName = this.Text;
  140. dlg.ItemIcon = this.Image;
  141. dlg.ItemIconPath = this.IconLocation.IconPath;
  142. dlg.ItemIconIndex = this.IconLocation.IconIndex;
  143. IniFileHelper helper = new IniFileHelper(Program.GuidInfosDicPath);
  144. string section = this.Guid.ToString();
  145. if(dlg.ShowDialog() != DialogResult.OK)
  146. {
  147. if(dlg.IsDelete) {
  148. helper.DeleteSection(section);
  149. GuidInfo.ItemTextDic.Remove(this.Guid);
  150. GuidInfo.ItemImageDic.Remove(this.Guid);
  151. GuidInfo.IconLocationDic.Remove(this.Guid);
  152. GuidInfo.UserDic.RootDic.Remove(section);
  153. this.Text = this.ItemText;
  154. this.Image = GuidInfo.GetImage(Guid);
  155. }
  156. return;
  157. }
  158. Directory.CreateDirectory(Program.ConfigDir);
  159. if(!dlg.ItemName.IsNullOrWhiteSpace())
  160. {
  161. helper.SetValue(section, "Text", dlg.ItemName);
  162. this.Text = ResourceString.GetDirectString(dlg.ItemName);
  163. if(GuidInfo.ItemTextDic.ContainsKey(this.Guid))
  164. {
  165. GuidInfo.ItemTextDic[this.Guid] = this.Text;
  166. }
  167. else
  168. {
  169. GuidInfo.ItemTextDic.Add(this.Guid, this.Text);
  170. }
  171. }
  172. if(dlg.ItemIconLocation != null)
  173. {
  174. helper.SetValue(section, "Icon", dlg.ItemIconLocation);
  175. var location = new GuidInfo.IconLocation { IconPath = dlg.ItemIconPath, IconIndex = dlg.ItemIconIndex };
  176. if(GuidInfo.IconLocationDic.ContainsKey(this.Guid))
  177. {
  178. GuidInfo.IconLocationDic[this.Guid] = location;
  179. }
  180. else
  181. {
  182. GuidInfo.IconLocationDic.Add(this.Guid, location);
  183. }
  184. this.Image = dlg.ItemIcon;
  185. if(GuidInfo.ItemImageDic.ContainsKey(this.Guid))
  186. {
  187. GuidInfo.ItemImageDic[this.Guid] = this.Image;
  188. }
  189. else
  190. {
  191. GuidInfo.ItemImageDic.Add(this.Guid, this.Image);
  192. }
  193. }
  194. }
  195. }
  196. private void RefreshMenuItem()
  197. {
  198. TsiDeleteMe.Enabled = !IsOpenLnkItem;
  199. TsiBlockGuid.Checked = false;
  200. foreach(string path in GuidBlockedItem.BlockedPaths)
  201. {
  202. if(Registry.GetValue(path, this.Guid.ToString("B"), null) != null)
  203. {
  204. TsiBlockGuid.Checked = true;
  205. break;
  206. }
  207. }
  208. }
  209. public void DeleteMe()
  210. {
  211. RegistryEx.DeleteKeyTree(this.RegPath);
  212. RegistryEx.DeleteKeyTree(this.BuckupPath);
  213. this.Dispose();
  214. }
  215. }
  216. }