diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index ac931ce..4782b9c 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -292,11 +292,31 @@ public partial class MainWindow : Window { if (HistoryList.SelectedItem is not GotifyMessage msg) return; var text = BuildFullMessageText(msg); - try + + // 剪贴板常被其他进程占着(RDP、杀软、其他复制操作),CLIPBRD_E_CANT_OPEN 是常见 race。 + // Clipboard.SetText 不自带重试,自己包一层:最多 10 次,每次等 50ms。 + const int MaxAttempts = 10; + const int DelayMs = 50; + Exception? lastEx = null; + bool ok = false; + for (int attempt = 1; attempt <= MaxAttempts; attempt++) + { + try + { + Clipboard.SetText(text); + ok = true; + break; + } + catch (System.Runtime.InteropServices.COMException ex) + { + lastEx = ex; + System.Threading.Thread.Sleep(DelayMs); + } + } + + if (ok) { - Clipboard.SetText(text); _logger?.Info($"Copied message to clipboard. id={msg.Id}"); - // 按钮反馈:短暂显示「已复制 ✓」 if (sender is Button btn) { var origContent = btn.Content; @@ -313,11 +333,12 @@ public partial class MainWindow : Window timer.Start(); } } - catch (Exception ex) + else { - _logger?.Error("Copy to clipboard failed.", ex); - MessageBox.Show($"复制失败:{ex.Message}", "Windows Gotify", - MessageBoxButton.OK, MessageBoxImage.Warning); + _logger?.Error("Copy to clipboard failed after retries.", lastEx); + MessageBox.Show( + $"复制失败:剪贴板被其他程序占用,重试 {MaxAttempts} 次仍未成功。\n请关闭正在使用剪贴板的程序后重试。\n\n错误:0x{(lastEx?.HResult ?? 0):X8}", + "Windows Gotify", MessageBoxButton.OK, MessageBoxImage.Warning); } }