From 86f432ef01a2849f323819bda8ee504b4f2ed70c Mon Sep 17 00:00:00 2001
From: CJKmkp <2564608840@qq.com>
Date: Tue, 29 Jul 2025 01:24:42 +0800
Subject: [PATCH] =?UTF-8?q?improve:PPT=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Ink Canvas/Helpers/PPTManager.cs | 256 +++++++++++++++++++++++++++----
1 file changed, 226 insertions(+), 30 deletions(-)
diff --git a/Ink Canvas/Helpers/PPTManager.cs b/Ink Canvas/Helpers/PPTManager.cs
index 0e511191..23c8767c 100644
--- a/Ink Canvas/Helpers/PPTManager.cs
+++ b/Ink Canvas/Helpers/PPTManager.cs
@@ -908,7 +908,8 @@ namespace Ink_Canvas.Helpers
_wpsProcessCheckTimer.Dispose();
}
- _wpsProcessCheckTimer = new Timer(500);
+ // 优化:增加检查间隔到2秒,减少性能开销
+ _wpsProcessCheckTimer = new Timer(2000);
_wpsProcessCheckTimer.Elapsed += OnWpsProcessCheckTimerElapsed;
_wpsProcessCheckTimer.Start();
LogHelper.WriteLogToFile("启动 WPS 进程检测定时器", LogHelper.LogType.Trace);
@@ -940,50 +941,218 @@ namespace Ink_Canvas.Helpers
return;
}
- // 检查前台WPS窗口是否存在
- bool isForegroundWpsWindowActive = IsForegroundWpsWindowStillActive();
+ // 优化:增加延迟检查,避免误杀
+ if (_wpsProcessCheckCount < 3) // 前6秒不进行查杀检查
+ {
+ LogHelper.WriteLogToFile($"WPS进程查杀延迟中,等待{6 - _wpsProcessCheckCount * 2}秒", LogHelper.LogType.Trace);
+ return;
+ }
+
+ // 检查前台WPS窗口是否存在(优化版)
+ bool isForegroundWpsWindowActive = IsForegroundWpsWindowStillActiveOptimized();
if (isForegroundWpsWindowActive)
{
- if (_wpsProcessCheckCount % 10 == 0)
+ if (_wpsProcessCheckCount % 5 == 0) // 每10秒记录一次日志
{
- LogHelper.WriteLogToFile($"前台WPS窗口仍然存在,继续监控(已检查{_wpsProcessCheckCount}次)", LogHelper.LogType.Trace);
+ LogHelper.WriteLogToFile($"WPS窗口仍然活跃,继续监控(已检查{_wpsProcessCheckCount}次)", LogHelper.LogType.Trace);
}
return;
}
- // 前台窗口已消失,检查是否需要结束进程
- LogHelper.WriteLogToFile("检测到前台WPS窗口已消失", LogHelper.LogType.Event);
-
- // 检查所有WPS文档是否已保存
- bool allSaved = CheckAllWpsDocumentsSaved();
-
- if (!allSaved)
+ // 优化:多重验证确保准确性
+ if (!PerformMultipleWpsWindowChecks())
{
- LogHelper.WriteLogToFile("检测到有未保存的WPS文档,跳过进程结束", LogHelper.LogType.Trace);
+ LogHelper.WriteLogToFile("多重验证显示WPS窗口仍然存在,跳过查杀", LogHelper.LogType.Trace);
+ return;
}
- // 结束WPS进程
+ // 前台窗口已消失,检查是否需要结束进程
+ LogHelper.WriteLogToFile("多重验证确认WPS窗口已消失,准备结束WPS进程", LogHelper.LogType.Event);
+
+ // 检查文档保存状态
+ if (!CheckAllWpsDocumentsSaved())
+ {
+ LogHelper.WriteLogToFile("检测到有未保存的WPS文档,跳过进程结束", LogHelper.LogType.Warning);
+ StopWpsProcessCheckTimer();
+ return;
+ }
+
+ // 安全结束WPS进程
+ SafeTerminateWpsProcess();
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"WPS 进程检测失败: {ex}", LogHelper.LogType.Error);
+ StopWpsProcessCheckTimer();
+ }
+ }
+
+ ///
+ /// 优化版的前台WPS窗口检测,减少性能开销
+ ///
+ private bool IsForegroundWpsWindowStillActiveOptimized()
+ {
+ try
+ {
+ // 快速检查:直接检查前台窗口
+ var foregroundWindow = GetForegroundWindow();
+ if (foregroundWindow == IntPtr.Zero) return false;
+
+ // 获取前台窗口的进程ID
+ uint processId;
+ GetWindowThreadProcessId(foregroundWindow, out processId);
+
+ // 如果前台窗口就是我们监控的WPS进程,则认为仍然活跃
+ if (processId == _wpsProcess?.Id)
+ {
+ return true;
+ }
+
+ // 检查是否为WPS相关窗口
+ var windowInfo = GetWindowInfo(foregroundWindow);
+ return IsWpsWindow(windowInfo);
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"优化版WPS窗口检测失败: {ex}", LogHelper.LogType.Error);
+ return false;
+ }
+ }
+
+ ///
+ /// 多重验证WPS窗口状态,确保查杀准确性
+ ///
+ private bool PerformMultipleWpsWindowChecks()
+ {
+ try
+ {
+ // 第一重验证:等待1秒后再次检查
+ Thread.Sleep(1000);
+ if (IsForegroundWpsWindowStillActiveOptimized())
+ {
+ LogHelper.WriteLogToFile("第一重验证:WPS窗口仍然存在", LogHelper.LogType.Trace);
+ return false;
+ }
+
+ // 第二重验证:检查所有WPS进程的窗口
+ var wpsProcesses = GetWpsProcesses();
+ foreach (var process in wpsProcesses)
+ {
+ if (process.Id == _wpsProcess?.Id) continue; // 跳过当前监控的进程
+
+ var windows = GetWpsWindowsByProcess(process.Id);
+ if (windows.Any(w => w.IsVisible && !w.IsMinimized))
+ {
+ LogHelper.WriteLogToFile($"第二重验证:发现其他WPS进程{process.Id}有活跃窗口", LogHelper.LogType.Trace);
+ return false;
+ }
+ }
+
+ // 第三重验证:检查任务栏中的WPS窗口
+ if (HasWpsWindowInTaskbar())
+ {
+ LogHelper.WriteLogToFile("第三重验证:任务栏中仍有WPS窗口", LogHelper.LogType.Trace);
+ return false;
+ }
+
+ LogHelper.WriteLogToFile("多重验证完成:确认WPS窗口已全部消失", LogHelper.LogType.Event);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"多重验证失败: {ex}", LogHelper.LogType.Error);
+ return false; // 出错时保守处理,不进行查杀
+ }
+ }
+
+ ///
+ /// 检查任务栏中是否有WPS窗口
+ ///
+ private bool HasWpsWindowInTaskbar()
+ {
+ try
+ {
+ var allWindows = new List();
+
+ EnumWindows((hWnd, lParam) =>
+ {
+ try
+ {
+ if (IsWindow(hWnd) && IsWindowVisible(hWnd))
+ {
+ var windowInfo = GetWindowInfo(hWnd);
+ if (IsWpsWindow(windowInfo) && !string.IsNullOrEmpty(windowInfo.Title))
+ {
+ allWindows.Add(windowInfo);
+ }
+ }
+ }
+ catch { }
+ return true;
+ }, IntPtr.Zero);
+
+ return allWindows.Count > 0;
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"检查任务栏WPS窗口失败: {ex}", LogHelper.LogType.Error);
+ return true; // 出错时保守处理,认为仍有窗口
+ }
+ }
+
+ ///
+ /// 安全地结束WPS进程
+ ///
+ private void SafeTerminateWpsProcess()
+ {
+ try
+ {
+ if (_wpsProcess == null || _wpsProcess.HasExited)
+ {
+ LogHelper.WriteLogToFile("WPS进程已经结束,无需查杀", LogHelper.LogType.Trace);
+ StopWpsProcessCheckTimer();
+ return;
+ }
+
+ LogHelper.WriteLogToFile($"开始安全结束WPS进程 (PID: {_wpsProcess.Id})", LogHelper.LogType.Event);
+
+ // 尝试优雅关闭
+ try
+ {
+ _wpsProcess.CloseMainWindow();
+ if (_wpsProcess.WaitForExit(3000)) // 等待3秒
+ {
+ LogHelper.WriteLogToFile("WPS进程已优雅关闭", LogHelper.LogType.Event);
+ StopWpsProcessCheckTimer();
+ return;
+ }
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"优雅关闭WPS进程失败: {ex}", LogHelper.LogType.Warning);
+ }
+
+ // 强制结束
try
{
if (!_wpsProcess.HasExited)
{
_wpsProcess.Kill();
- LogHelper.WriteLogToFile("成功结束WPS进程", LogHelper.LogType.Event);
+ LogHelper.WriteLogToFile("WPS进程已强制结束", LogHelper.LogType.Event);
}
}
catch (Exception ex)
{
- LogHelper.WriteLogToFile($"结束WPS进程失败: {ex}", LogHelper.LogType.Error);
- }
- finally
- {
- StopWpsProcessCheckTimer();
+ LogHelper.WriteLogToFile($"强制结束WPS进程失败: {ex}", LogHelper.LogType.Error);
}
}
catch (Exception ex)
{
- LogHelper.WriteLogToFile($"WPS 进程检测失败: {ex}", LogHelper.LogType.Error);
+ LogHelper.WriteLogToFile($"安全结束WPS进程时发生异常: {ex}", LogHelper.LogType.Error);
+ }
+ finally
+ {
StopWpsProcessCheckTimer();
}
}
@@ -1193,16 +1362,41 @@ namespace Ink_Canvas.Helpers
try
{
var pname = process.ProcessName.ToLower();
- if ((pname.Contains("wps") || pname.Contains("wpp") || pname.Contains("presentation"))
- && !pname.Contains("powerpnt")
- && !pname.Contains("office")
- && !pname.Contains("onenote")
- && !pname.Contains("excel")
- && !pname.Contains("word")
- && !pname.Contains("outlook")
- && !pname.Contains("microsoft"))
+
+ // 精确的WPS进程名匹配,避免误杀
+ var exactWpsNames = new[] { "wps", "wpp", "et", "wpspdf", "wpsoffice" };
+ var microsoftOfficeNames = new[] { "powerpnt", "excel", "word", "onenote", "outlook", "winword", "msaccess" };
+
+ // 排除微软Office进程
+ if (microsoftOfficeNames.Any(name => pname.Contains(name)))
{
- wpsProcesses.Add(process);
+ continue;
+ }
+
+ // 精确匹配WPS进程名
+ bool isWpsProcess = exactWpsNames.Any(name => pname.Equals(name) || pname.StartsWith(name + "."));
+
+ // 额外验证:检查进程路径
+ if (isWpsProcess)
+ {
+ try
+ {
+ var processPath = process.MainModule?.FileName?.ToLower() ?? "";
+ if (processPath.Contains("kingsoft") || processPath.Contains("wps office"))
+ {
+ wpsProcesses.Add(process);
+ LogHelper.WriteLogToFile($"检测到WPS进程: {process.ProcessName} (PID: {process.Id})", LogHelper.LogType.Trace);
+ }
+ }
+ catch
+ {
+ // 无法访问进程路径时,基于进程名判断
+ if (exactWpsNames.Contains(pname))
+ {
+ wpsProcesses.Add(process);
+ LogHelper.WriteLogToFile($"基于进程名检测到WPS进程: {process.ProcessName} (PID: {process.Id})", LogHelper.LogType.Trace);
+ }
+ }
}
}
catch (Exception ex)
@@ -1215,6 +1409,8 @@ namespace Ink_Canvas.Helpers
{
LogHelper.WriteLogToFile($"获取WPS进程失败: {ex}", LogHelper.LogType.Error);
}
+
+ LogHelper.WriteLogToFile($"共检测到{wpsProcesses.Count}个WPS进程", LogHelper.LogType.Trace);
return wpsProcesses;
}