diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index e185c88a..fa60e53b 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -14,6 +14,7 @@ using System.Windows.Threading; using static System.Windows.Forms.VisualStyles.VisualStyleElement; using MessageBox = System.Windows.MessageBox; using Window = System.Windows.Window; +using System.Collections.Generic; namespace Ink_Canvas { @@ -101,75 +102,81 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("未检测到Office安装", LogHelper.LogType.Warning); return; } - - var pptApplication = new Microsoft.Office.Interop.PowerPoint.Application(); - string officeVersion = pptApplication.Version; - LogHelper.WriteLogToFile($"检测到Office版本: {officeVersion}"); - - string regPath = $"Software\\Microsoft\\Office\\{officeVersion}\\Common\\Security"; - LogHelper.WriteLogToFile($"注册表路径: {regPath}"); - using (Microsoft.Win32.RegistryKey baseKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath)) + // 尝试获取所有可能的Office版本路径 + var officeVersions = GetOfficeVersions(); + if (officeVersions.Count == 0) { - if (baseKey == null) - { - LogHelper.WriteLogToFile($"注册表路径不存在: {regPath}", LogHelper.LogType.Warning); - return; - } + LogHelper.WriteLogToFile("未找到任何Office版本", LogHelper.LogType.Warning); + return; + } - Settings settingsInstance = new Settings(); - string backupPath = Path.Combine(settingsInstance.Automation.AutoSavedStrokesLocation, "RegistryBackups"); - LogHelper.WriteLogToFile($"备份路径: {backupPath}"); - - if (!Directory.Exists(backupPath)) - { - Directory.CreateDirectory(backupPath); - LogHelper.WriteLogToFile($"创建备份目录: {backupPath}"); - } - - string backupFile = Path.Combine(backupPath, $"SecurityBackup_{DateTime.Now:yyyyMMddHHmmss}.reg"); - LogHelper.WriteLogToFile($"创建备份文件: {backupFile}"); - - // 使用UTF8编码写入注册表文件 - using (StreamWriter sw = new StreamWriter(backupFile, false, System.Text.Encoding.UTF8)) - { - sw.WriteLine("Windows Registry Editor Version 5.00\n"); - sw.WriteLine(); - sw.WriteLine($"[{Microsoft.Win32.Registry.CurrentUser.Name}\\{regPath}]"); - - foreach (string valueName in baseKey.GetValueNames()) - { - object value = baseKey.GetValue(valueName); - sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}"); - LogHelper.WriteLogToFile($"备份注册表值: {valueName} = {value}"); - } - } + foreach (var version in officeVersions) + { + string regPath = $"Software\\Microsoft\\Office\\{version}\\Common\\Security"; + LogHelper.WriteLogToFile($"正在处理Office版本 {version}, 注册表路径: {regPath}"); - using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regPath, true)) + try { - // 仅在值不存在或不等于1时更新 - object currentValue = key.GetValue("DisableProtectedView"); - if (currentValue == null || (int)currentValue != 1) + using (Microsoft.Win32.RegistryKey baseKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath)) { - key.SetValue("DisableProtectedView", 1, Microsoft.Win32.RegistryValueKind.DWord); - LogHelper.WriteLogToFile("注册表值已设置: DisableProtectedView = 1"); - } - else - { - LogHelper.WriteLogToFile("注册表值已存在且无需更改: DisableProtectedView = 1"); + if (baseKey == null) + { + LogHelper.WriteLogToFile($"注册表路径不存在: {regPath}", LogHelper.LogType.Warning); + continue; + } + + Settings settingsInstance = new Settings(); + string backupPath = Path.Combine(settingsInstance.Automation.AutoSavedStrokesLocation, "RegistryBackups"); + LogHelper.WriteLogToFile($"备份路径: {backupPath}"); + + if (!Directory.Exists(backupPath)) + { + Directory.CreateDirectory(backupPath); + LogHelper.WriteLogToFile($"创建备份目录: {backupPath}"); + } + + string backupFile = Path.Combine(backupPath, $"SecurityBackup_{version}_{DateTime.Now:yyyyMMddHHmmss}.reg"); + LogHelper.WriteLogToFile($"创建备份文件: {backupFile}"); + + // 使用UTF8编码写入注册表文件 + using (StreamWriter sw = new StreamWriter(backupFile, false, System.Text.Encoding.UTF8)) + { + sw.WriteLine("Windows Registry Editor Version 5.00\n"); + sw.WriteLine(); + sw.WriteLine($"[{Microsoft.Win32.Registry.CurrentUser.Name}\\{regPath}]"); + + foreach (string valueName in baseKey.GetValueNames()) + { + object value = baseKey.GetValue(valueName); + sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}"); + LogHelper.WriteLogToFile($"备份注册表值: {valueName} = {value}"); + } + } + + using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regPath, true)) + { + // 仅在值不存在或不等于1时更新 + object currentValue = key.GetValue("DisableProtectedView"); + if (currentValue == null || (int)currentValue != 1) + { + key.SetValue("DisableProtectedView", 1, Microsoft.Win32.RegistryValueKind.DWord); + LogHelper.WriteLogToFile($"Office {version} 注册表值已设置: DisableProtectedView = 1"); + } + else + { + LogHelper.WriteLogToFile($"Office {version} 注册表值已存在且无需更改: DisableProtectedView = 1"); + } + } } } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"处理Office版本 {version} 时出错: {ex.Message}", LogHelper.LogType.Error); + continue; + } } } - catch (System.Runtime.InteropServices.COMException comEx) when (comEx.ErrorCode == -2147221040) - { - // 处理特定的COM错误(如Office未安装) - LogHelper.WriteLogToFile($"Office COM错误: 未安装PowerPoint (HRESULT: 0x{comEx.ErrorCode:x8})", LogHelper.LogType.Error); - } - catch (System.Runtime.InteropServices.COMException comEx) - { - LogHelper.WriteLogToFile($"Office COM错误: {comEx.Message} (HRESULT: 0x{comEx.ErrorCode:x8})", LogHelper.LogType.Error); - } catch (SecurityException secEx) { LogHelper.WriteLogToFile($"安全异常: {secEx.Message}", LogHelper.LogType.Error); @@ -180,14 +187,6 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"访问被拒绝: {authEx.Message}", LogHelper.LogType.Error); ShowPermissionError(); } - catch (DirectoryNotFoundException dirEx) - { - LogHelper.WriteLogToFile($"目录未找到: {dirEx.Message}", LogHelper.LogType.Error); - } - catch (IOException ioEx) - { - LogHelper.WriteLogToFile($"IO错误: {ioEx.Message}", LogHelper.LogType.Error); - } catch (Exception ex) { LogHelper.WriteLogToFile($"未知错误: {ex.GetType().FullName} - {ex.Message}", LogHelper.LogType.Error); @@ -343,5 +342,84 @@ namespace Ink_Canvas LogHelper.WriteLogToFile(message, LogHelper.LogType.Error); System.Windows.MessageBox.Show(message, "权限错误", MessageBoxButton.OK, MessageBoxImage.Error); } + + /// + /// 获取所有已安装的Office版本 + /// + private List GetOfficeVersions() + { + var versions = new List(); + try + { + // 检查HKLM + using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office")) + { + if (key != null) + { + foreach (var subKeyName in key.GetSubKeyNames()) + { + if (subKeyName.Contains(".0")) + { + versions.Add(subKeyName); + LogHelper.WriteLogToFile($"在HKLM中找到Office版本: {subKeyName}"); + } + } + } + } + + // 检查HKCU + using (var key = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Office")) + { + if (key != null) + { + foreach (var subKeyName in key.GetSubKeyNames()) + { + if (subKeyName.Contains(".0") && !versions.Contains(subKeyName)) + { + versions.Add(subKeyName); + LogHelper.WriteLogToFile($"在HKCU中找到Office版本: {subKeyName}"); + } + } + } + } + + // 检查64位注册表 + using (var key = Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Microsoft\\Office")) + { + if (key != null) + { + foreach (var subKeyName in key.GetSubKeyNames()) + { + if (subKeyName.Contains(".0") && !versions.Contains(subKeyName)) + { + versions.Add(subKeyName); + LogHelper.WriteLogToFile($"在64位注册表中找到Office版本: {subKeyName}"); + } + } + } + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"获取Office版本时出错: {ex.Message}", LogHelper.LogType.Error); + } + + // 按版本号排序 + versions.Sort((a, b) => + { + try + { + double va = double.Parse(a.Replace(".0", "")); + double vb = double.Parse(b.Replace(".0", "")); + return vb.CompareTo(va); // 降序排列,最新版本在前 + } + catch + { + return 0; + } + }); + + return versions; + } } } diff --git a/Ink Canvas/Helpers/ForegroundWindowInfo.cs b/Ink Canvas/Helpers/ForegroundWindowInfo.cs index 3a5312af..5e91858d 100644 --- a/Ink Canvas/Helpers/ForegroundWindowInfo.cs +++ b/Ink Canvas/Helpers/ForegroundWindowInfo.cs @@ -29,8 +29,26 @@ namespace Ink_Canvas.Helpers [DllImport("user32.dll")] private static extern int SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni); + [DllImport("user32.dll")] + private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi); + + [DllImport("user32.dll")] + private static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags); + private const uint ABM_GETTASKBARPOS = 0x00000005; + private const uint ABM_GETSTATE = 0x00000004; private const int SPI_GETWORKAREA = 0x0030; + private const uint MONITOR_DEFAULTTOPRIMARY = 1; + private const int ABS_AUTOHIDE = 0x0000001; + + [StructLayout(LayoutKind.Sequential)] + private struct MONITORINFO + { + public int cbSize; + public RECT rcMonitor; + public RECT rcWork; + public uint dwFlags; + } [StructLayout(LayoutKind.Sequential)] private struct APPBARDATA @@ -68,6 +86,17 @@ namespace Ink_Canvas.Helpers var abd = new APPBARDATA(); abd.cbSize = Marshal.SizeOf(abd); + // 获取任务栏状态 + IntPtr state = SHAppBarMessage(ABM_GETSTATE, ref abd); + bool isAutoHide = (state.ToInt32() & ABS_AUTOHIDE) == ABS_AUTOHIDE; + + // 如果任务栏是自动隐藏的,返回0 + if (isAutoHide) + { + LogHelper.WriteLogToFile("任务栏处于自动隐藏状态", LogHelper.LogType.Info); + return 0; + } + // 获取任务栏信息 IntPtr result = SHAppBarMessage(ABM_GETTASKBARPOS, ref abd); if (result != IntPtr.Zero) @@ -102,6 +131,7 @@ namespace Ink_Canvas.Helpers catch (Exception ex) { Debug.WriteLine($"获取任务栏高度出错: {ex.Message}"); + LogHelper.WriteLogToFile($"获取任务栏高度出错: {ex.Message}", LogHelper.LogType.Error); } // 如果获取失败,回退到通用方法 diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 9f8ebffc..754e4abd 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -1083,10 +1083,33 @@ namespace Ink_Canvas { pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2; if (PosXCaculatedWithTaskbarHeight == false) - pos.Y = screenHeight - MarginFromEdge * ViewboxFloatingBarScaleTransform.ScaleY; + { + // 如果任务栏高度为0(隐藏状态),则使用固定边距 + if (toolbarHeight == 0) + { + pos.Y = screenHeight - MarginFromEdge * ViewboxFloatingBarScaleTransform.ScaleY; + LogHelper.WriteLogToFile($"任务栏隐藏,使用固定边距: {MarginFromEdge}", LogHelper.LogType.Info); + } + else + { + pos.Y = screenHeight - MarginFromEdge * ViewboxFloatingBarScaleTransform.ScaleY; + } + } else if (PosXCaculatedWithTaskbarHeight == true) - pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - - toolbarHeight - ViewboxFloatingBarScaleTransform.ScaleY * 3; + { + // 如果任务栏高度为0(隐藏状态),则使用固定高度 + if (toolbarHeight == 0) + { + pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - + 3 * ViewboxFloatingBarScaleTransform.ScaleY; + LogHelper.WriteLogToFile($"任务栏隐藏,使用固定高度: {ViewboxFloatingBar.ActualHeight}", LogHelper.LogType.Info); + } + else + { + pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - + toolbarHeight - ViewboxFloatingBarScaleTransform.ScaleY * 3; + } + } if (MarginFromEdge != -60) { if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) { @@ -1145,8 +1168,18 @@ namespace Ink_Canvas { var toolbarHeight = ForegroundWindowInfo.GetTaskbarHeight(screen, dpiScaleY); pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2; - pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - - toolbarHeight - ViewboxFloatingBarScaleTransform.ScaleY * 3; + // 如果任务栏高度为0(隐藏状态),则使用固定边距 + if (toolbarHeight == 0) + { + pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - + 3 * ViewboxFloatingBarScaleTransform.ScaleY; + LogHelper.WriteLogToFile($"任务栏隐藏,使用固定高度: {ViewboxFloatingBar.ActualHeight}", LogHelper.LogType.Info); + } + else + { + pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY - + toolbarHeight - ViewboxFloatingBarScaleTransform.ScaleY * 3; + } if (pointDesktop.X != -1 || pointDesktop.Y != -1) pointDesktop = pos;