From b217ef6767ab2dd1d88f9ac94e08d88d7e31013b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=AB=98=E6=80=A1=E9=A3=9E?= <363301617@qq.com>
Date: Sun, 8 Dec 2024 23:08:29 +0800
Subject: [PATCH] Add Context menu item layout
Add Context menu item layout
---
.../Strings/ContextMenuManager.en-us.restext | 4 +-
.../Strings/ContextMenuManager.restext | 4 +-
.../ContextMenuManager.zh-hans.restext | 4 +-
.../Views/Pages/ContextMenuManager.xaml | 59 ++++++++++++
.../Views/Pages/ContextMenuManager.xaml.cs | 89 ++++++++++++++++---
.../PInvoke/Kernel32/Kernel32Library.cs | 16 +++-
6 files changed, 162 insertions(+), 14 deletions(-)
diff --git a/WindowsTools/Strings/ContextMenuManager.en-us.restext b/WindowsTools/Strings/ContextMenuManager.en-us.restext
index 0cb52e1..cff24d4 100644
--- a/WindowsTools/Strings/ContextMenuManager.en-us.restext
+++ b/WindowsTools/Strings/ContextMenuManager.en-us.restext
@@ -6,6 +6,8 @@ LearnContextMenuManager=Learn right-click menu management
LearnCustomRightClickMenu=Learn about customizing the right-click menu
LoadingContextMenuInformation=Loading right-click menu information, please wait...
OpenPackagePathToolTip=Open the app installation folder
+Refresh=Refresh
SearchAppNamePHText=Search app name
SearchEmptyDescription=No matching right-click menu item found
-Refresh=Refresh
+SelectedToolTip=Selected
+UnSelectedToolTip=Unselected
\ No newline at end of file
diff --git a/WindowsTools/Strings/ContextMenuManager.restext b/WindowsTools/Strings/ContextMenuManager.restext
index 0cb52e1..a1267e7 100644
--- a/WindowsTools/Strings/ContextMenuManager.restext
+++ b/WindowsTools/Strings/ContextMenuManager.restext
@@ -6,6 +6,8 @@ LearnContextMenuManager=Learn right-click menu management
LearnCustomRightClickMenu=Learn about customizing the right-click menu
LoadingContextMenuInformation=Loading right-click menu information, please wait...
OpenPackagePathToolTip=Open the app installation folder
+Refresh=Refresh
SearchAppNamePHText=Search app name
SearchEmptyDescription=No matching right-click menu item found
-Refresh=Refresh
+SelectedToolTip=Selected
+UnSelectedToolTip=Unselected
diff --git a/WindowsTools/Strings/ContextMenuManager.zh-hans.restext b/WindowsTools/Strings/ContextMenuManager.zh-hans.restext
index 1ffaf39..f1a364b 100644
--- a/WindowsTools/Strings/ContextMenuManager.zh-hans.restext
+++ b/WindowsTools/Strings/ContextMenuManager.zh-hans.restext
@@ -6,6 +6,8 @@ LearnContextMenuManager=了解右键菜单管理
LearnCustomRightClickMenu=了解自定义右键菜单
LoadingContextMenuInformation=正在加载右键菜单信息中,请稍候...
OpenPackagePathToolTip=打开应用安装目录
+Refresh=刷新
SearchAppNamePHText=搜索应用名称
SearchEmptyDescription=没有搜索到复合的右键菜单项
-Refresh=刷新
+SelectedToolTip=已选择
+UnSelectedToolTip=未选择
\ No newline at end of file
diff --git a/WindowsTools/Views/Pages/ContextMenuManager.xaml b/WindowsTools/Views/Pages/ContextMenuManager.xaml
index b74b449..17b2c46 100644
--- a/WindowsTools/Views/Pages/ContextMenuManager.xaml
+++ b/WindowsTools/Views/Pages/ContextMenuManager.xaml
@@ -12,6 +12,11 @@
NavigationCacheMode="Enabled"
mc:Ignorable="d">
+
+
+
+
+
@@ -292,6 +297,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WindowsTools/Views/Pages/ContextMenuManager.xaml.cs b/WindowsTools/Views/Pages/ContextMenuManager.xaml.cs
index 178734c..7e4b5e9 100644
--- a/WindowsTools/Views/Pages/ContextMenuManager.xaml.cs
+++ b/WindowsTools/Views/Pages/ContextMenuManager.xaml.cs
@@ -6,12 +6,18 @@
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Linq;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Input;
using WindowsTools.Models;
using WindowsTools.Services.Root;
+using WindowsTools.WindowsAPI.PInvoke.Kernel32;
+
+// 抑制 CA1822 警告
+#pragma warning disable CA1822
namespace WindowsTools.Views.Pages
{
@@ -81,6 +87,33 @@ public ContextMenuManagerPage()
InitializeComponent();
}
+ ///
+ /// 打开应用包路径
+ ///
+ private void OnOpenPackagePathExecuteRequested(XamlUICommand sender, ExecuteRequestedEventArgs args)
+ {
+ string path = args.Parameter as string;
+
+ Task.Run(() =>
+ {
+ try
+ {
+ Process.Start(path);
+ }
+ catch (Exception e)
+ {
+ LogService.WriteLog(EventLevel.Error, "Open package path failed", e);
+ }
+ });
+ }
+
+ ///
+ /// 点击复选框时使保存按钮处于可选状态
+ ///
+ private void OnCheckExecuteRequested(XamlUICommand sender, ExecuteRequestedEventArgs args)
+ {
+ }
+
#region 第一部分:右键菜单管理页面——挂载的事件
///
@@ -91,7 +124,17 @@ private async void OnLoaded(object sender, RoutedEventArgs args)
if (!isInitialized)
{
isInitialized = true;
- await Task.Delay(500);
+ ContextMenuCollection.Clear();
+ List contextMenuList = await Task.Run(async () =>
+ {
+ await Task.Delay(500);
+ List contextMenuList = GetContextMenuList();
+ return contextMenuList;
+ });
+ foreach (ContextMenuModel contextMenuItem in contextMenuList)
+ {
+ ContextMenuCollection.Add(contextMenuItem);
+ }
IsLoadCompleted = true;
}
}
@@ -149,7 +192,12 @@ private void OnSerachAppNameTextChanged(object sender, AutoSuggestBoxTextChanged
private async void OnRefreshClicked(object sender, RoutedEventArgs args)
{
IsLoadCompleted = false;
- await Task.Delay(500);
+ ContextMenuCollection.Clear();
+ List contextMenuList = await Task.Run(GetContextMenuList);
+ foreach (ContextMenuModel contextMenuItem in contextMenuList)
+ {
+ ContextMenuCollection.Add(contextMenuItem);
+ }
IsLoadCompleted = true;
}
@@ -161,6 +209,7 @@ private async void OnRefreshClicked(object sender, RoutedEventArgs args)
private List GetContextMenuList()
{
List contextMenuList = [];
+ List> blockedList = GetBlockedClsidList();
try
{
@@ -192,11 +241,13 @@ private List GetContextMenuList()
{
int serverId = Convert.ToInt32(clsidKey.GetValue("ServerId", 0));
int threading = Convert.ToInt32(clsidKey.GetValue("Threading", 0));
+ bool isBlocked = blockedList.Any(item => item.Key.Equals(clsid));
contextMenuItemList.Add(new ContextMenuItemModel()
{
Clsid = clsid,
DllPath = dllPath,
+ IsEnabled = !isBlocked,
ThreadingMode = threading switch
{
0 => ApartmentState.STA,
@@ -207,25 +258,37 @@ private List GetContextMenuList()
}
}
- classKey.Close();
- classKey.Dispose();
+ clsidKey.Close();
+ clsidKey.Dispose();
}
}
+ int length = 0;
+ string packagePath = string.Empty;
+
+ if (Kernel32Library.GetPackagePathByFullName(packageFullName, ref length, null) is 122)
+ {
+ StringBuilder packagePathBuilder = new(length + 1);
+ int result = Kernel32Library.GetPackagePathByFullName(packageFullName, ref length, packagePathBuilder);
+ packagePath = packagePathBuilder.ToString();
+ }
+
contextMenuList.Add(new()
{
+ PackageDisplayName = string.Empty,
PackageFullName = packageFullName,
+ PackagePath = packagePath,
ContextMenuItemCollection = new(contextMenuItemList)
});
- }
- classKey.Close();
- classKey.Dispose();
+ classKey.Close();
+ classKey.Dispose();
+ }
}
- }
- packageListKey.Close();
- packageListKey.Dispose();
+ packageListKey.Close();
+ packageListKey.Dispose();
+ }
}
catch (Exception e)
{
@@ -257,6 +320,9 @@ private List> GetBlockedClsidList()
blockClsidList.Add(new KeyValuePair(clsid, Registry.LocalMachine.ToString()));
}
}
+
+ blockKey.Close();
+ blockKey.Dispose();
}
}
catch (Exception e)
@@ -279,6 +345,9 @@ private List> GetBlockedClsidList()
blockClsidList.Add(new KeyValuePair(clsid, Registry.CurrentUser.ToString()));
}
}
+
+ blockKey.Close();
+ blockKey.Dispose();
}
}
catch (Exception e)
diff --git a/WindowsTools/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs b/WindowsTools/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs
index a832578..75fe628 100644
--- a/WindowsTools/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs
+++ b/WindowsTools/WindowsAPI/PInvoke/Kernel32/Kernel32Library.cs
@@ -1,4 +1,5 @@
-using System.Runtime.InteropServices;
+using System;
+using System.Runtime.InteropServices;
using System.Text;
// 抑制 CA1401 警告
@@ -33,6 +34,19 @@ public static class Kernel32Library
[DllImport(Kernel32, CharSet = CharSet.Unicode, EntryPoint = "GetCurrentPackageFamilyName", PreserveSig = true, SetLastError = false)]
public static extern int GetCurrentPackageFamilyName(ref int packageFamilyNameLength, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder packageFamilyName);
+ ///
+ /// 获取指定包的路径。
+ ///
+ /// 包的全名。
+ ///
+ /// 指向包含包路径字符串中 WCHAR) 字符数 (的变量的指针,其中包含 null 终止符。
+ /// 首先,将 NULL 传递给 路径 以获取字符数。 使用此数字为 路径分配内存空间。 然后传递此内存空间的地址以填充 路径。
+ ///
+ /// 指向接收包路径字符串(包括 null 终止符)的内存空间的指针。
+ /// 如果函数成功,则返回 ERROR_SUCCESS。 否则,函数将返回错误代码。
+ [DllImport(Kernel32, CharSet = CharSet.Unicode, EntryPoint = "GetPackagePathByFullName", PreserveSig = true, SetLastError = false)]
+ public static extern int GetPackagePathByFullName([MarshalAs(UnmanagedType.LPWStr)] string packageFullName, ref int pathLength, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder path);
+
///
/// 检索系统的电源状态。 状态指示系统是使用交流还是直流电源运行,电池当前是否正在充电,剩余的电池使用时间,以及节电模式是打开还是关闭。
///