From fe47293da55a06138a63c824a3e94d1fb965c114 Mon Sep 17 00:00:00 2001 From: Solin Date: Mon, 19 Jan 2026 09:58:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A4=84=E7=90=86=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E4=BB=A5=E9=87=8D=E7=BD=AE=E5=AA=92=E4=BD=93?= =?UTF-8?q?=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MainForm.cs | 14 ++++++++++++++ NativeMethods.cs | 19 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/MainForm.cs b/MainForm.cs index 0d7fef1..e044255 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -2,6 +2,7 @@ using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; +using Microsoft.Win32; namespace TimerApp { @@ -129,6 +130,8 @@ namespace TimerApp _monitor.Start(); + SystemEvents.PowerModeChanged += OnPowerModeChanged; + // Set tray icon try { @@ -550,6 +553,7 @@ namespace TimerApp } else { + SystemEvents.PowerModeChanged -= OnPowerModeChanged; notifyIcon1.Visible = false; notifyIcon1.Dispose(); } @@ -615,5 +619,15 @@ namespace TimerApp { this.WindowState = FormWindowState.Minimized; } + + private void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e) + { + if (e.Mode == PowerModes.Resume) + { + // 系统唤醒时,强制重置媒体播放检测状态, + // 避免因检测线程挂起导致一直误报“正在播放”而无法进入工作状态。 + NativeMethods.InvalidateMediaCache(); + } + } } } diff --git a/NativeMethods.cs b/NativeMethods.cs index 5321aab..0421e3f 100644 --- a/NativeMethods.cs +++ b/NativeMethods.cs @@ -57,6 +57,18 @@ namespace TimerApp return Volatile.Read(ref _mediaPlaying); } + /// + /// 强制失效媒体播放状态缓存 + /// + public static void InvalidateMediaCache() + { + Interlocked.Exchange(ref _mediaLastUpdateMs, -1); + // 不直接重置 _mediaPlaying,以免在检测过程中出现闪烁, + // 只是强制下一次 IsMediaPlaying 触发新的检测。 + // 但如果处于 Resume 状态,假设不播放是安全的。 + Volatile.Write(ref _mediaPlaying, false); + } + private static bool _mediaPlaying; private static long _mediaLastUpdateMs = -1; private static int _mediaUpdateInProgress; @@ -256,7 +268,12 @@ namespace TimerApp thread.IsBackground = true; thread.SetApartmentState(ApartmentState.STA); thread.Start(); - thread.Join(); + + // Wait with timeout (e.g. 2 seconds) to prevent hanging + if (!thread.Join(2000)) + { + return false; + } if (error is not null) {