如果我在字符串中有一些文本,我如何将其复制到剪贴板,以便用户可以将其粘贴到另一个窗口(例如,从我的应用程序到记事本)?
WPF: System.Windows.Clipboard (PresentationCore.dll)
System.Windows.Clipboard
Winforms: System.Windows.Forms.Clipboard
System.Windows.Forms.Clipboard
它们都有一个静态的SetText方法。
SetText
System.Windows.Forms.Clipboard.SetText (Windows窗体)或System.Windows.Clipboard.SetText (WPF)
System.Windows.Forms.Clipboard.SetText
System.Windows.Clipboard.SetText
你可以使用System.Windows.Forms.Clipboard.SetText(...)。
System.Windows.Forms.Clipboard.SetText(...)
我希望调用SetText是那么容易,但有相当多的陷阱,你必须处理。您必须确保调用它的线程正在STA中运行。它有时会因为拒绝访问错误而失败,然后在几秒钟后正常工作——这与剪贴板中的COM计时问题有关。如果您的应用程序是通过远程桌面访问剪贴板是粗略的。我们使用一个集中的方法来处理所有这些场景,而不是直接调用SetText。
以下是我们的集中代码:
StaHelper类只是在单线程单元(STA)中的线程上执行一些任意代码——这是剪贴板所需要的。
abstract class StaHelper { readonly ManualResetEvent _complete = new ManualResetEvent( false ); public void Go() { var thread = new Thread( new ThreadStart( DoWork ) ) { IsBackground = true, } thread.SetApartmentState( ApartmentState.STA ); thread.Start(); } // Thread entry method private void DoWork() { try { _complete.Reset(); Work(); } catch( Exception ex ) { if( DontRetryWorkOnFailed ) throw; else { try { Thread.Sleep( 1000 ); Work(); } catch { // ex from first exception LogAndShowMessage( ex ); } } } finally { _complete.Set(); } } public bool DontRetryWorkOnFailed{ get; set; } // Implemented in base class to do actual work. protected abstract void Work(); }
然后我们有一个特定的类来设置剪贴板上的文本。在某些Windows/. net版本的某些边缘情况下,手动创建DataObject是必需的。我现在不记得具体的场景了,在。net 3.5中可能不需要它。
DataObject
class SetClipboardHelper : StaHelper { readonly string _format; readonly object _data; public SetClipboardHelper( string format, object data ) { _format = format; _data = data; } protected override void Work() { var obj = new System.Windows.Forms.DataObject( _format, _data ); Clipboard.SetDataObject( obj, true ); } }
用法如下:
new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();
在Windows窗体中,如果你的字符串在文本框中,你可以很容易地使用这个:
textBoxcsharp.SelectAll(); textBoxcsharp.Copy(); textBoxcsharp.DeselectAll();
使用这个问题中显示的解决方案System.Windows.Forms.Clipboard.SetText(...)会导致异常:
在OLE调用之前,当前线程必须设置为单线程公寓(STA)模式
为了防止这种情况,你可以添加属性:
[STAThread]
来
static void Main(string[] args)
这对我来说很管用:
你想做的是:
System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard");
但是它会导致一个错误,说它必须在ApartmentState.STA的单个线程中。
让我们让它在这样一个线程中运行。它的代码:
public void somethingToRunInThread() { System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard"); } protected void copy_to_clipboard() { Thread clipboardThread = new Thread(somethingToRunInThread); clipboardThread.SetApartmentState(ApartmentState.STA); clipboardThread.IsBackground = false; clipboardThread.Start(); }
在调用copy_to_clipboard()之后,字符串被复制到剪贴板中,所以你可以Paste或Ctrl + V,并将字符串返回为要复制到剪贴板的字符串。
copy_to_clipboard()
使用try-catch,即使它有一个错误,它仍然会复制。
try
catch
Try Clipboard.SetText("copy me to clipboard") Catch ex As Exception End Try
如果使用消息框捕获异常,它将显示错误,但值仍然复制到剪贴板。