Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b5ec6e0d79 | |||
| 82486c707d | |||
| 5ff437bed5 | |||
| 2f7e0b85c0 | |||
| c9548af008 | |||
| b20e4a041f | |||
| 87f64ccc81 | |||
| 58028ea95c | |||
| 35fa062cc3 | |||
| 9de6555519 | |||
| a9baf47823 | |||
| a9b64d2899 |
+573
-4
@@ -1,16 +1,20 @@
|
|||||||
using Hardcodet.Wpf.TaskbarNotification;
|
using Hardcodet.Wpf.TaskbarNotification;
|
||||||
using Ink_Canvas.Helpers;
|
using Ink_Canvas.Helpers;
|
||||||
using iNKORE.UI.WPF.Modern.Controls;
|
using iNKORE.UI.WPF.Modern.Controls;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using System.Security; // 添加SecurityException所需命名空间
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Threading;
|
||||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
||||||
using MessageBox = System.Windows.MessageBox;
|
using MessageBox = System.Windows.MessageBox;
|
||||||
using Window = System.Windows.Window;
|
using Window = System.Windows.Window;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ink_Canvas
|
namespace Ink_Canvas
|
||||||
{
|
{
|
||||||
@@ -49,12 +53,11 @@ namespace Ink_Canvas
|
|||||||
LogHelper.NewLog(e.Exception.ToString());
|
LogHelper.NewLog(e.Exception.ToString());
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
|
|
||||||
// 新增:根据设置自动处理崩溃
|
// 修改:仅当非用户主动退出时才触发自动重启
|
||||||
if (CrashAction == CrashActionType.SilentRestart)
|
if (CrashAction == CrashActionType.SilentRestart && !IsAppExitByUser)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 静默重启:启动新进程并退出当前进程
|
|
||||||
string exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
|
string exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
|
||||||
System.Diagnostics.Process.Start(exePath);
|
System.Diagnostics.Process.Start(exePath);
|
||||||
}
|
}
|
||||||
@@ -87,6 +90,127 @@ namespace Ink_Canvas
|
|||||||
_taskbar = (TaskbarIcon)FindResource("TaskbarTrayIcon");
|
_taskbar = (TaskbarIcon)FindResource("TaskbarTrayIcon");
|
||||||
|
|
||||||
StartArgs = e.Args;
|
StartArgs = e.Args;
|
||||||
|
|
||||||
|
// 新增:Office注册表检测
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("开始Office注册表检测");
|
||||||
|
|
||||||
|
// 检查Office安装
|
||||||
|
if (!IsOfficeInstalled())
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("未检测到Office安装", LogHelper.LogType.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试获取所有可能的Office版本路径
|
||||||
|
var officeVersions = GetOfficeVersions();
|
||||||
|
if (officeVersions.Count == 0)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("未找到任何Office版本", LogHelper.LogType.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var version in officeVersions)
|
||||||
|
{
|
||||||
|
string regPath = $"Software\\Microsoft\\Office\\{version}\\Common\\Security";
|
||||||
|
LogHelper.WriteLogToFile($"正在处理Office版本 {version}, 注册表路径: {regPath}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Microsoft.Win32.RegistryKey baseKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(regPath))
|
||||||
|
{
|
||||||
|
if (baseKey == null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"注册表路径不存在: {regPath}", LogHelper.LogType.Warning);
|
||||||
|
// 尝试创建路径
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Microsoft.Win32.RegistryKey createKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(regPath, true))
|
||||||
|
{
|
||||||
|
if (createKey != null)
|
||||||
|
{
|
||||||
|
createKey.SetValue("DisableProtectedView", 1, Microsoft.Win32.RegistryValueKind.DWord);
|
||||||
|
LogHelper.WriteLogToFile($"创建并设置注册表路径: {regPath}", LogHelper.LogType.Info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception createEx)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"创建注册表路径失败: {createEx.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 备份路径更改为软件根目录下的saves/RegistryBackups文件夹
|
||||||
|
string backupPath = Path.Combine(RootPath, "saves", "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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理Office 365的特殊路径
|
||||||
|
TryModifyOffice365Registry();
|
||||||
|
}
|
||||||
|
catch (SecurityException secEx)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"安全异常: {secEx.Message}", LogHelper.LogType.Error);
|
||||||
|
ShowPermissionError();
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException authEx)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"访问被拒绝: {authEx.Message}", LogHelper.LogType.Error);
|
||||||
|
ShowPermissionError();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"未知错误: {ex.GetType().FullName} - {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
LogHelper.WriteLogToFile(ex.StackTrace, LogHelper.LogType.Info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
|
||||||
@@ -208,5 +332,450 @@ namespace Ink_Canvas
|
|||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查Office是否安装
|
||||||
|
/// </summary>
|
||||||
|
private bool IsOfficeInstalled()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 检查多个可能的注册表路径
|
||||||
|
// 1. 检查传统的Office版本
|
||||||
|
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office"))
|
||||||
|
{
|
||||||
|
if (key != null && key.GetSubKeyNames().Any(name => name.Contains(".0")))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("检测到传统Office安装", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 检查64位注册表中的Office
|
||||||
|
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Wow6432Node\\Microsoft\\Office"))
|
||||||
|
{
|
||||||
|
if (key != null && key.GetSubKeyNames().Any(name => name.Contains(".0")))
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("检测到64位注册表中的Office安装", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 检查Office 365/Click-to-Run安装
|
||||||
|
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("检测到Office 365 Click-to-Run", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 检查Office 365部署配置
|
||||||
|
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\15.0\\ClickToRun"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("检测到Office 365 (15.0)", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\16.0\\ClickToRun"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("检测到Office 365 (16.0)", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 检查Office 365零售订阅信息
|
||||||
|
using (Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun\\Configuration"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("检测到Office 365配置", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile("未检测到任何Office安装", LogHelper.LogType.Warning);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"检查Office安装时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 显示权限不足的错误提示
|
||||||
|
/// </summary>
|
||||||
|
private void ShowPermissionError()
|
||||||
|
{
|
||||||
|
const string message = "需要管理员权限才能完成此操作\n请以管理员身份重新启动应用程序";
|
||||||
|
LogHelper.WriteLogToFile(message, LogHelper.LogType.Error);
|
||||||
|
System.Windows.MessageBox.Show(message, "权限错误", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有已安装的Office版本
|
||||||
|
/// </summary>
|
||||||
|
private List<string> GetOfficeVersions()
|
||||||
|
{
|
||||||
|
var versions = new List<string>();
|
||||||
|
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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Office 365的特殊路径
|
||||||
|
CheckOffice365Versions(versions);
|
||||||
|
|
||||||
|
// 如果没有找到任何版本,添加默认的Office 365版本号
|
||||||
|
if (versions.Count == 0 && IsOffice365Installed())
|
||||||
|
{
|
||||||
|
versions.Add("16.0");
|
||||||
|
LogHelper.WriteLogToFile("未找到具体版本,添加默认Office 365版本: 16.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检测Office 365是否已安装
|
||||||
|
/// </summary>
|
||||||
|
private bool IsOffice365Installed()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 检查多个Office 365特定路径
|
||||||
|
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\15.0\\ClickToRun"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\16.0\\ClickToRun"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun\\Configuration"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查Office 365特有的版本信息
|
||||||
|
/// </summary>
|
||||||
|
private void CheckOffice365Versions(List<string> versions)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 检查Click-to-Run版本路径
|
||||||
|
using (var key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Office\\ClickToRun\\Configuration"))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
var platformVersion = key.GetValue("Platform") as string;
|
||||||
|
var clickToRunVersion = key.GetValue("VersionToReport") as string;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(platformVersion))
|
||||||
|
{
|
||||||
|
var majorVersion = platformVersion.Split('.').FirstOrDefault();
|
||||||
|
if (!string.IsNullOrEmpty(majorVersion) && !versions.Contains($"{majorVersion}.0"))
|
||||||
|
{
|
||||||
|
versions.Add($"{majorVersion}.0");
|
||||||
|
LogHelper.WriteLogToFile($"在Office 365配置中找到平台版本: {majorVersion}.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(clickToRunVersion))
|
||||||
|
{
|
||||||
|
var majorVersion = clickToRunVersion.Split('.').FirstOrDefault();
|
||||||
|
if (!string.IsNullOrEmpty(majorVersion) && !versions.Contains($"{majorVersion}.0"))
|
||||||
|
{
|
||||||
|
versions.Add($"{majorVersion}.0");
|
||||||
|
LogHelper.WriteLogToFile($"在Office 365配置中找到报告版本: {majorVersion}.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查安装路径来确认版本
|
||||||
|
var possibleVersions = new[] { "15.0", "16.0" }; // Office 2013 (15.0) 和 Office 2016/2019/365 (16.0)
|
||||||
|
foreach (var version in possibleVersions)
|
||||||
|
{
|
||||||
|
using (var key = Registry.LocalMachine.OpenSubKey($"Software\\Microsoft\\Office\\{version}\\Common\\InstallRoot"))
|
||||||
|
{
|
||||||
|
if (key != null && key.GetValue("Path") != null && !versions.Contains(version))
|
||||||
|
{
|
||||||
|
versions.Add(version);
|
||||||
|
LogHelper.WriteLogToFile($"在InstallRoot中找到Office版本: {version}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"检查Office 365版本时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 尝试修改Office 365的特殊注册表路径
|
||||||
|
/// </summary>
|
||||||
|
private void TryModifyOffice365Registry()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 准备备份目录
|
||||||
|
string backupPath = Path.Combine(RootPath, "saves", "RegistryBackups");
|
||||||
|
if (!Directory.Exists(backupPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(backupPath);
|
||||||
|
LogHelper.WriteLogToFile($"创建Office 365备份目录: {backupPath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查Office 365 Outlook和PowerPoint的特定路径
|
||||||
|
string[] apps = { "outlook", "powerpoint" };
|
||||||
|
|
||||||
|
foreach (var app in apps)
|
||||||
|
{
|
||||||
|
// 检查用户级别的注册表
|
||||||
|
string regPath = $"Software\\Microsoft\\Office\\16.0\\{app}\\Security";
|
||||||
|
LogHelper.WriteLogToFile($"检查Office 365特定应用注册表: {regPath}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 先检查是否存在该路径
|
||||||
|
using (var baseKey = Registry.CurrentUser.OpenSubKey(regPath))
|
||||||
|
{
|
||||||
|
// 如果路径存在,先备份
|
||||||
|
if (baseKey != null)
|
||||||
|
{
|
||||||
|
string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_{app}_{DateTime.Now:yyyyMMddHHmmss}.reg");
|
||||||
|
LogHelper.WriteLogToFile($"创建Office 365 {app}备份文件: {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($"备份Office 365 {app}注册表值: {valueName} = {value}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改或创建注册表项
|
||||||
|
using (var key = Registry.CurrentUser.CreateSubKey(regPath, true))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
object currentValue = key.GetValue("DisableProtectedView");
|
||||||
|
if (currentValue == null || (int)currentValue != 1)
|
||||||
|
{
|
||||||
|
key.SetValue("DisableProtectedView", 1, RegistryValueKind.DWord);
|
||||||
|
LogHelper.WriteLogToFile($"Office 365 {app} 注册表值已设置: DisableProtectedView = 1");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"Office 365 {app} 注册表值已存在且无需更改");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"修改 {app} 注册表时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试通过Office信任中心路径修改
|
||||||
|
string trustCenterPath = "Software\\Microsoft\\Office\\16.0\\Common\\Security\\FileValidation";
|
||||||
|
LogHelper.WriteLogToFile($"检查信任中心路径: {trustCenterPath}");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 先检查是否存在该路径
|
||||||
|
using (var baseKey = Registry.CurrentUser.OpenSubKey(trustCenterPath))
|
||||||
|
{
|
||||||
|
// 如果路径存在,先备份
|
||||||
|
if (baseKey != null)
|
||||||
|
{
|
||||||
|
string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_TrustCenter_{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}\\{trustCenterPath}]");
|
||||||
|
|
||||||
|
foreach (string valueName in baseKey.GetValueNames())
|
||||||
|
{
|
||||||
|
object value = baseKey.GetValue(valueName);
|
||||||
|
sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}");
|
||||||
|
LogHelper.WriteLogToFile($"备份信任中心注册表值: {valueName} = {value}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var key = Registry.CurrentUser.CreateSubKey(trustCenterPath, true))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
key.SetValue("DisableEditFromPV", 1, RegistryValueKind.DWord);
|
||||||
|
LogHelper.WriteLogToFile("已禁用受保护视图中的编辑");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"修改信任中心路径时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试修改EnableEditWhileViewingPolicy
|
||||||
|
string policyPath = "Software\\Policies\\Microsoft\\Office\\16.0\\Common\\Security";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 先检查是否存在该路径
|
||||||
|
using (var baseKey = Registry.CurrentUser.OpenSubKey(policyPath))
|
||||||
|
{
|
||||||
|
// 如果路径存在,先备份
|
||||||
|
if (baseKey != null)
|
||||||
|
{
|
||||||
|
string backupFile = Path.Combine(backupPath, $"SecurityBackup_365_Policy_{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}\\{policyPath}]");
|
||||||
|
|
||||||
|
foreach (string valueName in baseKey.GetValueNames())
|
||||||
|
{
|
||||||
|
object value = baseKey.GetValue(valueName);
|
||||||
|
sw.WriteLine($"\"{valueName}\"=dword:{((int)value):x8}");
|
||||||
|
LogHelper.WriteLogToFile($"备份策略注册表值: {valueName} = {value}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var key = Registry.CurrentUser.CreateSubKey(policyPath, true))
|
||||||
|
{
|
||||||
|
if (key != null)
|
||||||
|
{
|
||||||
|
key.SetValue("EnableEditWhileViewingPolicy", 1, RegistryValueKind.DWord);
|
||||||
|
LogHelper.WriteLogToFile("已启用查看时编辑策略");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"修改策略路径时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"修改Office 365注册表时发生未知错误: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,44 @@ namespace Ink_Canvas.Helpers
|
|||||||
[DllImport("user32.dll")]
|
[DllImport("user32.dll")]
|
||||||
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
||||||
|
|
||||||
|
[DllImport("shell32.dll")]
|
||||||
|
private static extern IntPtr SHAppBarMessage(uint dwMessage, ref APPBARDATA pData);
|
||||||
|
|
||||||
|
[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
|
||||||
|
{
|
||||||
|
public int cbSize;
|
||||||
|
public IntPtr hWnd;
|
||||||
|
public uint uCallbackMessage;
|
||||||
|
public uint uEdge;
|
||||||
|
public RECT rc;
|
||||||
|
public IntPtr lParam;
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct RECT {
|
public struct RECT {
|
||||||
public int Left;
|
public int Left;
|
||||||
@@ -34,6 +72,72 @@ namespace Ink_Canvas.Helpers
|
|||||||
public int Height => Bottom - Top;
|
public int Height => Bottom - Top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取Windows任务栏的高度(仅计算任务栏,不包括其他应用的停靠栏)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="screen">当前屏幕</param>
|
||||||
|
/// <param name="dpiScaleY">DPI缩放Y值</param>
|
||||||
|
/// <returns>任务栏高度</returns>
|
||||||
|
public static double GetTaskbarHeight(System.Windows.Forms.Screen screen, double dpiScaleY)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 创建APPBARDATA结构
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
// 获取当前屏幕的工作区
|
||||||
|
RECT workArea = new RECT();
|
||||||
|
SystemParametersInfo(SPI_GETWORKAREA, 0, Marshal.AllocHGlobal(Marshal.SizeOf(workArea)), 0);
|
||||||
|
|
||||||
|
// 根据任务栏位置计算高度
|
||||||
|
int taskbarHeight = 0;
|
||||||
|
|
||||||
|
// 任务栏的uEdge: 0=左, 1=上, 2=右, 3=下
|
||||||
|
switch (abd.uEdge)
|
||||||
|
{
|
||||||
|
case 1: // 上
|
||||||
|
taskbarHeight = abd.rc.Height;
|
||||||
|
break;
|
||||||
|
case 3: // 下
|
||||||
|
taskbarHeight = abd.rc.Height;
|
||||||
|
break;
|
||||||
|
case 0: // 左
|
||||||
|
case 2: // 右
|
||||||
|
// 水平任务栏不影响高度
|
||||||
|
taskbarHeight = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 考虑DPI缩放
|
||||||
|
return taskbarHeight / dpiScaleY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"获取任务栏高度出错: {ex.Message}");
|
||||||
|
LogHelper.WriteLogToFile($"获取任务栏高度出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果获取失败,回退到通用方法
|
||||||
|
return (screen.Bounds.Height - screen.WorkingArea.Height) / dpiScaleY;
|
||||||
|
}
|
||||||
|
|
||||||
public static string WindowTitle() {
|
public static string WindowTitle() {
|
||||||
IntPtr foregroundWindowHandle = GetForegroundWindow();
|
IntPtr foregroundWindowHandle = GetForegroundWindow();
|
||||||
|
|
||||||
|
|||||||
@@ -226,7 +226,7 @@
|
|||||||
<ui:SimpleStackPanel VerticalAlignment="Center">
|
<ui:SimpleStackPanel VerticalAlignment="Center">
|
||||||
<TextBlock Foreground="#fafafa" HorizontalAlignment="Center"
|
<TextBlock Foreground="#fafafa" HorizontalAlignment="Center"
|
||||||
VerticalAlignment="Center" FontSize="15" Margin="0,0,0,10"
|
VerticalAlignment="Center" FontSize="15" Margin="0,0,0,10"
|
||||||
Text="开发中..." />
|
Text="开发中...请不要点击,可能会导致ICC异常崩溃" />
|
||||||
<ui:SimpleStackPanel Spacing="5">
|
<ui:SimpleStackPanel Spacing="5">
|
||||||
<ui:SimpleStackPanel Spacing="5" Orientation="Horizontal"
|
<ui:SimpleStackPanel Spacing="5" Orientation="Horizontal"
|
||||||
HorizontalAlignment="Center">
|
HorizontalAlignment="Center">
|
||||||
@@ -1965,6 +1965,15 @@
|
|||||||
FontWeight="Bold"
|
FontWeight="Bold"
|
||||||
Toggled="ToggleSwitchDisplayRandWindowNamesInputBtn_OnToggled" />
|
Toggled="ToggleSwitchDisplayRandWindowNamesInputBtn_OnToggled" />
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<TextBlock Foreground="#fafafa" Text="启用随机抽和单次抽按钮"
|
||||||
|
VerticalAlignment="Center" FontSize="14" Margin="0,0,16,0" />
|
||||||
|
<ui:ToggleSwitch OnContent="" OffContent=""
|
||||||
|
Name="ToggleSwitchShowRandomAndSingleDraw"
|
||||||
|
IsOn="True" FontFamily="Microsoft YaHei UI"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Toggled="ToggleSwitchShowRandomAndSingleDraw_Toggled" />
|
||||||
|
</ui:SimpleStackPanel>
|
||||||
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
<Line HorizontalAlignment="Center" X1="0" Y1="0" X2="400" Y2="0"
|
||||||
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
Stroke="#3f3f46" StrokeThickness="1" Margin="0,4,0,4" />
|
||||||
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
<ui:SimpleStackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
@@ -2381,7 +2390,7 @@
|
|||||||
<Grid Name="GridTransparencyFakeBackground" Opacity="0" />
|
<Grid Name="GridTransparencyFakeBackground" Opacity="0" />
|
||||||
<Label Name="Label" Visibility="Collapsed" Foreground="Gray" Content="0" />
|
<Label Name="Label" Visibility="Collapsed" Foreground="Gray" Content="0" />
|
||||||
<Grid Name="InkCanvasGridForInkReplay">
|
<Grid Name="InkCanvasGridForInkReplay">
|
||||||
<InkCanvas x:Name="inkCanvas" ForceCursor="False"
|
<InkCanvas x:Name="inkCanvas" ForceCursor="True" UseCustomCursor="True"
|
||||||
TouchUp="Main_Grid_TouchUp" TouchDown="Main_Grid_TouchDown"
|
TouchUp="Main_Grid_TouchUp" TouchDown="Main_Grid_TouchDown"
|
||||||
TouchMove="inkCanvas_TouchMove"
|
TouchMove="inkCanvas_TouchMove"
|
||||||
ManipulationDelta="Main_Grid_ManipulationDelta"
|
ManipulationDelta="Main_Grid_ManipulationDelta"
|
||||||
@@ -4386,7 +4395,7 @@
|
|||||||
<Label Content="计时器" FontSize="8"
|
<Label Content="计时器" FontSize="8"
|
||||||
HorizontalAlignment="Center" />
|
HorizontalAlignment="Center" />
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
<ui:SimpleStackPanel MouseDown="Border_MouseDown"
|
<ui:SimpleStackPanel x:Name="RandomDrawPanel" Visibility="Collapsed" MouseDown="Border_MouseDown"
|
||||||
MouseUp="SymbolIconRand_MouseUp"
|
MouseUp="SymbolIconRand_MouseUp"
|
||||||
Margin="0,0,0,0" Height="38" Width="32"
|
Margin="0,0,0,0" Height="38" Width="32"
|
||||||
Orientation="Vertical">
|
Orientation="Vertical">
|
||||||
@@ -4406,7 +4415,7 @@
|
|||||||
<Label Content="随机抽" FontSize="8"
|
<Label Content="随机抽" FontSize="8"
|
||||||
HorizontalAlignment="Center" />
|
HorizontalAlignment="Center" />
|
||||||
</ui:SimpleStackPanel>
|
</ui:SimpleStackPanel>
|
||||||
<ui:SimpleStackPanel MouseDown="Border_MouseDown"
|
<ui:SimpleStackPanel x:Name="SingleDrawPanel" Visibility="Collapsed" MouseDown="Border_MouseDown"
|
||||||
MouseUp="SymbolIconRandOne_MouseUp"
|
MouseUp="SymbolIconRandOne_MouseUp"
|
||||||
Margin="0,0,0,0" Height="38" Width="32"
|
Margin="0,0,0,0" Height="38" Width="32"
|
||||||
Orientation="Vertical">
|
Orientation="Vertical">
|
||||||
|
|||||||
@@ -154,16 +154,11 @@ namespace Ink_Canvas {
|
|||||||
private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) {
|
private void inkCanvas_EditingModeChanged(object sender, RoutedEventArgs e) {
|
||||||
var inkCanvas1 = sender as InkCanvas;
|
var inkCanvas1 = sender as InkCanvas;
|
||||||
if (inkCanvas1 == null) return;
|
if (inkCanvas1 == null) return;
|
||||||
// 修复“显示画笔光标”选项不可用的问题
|
// 修复"显示画笔光标"选项不可用的问题
|
||||||
if (Settings.Canvas.IsShowCursor) {
|
if (Settings.Canvas.IsShowCursor) {
|
||||||
inkCanvas1.UseCustomCursor = true;
|
inkCanvas1.UseCustomCursor = true;
|
||||||
// 修复触屏和数位笔时光标不显示:只要有输入设备悬停、捕获,或有任何Stylus设备连接就显示
|
// 修复触屏和数位笔时光标不显示:强制显示光标,不再依赖鼠标或触控状态
|
||||||
if ((inkCanvas1.EditingMode == InkCanvasEditingMode.Ink || drawingShapeMode != 0)
|
inkCanvas1.ForceCursor = true;
|
||||||
&& (inkCanvas1.IsStylusDirectlyOver || inkCanvas1.IsMouseDirectlyOver || inkCanvas1.IsStylusCaptured || inkCanvas1.IsMouseCaptured
|
|
||||||
|| Stylus.CurrentStylusDevice != null))
|
|
||||||
inkCanvas1.ForceCursor = true;
|
|
||||||
else
|
|
||||||
inkCanvas1.ForceCursor = false;
|
|
||||||
} else {
|
} else {
|
||||||
inkCanvas1.UseCustomCursor = false;
|
inkCanvas1.UseCustomCursor = false;
|
||||||
inkCanvas1.ForceCursor = false;
|
inkCanvas1.ForceCursor = false;
|
||||||
@@ -292,8 +287,8 @@ namespace Ink_Canvas {
|
|||||||
|
|
||||||
[DllImport("user32.dll", SetLastError = true)]
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
|
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
|
||||||
|
|
||||||
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) {
|
private void MainWindow_OnSizeChanged(object sender, SizeChangedEventArgs e) {
|
||||||
if (Settings.Advanced.IsEnableForceFullScreen) {
|
if (Settings.Advanced.IsEnableForceFullScreen) {
|
||||||
if (isLoaded) ShowNotification(
|
if (isLoaded) ShowNotification(
|
||||||
$"检测到窗口大小变化,已自动恢复到全屏:{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}(缩放比例为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight})");
|
$"检测到窗口大小变化,已自动恢复到全屏:{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height}(缩放比例为{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth}x{System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight})");
|
||||||
@@ -361,16 +356,38 @@ namespace Ink_Canvas {
|
|||||||
inkCanvas.Cursor = new Cursor(sri.Stream);
|
inkCanvas.Cursor = new Cursor(sri.Stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触摸输入,通常隐藏光标
|
// 触摸输入,不隐藏光标
|
||||||
private void inkCanvas_TouchDown(object sender, TouchEventArgs e)
|
private void inkCanvas_TouchDown(object sender, TouchEventArgs e)
|
||||||
{
|
{
|
||||||
System.Windows.Forms.Cursor.Show();
|
// 修改:根据用户设置决定是否强制显示自定义光标
|
||||||
|
if (Settings.Canvas.IsShowCursor)
|
||||||
|
{
|
||||||
|
inkCanvas.ForceCursor = true;
|
||||||
|
// 确保鼠标光标对触摸可见
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
// 新增:当处于套索选择模式时保持光标可见
|
||||||
|
if (inkCanvas.EditingMode == InkCanvasEditingMode.Select)
|
||||||
|
inkCanvas.Cursor = Cursors.Cross;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inkCanvas.ForceCursor = false;
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触摸结束,恢复光标
|
// 触摸结束,恢复光标
|
||||||
private void inkCanvas_TouchUp(object sender, TouchEventArgs e)
|
private void inkCanvas_TouchUp(object sender, TouchEventArgs e)
|
||||||
{
|
{
|
||||||
System.Windows.Forms.Cursor.Show();
|
// 修改:根据当前模式和设置恢复光标状态
|
||||||
|
if (Settings.Canvas.IsShowCursor) {
|
||||||
|
inkCanvas.ForceCursor = true;
|
||||||
|
// 确保鼠标光标对触摸可见
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
} else {
|
||||||
|
inkCanvas.ForceCursor = false;
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Definations and Loading
|
#endregion Definations and Loading
|
||||||
|
|||||||
@@ -740,9 +740,11 @@ namespace Ink_Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void SymbolIconRand_MouseUp(object sender, MouseButtonEventArgs e) {
|
private void SymbolIconRand_MouseUp(object sender, MouseButtonEventArgs e) {
|
||||||
|
// 如果控件被隐藏,不处理事件
|
||||||
|
if (RandomDrawPanel.Visibility != Visibility.Visible) return;
|
||||||
|
|
||||||
LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||||
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||||
//if (lastBorderMouseDownObject != sender) return;
|
|
||||||
|
|
||||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||||
@@ -808,14 +810,16 @@ namespace Ink_Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void SymbolIconRandOne_MouseUp(object sender, MouseButtonEventArgs e) {
|
private void SymbolIconRandOne_MouseUp(object sender, MouseButtonEventArgs e) {
|
||||||
|
// 如果控件被隐藏,不处理事件
|
||||||
|
if (SingleDrawPanel.Visibility != Visibility.Visible) return;
|
||||||
|
|
||||||
LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
LeftUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||||
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
RightUnFoldButtonQuickPanel.Visibility = Visibility.Collapsed;
|
||||||
//if (lastBorderMouseDownObject != sender) return;
|
|
||||||
|
|
||||||
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
AnimationsHelper.HideWithSlideAndFade(BorderTools);
|
||||||
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
AnimationsHelper.HideWithSlideAndFade(BoardBorderTools);
|
||||||
|
|
||||||
new RandWindow(Settings,true).ShowDialog();
|
new RandWindow(Settings, true).ShowDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) {
|
private void GridInkReplayButton_MouseUp(object sender, MouseButtonEventArgs e) {
|
||||||
@@ -1074,15 +1078,38 @@ namespace Ink_Canvas {
|
|||||||
var windowHandle = new WindowInteropHelper(this).Handle;
|
var windowHandle = new WindowInteropHelper(this).Handle;
|
||||||
var screen = System.Windows.Forms.Screen.FromHandle(windowHandle);
|
var screen = System.Windows.Forms.Screen.FromHandle(windowHandle);
|
||||||
double screenWidth = screen.Bounds.Width / dpiScaleX, screenHeight = screen.Bounds.Height / dpiScaleY;
|
double screenWidth = screen.Bounds.Width / dpiScaleX, screenHeight = screen.Bounds.Height / dpiScaleY;
|
||||||
var toolbarHeight = SystemParameters.PrimaryScreenHeight - SystemParameters.FullPrimaryScreenHeight -
|
// 仅计算Windows任务栏高度,不考虑其他程序对工作区的影响
|
||||||
SystemParameters.WindowCaptionHeight;
|
var toolbarHeight = ForegroundWindowInfo.GetTaskbarHeight(screen, dpiScaleY);
|
||||||
pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2;
|
pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2;
|
||||||
|
|
||||||
if (PosXCaculatedWithTaskbarHeight == false)
|
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)
|
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 (MarginFromEdge != -60) {
|
||||||
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) {
|
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) {
|
||||||
@@ -1137,12 +1164,22 @@ namespace Ink_Canvas {
|
|||||||
var windowHandle = new WindowInteropHelper(this).Handle;
|
var windowHandle = new WindowInteropHelper(this).Handle;
|
||||||
var screen = System.Windows.Forms.Screen.FromHandle(windowHandle);
|
var screen = System.Windows.Forms.Screen.FromHandle(windowHandle);
|
||||||
double screenWidth = screen.Bounds.Width / dpiScaleX, screenHeight = screen.Bounds.Height / dpiScaleY;
|
double screenWidth = screen.Bounds.Width / dpiScaleX, screenHeight = screen.Bounds.Height / dpiScaleY;
|
||||||
var toolbarHeight = SystemParameters.PrimaryScreenHeight - SystemParameters.FullPrimaryScreenHeight -
|
// 仅计算Windows任务栏高度,不考虑其他程序对工作区的影响
|
||||||
SystemParameters.WindowCaptionHeight;
|
var toolbarHeight = ForegroundWindowInfo.GetTaskbarHeight(screen, dpiScaleY);
|
||||||
pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2;
|
pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2;
|
||||||
|
|
||||||
pos.Y = screenHeight - ViewboxFloatingBar.ActualHeight * ViewboxFloatingBarScaleTransform.ScaleY -
|
// 如果任务栏高度为0(隐藏状态),则使用固定边距
|
||||||
toolbarHeight - ViewboxFloatingBarScaleTransform.ScaleY * 3;
|
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;
|
if (pointDesktop.X != -1 || pointDesktop.Y != -1) pointDesktop = pos;
|
||||||
|
|
||||||
@@ -1180,8 +1217,8 @@ namespace Ink_Canvas {
|
|||||||
var windowHandle = new WindowInteropHelper(this).Handle;
|
var windowHandle = new WindowInteropHelper(this).Handle;
|
||||||
var screen = System.Windows.Forms.Screen.FromHandle(windowHandle);
|
var screen = System.Windows.Forms.Screen.FromHandle(windowHandle);
|
||||||
double screenWidth = screen.Bounds.Width / dpiScaleX, screenHeight = screen.Bounds.Height / dpiScaleY;
|
double screenWidth = screen.Bounds.Width / dpiScaleX, screenHeight = screen.Bounds.Height / dpiScaleY;
|
||||||
var toolbarHeight = SystemParameters.PrimaryScreenHeight - SystemParameters.FullPrimaryScreenHeight -
|
// 仅计算Windows任务栏高度,不考虑其他程序对工作区的影响
|
||||||
SystemParameters.WindowCaptionHeight;
|
var toolbarHeight = ForegroundWindowInfo.GetTaskbarHeight(screen, dpiScaleY);
|
||||||
pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2;
|
pos.X = (screenWidth - ViewboxFloatingBar.ActualWidth * ViewboxFloatingBarScaleTransform.ScaleX) / 2;
|
||||||
|
|
||||||
pos.Y = screenHeight - 55 * ViewboxFloatingBarScaleTransform.ScaleY;
|
pos.Y = screenHeight - 55 * ViewboxFloatingBarScaleTransform.ScaleY;
|
||||||
@@ -1585,7 +1622,7 @@ namespace Ink_Canvas {
|
|||||||
|
|
||||||
public void BtnRestart_Click(object sender, RoutedEventArgs e) {
|
public void BtnRestart_Click(object sender, RoutedEventArgs e) {
|
||||||
Process.Start(System.Windows.Forms.Application.ExecutablePath, "-m");
|
Process.Start(System.Windows.Forms.Application.ExecutablePath, "-m");
|
||||||
|
App.IsAppExitByUser = true;
|
||||||
CloseIsFromButton = true;
|
CloseIsFromButton = true;
|
||||||
Application.Current.Shutdown();
|
Application.Current.Shutdown();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using System.Windows.Ink;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
using Microsoft.Win32;
|
||||||
using Application = System.Windows.Application;
|
using Application = System.Windows.Application;
|
||||||
using File = System.IO.File;
|
using File = System.IO.File;
|
||||||
using MessageBox = System.Windows.MessageBox;
|
using MessageBox = System.Windows.MessageBox;
|
||||||
@@ -86,6 +87,61 @@ namespace Ink_Canvas {
|
|||||||
|
|
||||||
Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn;
|
Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn;
|
||||||
SaveSettingsToFile();
|
SaveSettingsToFile();
|
||||||
|
|
||||||
|
// 重置PowerPoint/WPS实例状态
|
||||||
|
ResetPresentationObjects();
|
||||||
|
isPowerPointInitialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置所有演示相关的COM对象
|
||||||
|
/// </summary>
|
||||||
|
private void ResetPresentationObjects()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 清理对象引用
|
||||||
|
if (pptApplication != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 尝试解除事件绑定
|
||||||
|
pptApplication.PresentationOpen -= PptApplication_PresentationOpen;
|
||||||
|
pptApplication.PresentationClose -= PptApplication_PresentationClose;
|
||||||
|
pptApplication.SlideShowBegin -= PptApplication_SlideShowBegin;
|
||||||
|
pptApplication.SlideShowNextSlide -= PptApplication_SlideShowNextSlide;
|
||||||
|
pptApplication.SlideShowEnd -= PptApplication_SlideShowEnd;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
|
||||||
|
try { Marshal.ReleaseComObject(pptApplication); } catch { }
|
||||||
|
pptApplication = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (presentation != null)
|
||||||
|
{
|
||||||
|
try { Marshal.ReleaseComObject(presentation); } catch { }
|
||||||
|
presentation = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slides != null)
|
||||||
|
{
|
||||||
|
try { Marshal.ReleaseComObject(slides); } catch { }
|
||||||
|
slides = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
slide = null;
|
||||||
|
|
||||||
|
// 强制GC回收
|
||||||
|
GC.Collect();
|
||||||
|
GC.WaitForPendingFinalizers();
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile("成功重置所有演示对象", LogHelper.LogType.Info);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"重置演示对象时出错: {ex.Message}", LogHelper.LogType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool isWPSSupportOn => Settings.PowerPointSettings.IsSupportWPS;
|
private static bool isWPSSupportOn => Settings.PowerPointSettings.IsSupportWPS;
|
||||||
@@ -93,8 +149,32 @@ namespace Ink_Canvas {
|
|||||||
public static bool IsShowingRestoreHiddenSlidesWindow = false;
|
public static bool IsShowingRestoreHiddenSlidesWindow = false;
|
||||||
private static bool IsShowingAutoplaySlidesWindow = false;
|
private static bool IsShowingAutoplaySlidesWindow = false;
|
||||||
private bool isPowerPointInitialized = false;
|
private bool isPowerPointInitialized = false;
|
||||||
|
private bool isWPSMode = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有可能的WPS进程名
|
||||||
|
/// </summary>
|
||||||
|
private string[] GetPossibleWPSProcessNames()
|
||||||
|
{
|
||||||
|
return new[] { "wpp", "wppmain", "wps", "et" };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 检查WPS进程是否正在运行
|
||||||
|
/// </summary>
|
||||||
|
private bool IsWPSRunning()
|
||||||
|
{
|
||||||
|
foreach (var processName in GetPossibleWPSProcessNames())
|
||||||
|
{
|
||||||
|
var processes = Process.GetProcessesByName(processName);
|
||||||
|
if (processes.Length > 0)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"检测到WPS进程: {processName}", LogHelper.LogType.Info);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void TimerCheckPPT_Elapsed(object sender, ElapsedEventArgs e)
|
private void TimerCheckPPT_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -107,19 +187,44 @@ namespace Ink_Canvas {
|
|||||||
// 检查是否已有初始化的 PowerPoint 实例
|
// 检查是否已有初始化的 PowerPoint 实例
|
||||||
if (!isPowerPointInitialized)
|
if (!isPowerPointInitialized)
|
||||||
{
|
{
|
||||||
// 优先检测WPS进程
|
// 检测WPS和PowerPoint进程
|
||||||
var wpsProcesses = Process.GetProcessesByName("wpp");
|
bool wpsRunning = IsWPSRunning();
|
||||||
var pptProcesses = Process.GetProcessesByName("POWERPNT");
|
var pptProcesses = Process.GetProcessesByName("POWERPNT");
|
||||||
|
|
||||||
|
// 根据设置和进程状态决定模式
|
||||||
|
isWPSMode = isWPSSupportOn && wpsRunning;
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile($"初始化模式: {(isWPSMode ? "WPS" : "PowerPoint")}", LogHelper.LogType.Info);
|
||||||
|
|
||||||
// 优先获取WPS实例
|
// 优先获取WPS实例
|
||||||
if (isWPSSupportOn && wpsProcesses.Length > 0)
|
if (isWPSMode)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("wpp.Application");
|
// 尝试多种可能的ProgID
|
||||||
|
string[] possibleProgIds = { "wpp.Application", "WPS.Application" };
|
||||||
|
|
||||||
|
foreach (var progId in possibleProgIds)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"尝试获取COM对象: {progId}", LogHelper.LogType.Info);
|
||||||
|
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject(progId);
|
||||||
|
if (pptApplication != null)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"成功连接到WPS: {progId}", LogHelper.LogType.Info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (COMException)
|
catch (COMException ex)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"获取WPS实例失败: {ex.Message}", LogHelper.LogType.Error);
|
||||||
pptApplication = null;
|
pptApplication = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,74 +234,71 @@ namespace Ink_Canvas {
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile("尝试获取PowerPoint实例", LogHelper.LogType.Info);
|
||||||
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("PowerPoint.Application");
|
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("PowerPoint.Application");
|
||||||
|
if (pptApplication != null)
|
||||||
|
LogHelper.WriteLogToFile("成功连接到PowerPoint", LogHelper.LogType.Info);
|
||||||
}
|
}
|
||||||
catch (COMException)
|
catch (COMException ex)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"获取PowerPoint实例失败: {ex.Message}", LogHelper.LogType.Error);
|
||||||
pptApplication = null;
|
pptApplication = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果都没有找到,且未启用WPS支持,则自动创建PowerPoint进程
|
// 如果都没有找到,且未启用WPS支持,则自动创建PowerPoint进程
|
||||||
if (pptApplication == null && !isWPSSupportOn)
|
if (pptApplication == null && !isWPSMode && pptProcesses.Length == 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile("尝试创建新的PowerPoint实例", LogHelper.LogType.Info);
|
||||||
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Activator.CreateInstance(
|
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Activator.CreateInstance(
|
||||||
Marshal.GetTypeFromCLSID(new Guid("91493441-5A91-11CF-8700-00AA0060263B")));
|
Marshal.GetTypeFromCLSID(new Guid("91493441-5A91-11CF-8700-00AA0060263B")));
|
||||||
|
if (pptApplication != null)
|
||||||
|
LogHelper.WriteLogToFile("成功创建PowerPoint实例", LogHelper.LogType.Info);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile($"创建PowerPoint实例失败: {ex.Message}", LogHelper.LogType.Error);
|
||||||
pptApplication = null;
|
pptApplication = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isPowerPointInitialized = true;
|
isPowerPointInitialized = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查进程是否还在
|
// 检查进程是否还在
|
||||||
var pptProcessesCheck = Process.GetProcessesByName("POWERPNT");
|
bool currentWpsRunning = IsWPSRunning();
|
||||||
var wpsProcessesCheck = Process.GetProcessesByName("wpp");
|
var currentPptProcesses = Process.GetProcessesByName("POWERPNT");
|
||||||
bool isWpsMode = isWPSSupportOn && wpsProcessesCheck.Length > 0;
|
|
||||||
bool isPptMode = !isWPSSupportOn && pptProcessesCheck.Length > 0;
|
// 检测应用程序是否关闭
|
||||||
|
bool applicationClosed = isWPSMode ? !currentWpsRunning : currentPptProcesses.Length == 0;
|
||||||
|
|
||||||
if ((isWpsMode && wpsProcessesCheck.Length == 0) || (!isWpsMode && pptProcessesCheck.Length == 0))
|
if (applicationClosed)
|
||||||
{
|
{
|
||||||
// 进程已关闭,清理对象
|
LogHelper.WriteLogToFile($"{(isWPSMode ? "WPS" : "PowerPoint")}进程已关闭,清理对象", LogHelper.LogType.Info);
|
||||||
if (pptApplication != null)
|
|
||||||
{
|
// 进程已关闭,调用重置方法清理对象
|
||||||
try { Marshal.ReleaseComObject(pptApplication); } catch { }
|
ResetPresentationObjects();
|
||||||
pptApplication = null;
|
|
||||||
}
|
|
||||||
if (presentation != null)
|
|
||||||
{
|
|
||||||
try { Marshal.ReleaseComObject(presentation); } catch { }
|
|
||||||
presentation = null;
|
|
||||||
}
|
|
||||||
if (slides != null)
|
|
||||||
{
|
|
||||||
try { Marshal.ReleaseComObject(slides); } catch { }
|
|
||||||
slides = null;
|
|
||||||
}
|
|
||||||
slide = null;
|
|
||||||
isPowerPointInitialized = false;
|
isPowerPointInitialized = false;
|
||||||
|
|
||||||
// PowerPoint进程守护:自动重启PowerPoint进程(仅在未启用WPS支持时)
|
// PowerPoint进程守护:自动重启PowerPoint进程(仅在未启用WPS支持时)
|
||||||
if (!isWPSSupportOn)
|
if (!isWPSSupportOn && !isWPSMode)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
LogHelper.WriteLogToFile("尝试重启PowerPoint进程", LogHelper.LogType.Info);
|
||||||
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Activator.CreateInstance(
|
pptApplication = (Microsoft.Office.Interop.PowerPoint.Application)Activator.CreateInstance(
|
||||||
Marshal.GetTypeFromCLSID(new Guid("91493441-5A91-11CF-8700-00AA0060263B")));
|
Marshal.GetTypeFromCLSID(new Guid("91493441-5A91-11CF-8700-00AA0060263B")));
|
||||||
isPowerPointInitialized = true;
|
isPowerPointInitialized = true;
|
||||||
|
LogHelper.WriteLogToFile("PowerPoint进程重启成功", LogHelper.LogType.Info);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile("PowerPoint 守护重启失败: " + ex.ToString(), LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"PowerPoint守护重启失败: {ex.Message}", LogHelper.LogType.Error);
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
// 启用WPS支持时不守护PowerPoint进程
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
using iNKORE.UI.WPF.Modern.Controls;
|
using iNKORE.UI.WPF.Modern.Controls;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
@@ -17,6 +17,13 @@ namespace Ink_Canvas {
|
|||||||
private object lastBorderMouseDownObject;
|
private object lastBorderMouseDownObject;
|
||||||
|
|
||||||
private void Border_MouseDown(object sender, MouseButtonEventArgs e) {
|
private void Border_MouseDown(object sender, MouseButtonEventArgs e) {
|
||||||
|
// 如果发送者是 RandomDrawPanel 或 SingleDrawPanel,且它们被隐藏,则不处理事件
|
||||||
|
if (sender is SimpleStackPanel panel) {
|
||||||
|
if ((panel == RandomDrawPanel || panel == SingleDrawPanel) &&
|
||||||
|
panel.Visibility != Visibility.Visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
lastBorderMouseDownObject = sender;
|
lastBorderMouseDownObject = sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -380,6 +387,11 @@ namespace Ink_Canvas {
|
|||||||
isProgramChangeStrokeSelection = false;
|
isProgramChangeStrokeSelection = false;
|
||||||
inkCanvas.Strokes.Add(StrokesSelectionClone);
|
inkCanvas.Strokes.Add(StrokesSelectionClone);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// 新增:启动套索选择模式
|
||||||
|
inkCanvas.EditingMode = InkCanvasEditingMode.Select;
|
||||||
|
inkCanvas.Select(new StrokeCollection());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1690,6 +1690,21 @@ namespace Ink_Canvas {
|
|||||||
SaveSettingsToFile();
|
SaveSettingsToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ToggleSwitchShowRandomAndSingleDraw_Toggled(object sender, RoutedEventArgs e) {
|
||||||
|
if (!isLoaded) return;
|
||||||
|
|
||||||
|
// 获取开关状态并保存到设置中
|
||||||
|
bool isToggled = ToggleSwitchShowRandomAndSingleDraw.IsOn;
|
||||||
|
Settings.RandSettings.ShowRandomAndSingleDraw = isToggled;
|
||||||
|
|
||||||
|
// 更新UI显示
|
||||||
|
RandomDrawPanel.Visibility = isToggled ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
SingleDrawPanel.Visibility = isToggled ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
|
||||||
|
// 保存设置到文件
|
||||||
|
SaveSettingsToFile();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static void SaveSettingsToFile() {
|
public static void SaveSettingsToFile() {
|
||||||
|
|||||||
@@ -569,7 +569,14 @@ namespace Ink_Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RandSettings
|
// RandSettings
|
||||||
if (Settings.RandSettings != null) { } else {
|
if (Settings.RandSettings != null) {
|
||||||
|
ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn;
|
||||||
|
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
||||||
|
RandWindowOnceMaxStudentsSlider.Value = Settings.RandSettings.RandWindowOnceMaxStudents;
|
||||||
|
ToggleSwitchShowRandomAndSingleDraw.IsOn = Settings.RandSettings.ShowRandomAndSingleDraw;
|
||||||
|
RandomDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
SingleDrawPanel.Visibility = Settings.RandSettings.ShowRandomAndSingleDraw ? Visibility.Visible : Visibility.Collapsed;
|
||||||
|
} else {
|
||||||
Settings.RandSettings = new RandSettings();
|
Settings.RandSettings = new RandSettings();
|
||||||
ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn;
|
ToggleSwitchDisplayRandWindowNamesInputBtn.IsOn = Settings.RandSettings.DisplayRandWindowNamesInputBtn;
|
||||||
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
RandWindowOnceCloseLatencySlider.Value = Settings.RandSettings.RandWindowOnceCloseLatency;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Ink_Canvas {
|
|||||||
#endregion Floating Bar Control
|
#endregion Floating Bar Control
|
||||||
|
|
||||||
private int drawingShapeMode = 0;
|
private int drawingShapeMode = 0;
|
||||||
private bool isLongPressSelected = false; // 用于存是否是“选中”状态,便于后期抬笔后不做切换到笔的处理
|
private bool isLongPressSelected = false; // 用于存是否是"选中"状态,便于后期抬笔后不做切换到笔的处理
|
||||||
|
|
||||||
#region Buttons
|
#region Buttons
|
||||||
|
|
||||||
@@ -429,6 +429,8 @@ namespace Ink_Canvas {
|
|||||||
|
|
||||||
private void inkCanvas_TouchMove(object sender, TouchEventArgs e) {
|
private void inkCanvas_TouchMove(object sender, TouchEventArgs e) {
|
||||||
if (isSingleFingerDragMode) return;
|
if (isSingleFingerDragMode) return;
|
||||||
|
|
||||||
|
// 处理形状绘制模式
|
||||||
if (drawingShapeMode != 0) {
|
if (drawingShapeMode != 0) {
|
||||||
if (isLastTouchEraser) return;
|
if (isLastTouchEraser) return;
|
||||||
//EraserContainer.Background = null;
|
//EraserContainer.Background = null;
|
||||||
@@ -443,15 +445,75 @@ namespace Ink_Canvas {
|
|||||||
catch {
|
catch {
|
||||||
Trace.WriteLine("lastTempStrokeCollection failed.");
|
Trace.WriteLine("lastTempStrokeCollection failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inkCanvas.EditingMode != InkCanvasEditingMode.None)
|
|
||||||
inkCanvas.EditingMode = InkCanvasEditingMode.None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseTouchMove(e.GetTouchPoint(inkCanvas).Position);
|
// 触摸移动时保持自定义光标显示
|
||||||
|
if (Settings.Canvas.IsShowCursor) {
|
||||||
|
inkCanvas.ForceCursor = true;
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NeedUpdateIniP()) iniP = e.GetTouchPoint(inkCanvas).Position;
|
||||||
|
if (drawingShapeMode == 9 && isFirstTouchCuboid == false) MouseTouchMove(iniP);
|
||||||
|
inkCanvas.Opacity = 1;
|
||||||
|
double boundsWidth = GetTouchBoundWidth(e), eraserMultiplier = 1.0;
|
||||||
|
if (!Settings.Advanced.EraserBindTouchMultiplier && Settings.Advanced.IsSpecialScreen)
|
||||||
|
eraserMultiplier = 1 / Settings.Advanced.TouchMultiplier;
|
||||||
|
if (boundsWidth > BoundsWidth) {
|
||||||
|
isLastTouchEraser = true;
|
||||||
|
if (drawingShapeMode == 0 && forceEraser) return;
|
||||||
|
if (boundsWidth > BoundsWidth * 2.5) {
|
||||||
|
double k = 1;
|
||||||
|
switch (Settings.Canvas.EraserSize) {
|
||||||
|
case 0:
|
||||||
|
k = 0.5;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
k = 0.8;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
k = 1.25;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
k = 1.8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
inkCanvas.EraserShape = new EllipseStylusShape(boundsWidth * k * eraserMultiplier,
|
||||||
|
boundsWidth * k * eraserMultiplier);
|
||||||
|
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (StackPanelPPTControls.Visibility == Visibility.Visible && inkCanvas.Strokes.Count == 0 &&
|
||||||
|
Settings.PowerPointSettings.IsEnableFingerGestureSlideShowControl) {
|
||||||
|
isLastTouchEraser = false;
|
||||||
|
inkCanvas.EditingMode = InkCanvasEditingMode.GestureOnly;
|
||||||
|
inkCanvas.Opacity = 0.1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
inkCanvas.EraserShape = new EllipseStylusShape(5, 5);
|
||||||
|
inkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
isLastTouchEraser = false;
|
||||||
|
// 修复面积擦时不显示橡皮形状:无论 forcePointEraser 状态,均显示 50x50 橡皮
|
||||||
|
inkCanvas.EraserShape = new EllipseStylusShape(50, 50);
|
||||||
|
if (forceEraser) return;
|
||||||
|
inkCanvas.EditingMode = InkCanvasEditingMode.Ink;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inkCanvas.EditingMode != InkCanvasEditingMode.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (e.TouchDevice == null) {
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
} else {
|
||||||
|
System.Windows.Forms.Cursor.Hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int drawMultiStepShapeCurrentStep = 0; //多笔完成的图形 当前所处在的笔画
|
private int drawMultiStepShapeCurrentStep = 0; //多笔完成的图形 当前所处在的笔画
|
||||||
|
|||||||
@@ -183,6 +183,11 @@ namespace Ink_Canvas {
|
|||||||
private bool forcePointEraser = true;
|
private bool forcePointEraser = true;
|
||||||
|
|
||||||
private void Main_Grid_TouchDown(object sender, TouchEventArgs e) {
|
private void Main_Grid_TouchDown(object sender, TouchEventArgs e) {
|
||||||
|
// 确保触摸时显示自定义光标
|
||||||
|
if (Settings.Canvas.IsShowCursor) {
|
||||||
|
inkCanvas.ForceCursor = true;
|
||||||
|
System.Windows.Forms.Cursor.Show();
|
||||||
|
}
|
||||||
|
|
||||||
inkCanvas.CaptureTouch(e.TouchDevice);
|
inkCanvas.CaptureTouch(e.TouchDevice);
|
||||||
ViewboxFloatingBar.IsHitTestVisible = false;
|
ViewboxFloatingBar.IsHitTestVisible = false;
|
||||||
|
|||||||
@@ -63,7 +63,11 @@ namespace Ink_Canvas
|
|||||||
|
|
||||||
private void RestartAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) {
|
private void RestartAppTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) {
|
||||||
var mainWin = (MainWindow)Application.Current.MainWindow;
|
var mainWin = (MainWindow)Application.Current.MainWindow;
|
||||||
if (mainWin.IsLoaded) mainWin.BtnRestart_Click(null,null);
|
if (mainWin.IsLoaded) {
|
||||||
|
App.IsAppExitByUser = true;
|
||||||
|
Application.Current.Shutdown();
|
||||||
|
// mainWin.BtnExit_Click(null,null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ForceFullScreenTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) {
|
private void ForceFullScreenTrayIconMenuItem_Clicked(object sender, RoutedEventArgs e) {
|
||||||
|
|||||||
@@ -406,5 +406,7 @@ namespace Ink_Canvas
|
|||||||
public double RandWindowOnceCloseLatency { get; set; } = 2.5;
|
public double RandWindowOnceCloseLatency { get; set; } = 2.5;
|
||||||
[JsonProperty("randWindowOnceMaxStudents")]
|
[JsonProperty("randWindowOnceMaxStudents")]
|
||||||
public int RandWindowOnceMaxStudents { get; set; } = 10;
|
public int RandWindowOnceMaxStudents { get; set; } = 10;
|
||||||
|
[JsonProperty("showRandomAndSingleDraw")]
|
||||||
|
public bool ShowRandomAndSingleDraw { get; set; } = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vendored
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
+1367
-1332
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
|||||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\Administrator\.nuget\packages\;E:\Program Files\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\Administrator\.nuget\packages\;E:\Program Files\Microsoft Visual Studio\Shared\NuGetPackages</NuGetPackageFolders>
|
||||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.13.2</NuGetToolVersion>
|
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.14.0</NuGetToolVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||||
<SourceRoot Include="C:\Users\Administrator\.nuget\packages\" />
|
<SourceRoot Include="C:\Users\Administrator\.nuget\packages\" />
|
||||||
|
|||||||
Reference in New Issue
Block a user