fix: 复制按钮加重试逻辑(CLIPBRD_E_CANT_OPEN 是常见 race)
修复 bug:点 [复制] 按钮偶发 "OpenClipboard 失败 0x800401D0 (CLIPBRD_E_CANT_OPEN)"。 根因:Clipboard.SetText 不自带重试,剪贴板被其他进程占着(RDP 同步、杀软扫描、用户刚复制过其他内容)时会抛 COMException 0x800401D0,典型 race condition。 修法:CopyMessageButton_Click 里包一层重试循环,最多 10 次,每次失败后 Thread.Sleep 50ms 再试(总等待上限 ~500ms,对 UI 不可感知)。失败兜底弹 MessageBox 显示重试次数 + HRESULT 0x 代码,方便用户诊断。 只捕获 COMException(剪贴板错误都走 OLE COM 接口),其他异常类型继续向上抛。
This commit is contained in:
+26
-5
@@ -292,11 +292,31 @@ public partial class MainWindow : Window
|
||||
{
|
||||
if (HistoryList.SelectedItem is not GotifyMessage msg) return;
|
||||
var text = BuildFullMessageText(msg);
|
||||
|
||||
// 剪贴板常被其他进程占着(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)
|
||||
{
|
||||
_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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user