Ric*_*ter 50 .net c# clipboard
在过去的几个小时里,我一直在跟踪一个相当具体的错误,因为另一个应用程序打开了剪贴板.基本上,因为剪贴板是一个共享资源(根据"为什么我的共享剪贴板不起作用?")并且您尝试执行
Clipboard.SetText(string)
Run Code Online (Sandbox Code Playgroud)
要么
Clipboard.Clear().
Run Code Online (Sandbox Code Playgroud)
抛出以下异常:
System.Runtime.InteropServices.ExternalException: Requested Clipboard operation did not succeed. at System.Windows.Forms.Clipboard.ThrowIfFailed(Int32 hr) at System.Windows.Forms.Clipboard.SetDataObject(Object data, Boolean copy, Int32 retryTimes, Int32 retryDelay) at System.Windows.Forms.Clipboard.SetText(String text, TextDataFormat format) at System.Windows.Forms.Clipboard.SetText(String text)
我的初始解决方案是在短暂停顿后重试,直到我意识到Clipboard.SetDataObject具有次数和延迟长度的字段,.NET的默认行为是尝试10次,延迟100毫秒.
最终用户已经注意到最后一件事,即尽管异常被抛出,副本到剪贴板操作仍然有效,但我还没有找到任何关于为什么会这样做的进一步信息.
我目前解决这个问题的方法就是默默地忽略异常...这真的是最好的方法吗?
Ale*_*lex 41
我很抱歉复活了一个旧问题,但另一种解决方法是使用Clipboard.SetDataObject
而不是Clipboard.SetText
.
根据这篇msdn文章,这个方法有两个参数 - retryTimes和retryDelay--你可以像这样使用:
System.Windows.Forms.Clipboard.SetDataObject(
"some text", // Text to store in clipboard
false, // Do not keep after our application exits
5, // Retry 5 times
200); // 200 ms delay between retries
Run Code Online (Sandbox Code Playgroud)
Phi*_*ice 28
由于剪贴板由所有UI应用程序共享,你会遇到这种不时显然,你不想让你的应用程序崩溃,如果它无法写入剪贴板,所以适当地处理ExternalException是合理的,我会建议提呈如果setobjectdata调用写入剪贴板失败,则会给用户带来错误.
一个建议是使用(通过P/Invoke的)user32!GetOpenClipboardWindow
,看是否另一个应用程序具有打开剪贴板,它会返回HWND具有剪贴板打开的窗口,或者IntPtr.Zero
如果没有应用程序有它打开,你可以旋转的价值直到它IntPtr.Zero
达到指定的时间.
Jef*_*Roe 12
我今天遇到了这个错误.我决定通过告诉用户可能行为不端的应用程序来处理它.为此,您可以执行以下操作:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetOpenClipboardWindow();
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern int GetWindowText(int hwnd, StringBuilder text, int count);
private void btnCopy_Click(object sender, EventArgs e)
{
try
{
Clipboard.Clear();
Clipboard.SetText(textBox1.Text);
}
catch (Exception ex)
{
string msg = ex.Message;
msg += Environment.NewLine;
msg += Environment.NewLine;
msg += "The problem:";
msg += Environment.NewLine;
msg += getOpenClipboardWindowText();
MessageBox.Show(msg);
}
}
private string getOpenClipboardWindowText()
{
IntPtr hwnd = GetOpenClipboardWindow();
StringBuilder sb = new StringBuilder(501);
GetWindowText(hwnd.ToInt32(), sb, 500);
return sb.ToString();
// example:
// skype_plugin_core_proxy_window: 02490E80
}
Run Code Online (Sandbox Code Playgroud)
对我来说,问题窗口标题是"skype_plugin_core_proxy_window".我搜索了这方面的信息,并且惊讶地发现它只产生了一次打击,那是俄语.所以我添加了这个答案,既为该字符串提供了另一个答案,又提供了进一步的帮助,以便将可能行为不端的应用程序点亮.
首先调用这个:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr CloseClipboard();
Run Code Online (Sandbox Code Playgroud)
我注意到,如果您正在进行粘贴操作(WM_PASTE 消息),包括在 TextChanged 事件期间,剪贴板将保持由接收该事件的窗口(TextBox)锁定。因此,如果您只是在事件处理程序中调用“CloseClipboard”方法,那么您可以调用托管的 Clipboard.Clear 和 Clipboard.SetText 方法,而不会出现任何问题或延迟。
小智 5
做Clipboard.Clear()
之前Clipboard.SetDataObject(pasteString, true)
似乎可以解决问题。
之前的设置建议对我来说retryTimes
不起作用retryDelay
,无论如何默认值retryTimes = 10
是retryDelay = 100ms
归档时间: |
|
查看次数: |
36852 次 |
最近记录: |