If I have some text in a String, how can I copy that to the clipboard so that the user can paste it into another window (for example, from my application to Notepad)?
如果我在一个字符串中有一些文本,我如何将它复制到剪贴板,以便用户可以将它粘贴到另一个窗口(例如,从我的应用程序到记事本)?
9 个解决方案
#1
290
You can use System.Windows.Forms.Clipboard.SetText(...)
.
您可以使用System.Windows.Forms.Clipboard.SetText(……)。
#2
108
System.Windows.Forms.Clipboard.SetText
(Winforms) or System.Windows.Clipboard.SetText
(WPF)
System.Windows.Forms.Clipboard。SetText(Winforms)或System.Windows.Clipboard。SetText(WPF)
#3
59
I wish calling SetText
were that easy but there are quite a few gotchas that you have to deal with. You have to make sure that the thread you are calling it on is running in the STA. It can sometimes fail with an access denied error then work seconds later without problem - something to do with the COM timing issues in the clipboard. And if your application is accessed over Remote Desktop access to the clipboard is sketchy. We use a centralized method to handle all theses scenarios instead of calling SetText
directly.
我希望调用SetText很简单,但是有很多问题需要处理。您必须确保您所调用的线程在STA中运行。它有时会在访问被拒绝的错误后失败,然后几秒钟后工作,没有问题——这与剪贴板中的COM计时问题有关。如果您的应用程序是通过远程桌面访问的,那么剪贴板的访问是粗略的。我们使用集中的方法来处理所有的场景,而不是直接调用SetText。
@Stecy: Here's our centralized code:
@Stecy:这是我们的集中代码:
The StaHelper class simply executes some arbitrary code on a thread in the Single Thread Apartment (STA) - required by the clipboard.
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();
}
Then we have a specific class for setting text on the clipboard. Creating a DataObject
manually is required in some edge cases on some versions of Windows/.NET. I don't recall the exact scenarios now and it may not be required in .NET 3.5.
然后我们有一个在剪贴板上设置文本的特定类。在Windows/. net的某些版本中,手工创建DataObject是必要的。我现在不记得确切的场景,在。net 3.5中可能不需要它。
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 );
}
}
Usage looks like this:
使用看起来像这样:
new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();
#4
19
WPF: System.Windows.Clipboard
(PresentationCore.dll)
WPF:System.Windows。剪贴板(PresentationCore.dll)
Winforms: System.Windows.Forms.Clipboard
Winforms:System.Windows.Forms.Clipboard
Both have a static SetText
method.
它们都有一个静态SetText方法。
#5
15
This works for me:
这工作对我来说:
You want to do:
你想要做的事:
System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard");
But it causes an error saying it must be in a single thread of ApartmentState.STA.
但是它会导致一个错误,说它一定是在一个线程中的。
So let's make it run in such a thread. The code for it:
让它在这样的线程中运行。的代码:
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();
}
After calling copy_to_clipboard()
, the string is copied into the clipboard, so you can Paste or Ctrl + V and get back the string as String to be copied to the clipboard.
调用copy_to_clipboard()之后,字符串被复制到剪贴板中,因此您可以粘贴或按Ctrl + V,并以字符串的形式将字符串复制到剪贴板中。
#6
10
Using the solution showed in this question, System.Windows.Forms.Clipboard.SetText(...)
, results in the exception:
使用这个问题中显示的解决方案System.Windows.Forms.Clipboard.SetText(…),会导致异常:
Current thread must be set to single thread apartment (STA) mode before OLE calls can be made
在进行OLE调用之前,必须将当前线程设置为单线程单元模式(STA)
To prevent this, you can add the attribute:
要防止这种情况发生,可以添加以下属性:
[STAThread]
to
来
static void Main(string[] args)
#7
4
In Windows Forms, if your string is in a textbox, you can easily use this:
在Windows窗体中,如果您的字符串在文本框中,您可以轻松地使用以下内容:
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
#9
0
Use try
-catch
, even if it has an error it will still copy.
使用try-catch,即使它有错误,它仍然会复制。
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
If you use a message box to capture the exception, it will show you error, but the value is still copied to clipboard.
如果您使用消息框捕获异常,它将显示错误,但该值仍然被复制到剪贴板。
#1
290
You can use System.Windows.Forms.Clipboard.SetText(...)
.
您可以使用System.Windows.Forms.Clipboard.SetText(……)。
#2
108
System.Windows.Forms.Clipboard.SetText
(Winforms) or System.Windows.Clipboard.SetText
(WPF)
System.Windows.Forms.Clipboard。SetText(Winforms)或System.Windows.Clipboard。SetText(WPF)
#3
59
I wish calling SetText
were that easy but there are quite a few gotchas that you have to deal with. You have to make sure that the thread you are calling it on is running in the STA. It can sometimes fail with an access denied error then work seconds later without problem - something to do with the COM timing issues in the clipboard. And if your application is accessed over Remote Desktop access to the clipboard is sketchy. We use a centralized method to handle all theses scenarios instead of calling SetText
directly.
我希望调用SetText很简单,但是有很多问题需要处理。您必须确保您所调用的线程在STA中运行。它有时会在访问被拒绝的错误后失败,然后几秒钟后工作,没有问题——这与剪贴板中的COM计时问题有关。如果您的应用程序是通过远程桌面访问的,那么剪贴板的访问是粗略的。我们使用集中的方法来处理所有的场景,而不是直接调用SetText。
@Stecy: Here's our centralized code:
@Stecy:这是我们的集中代码:
The StaHelper class simply executes some arbitrary code on a thread in the Single Thread Apartment (STA) - required by the clipboard.
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();
}
Then we have a specific class for setting text on the clipboard. Creating a DataObject
manually is required in some edge cases on some versions of Windows/.NET. I don't recall the exact scenarios now and it may not be required in .NET 3.5.
然后我们有一个在剪贴板上设置文本的特定类。在Windows/. net的某些版本中,手工创建DataObject是必要的。我现在不记得确切的场景,在。net 3.5中可能不需要它。
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 );
}
}
Usage looks like this:
使用看起来像这样:
new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();
#4
19
WPF: System.Windows.Clipboard
(PresentationCore.dll)
WPF:System.Windows。剪贴板(PresentationCore.dll)
Winforms: System.Windows.Forms.Clipboard
Winforms:System.Windows.Forms.Clipboard
Both have a static SetText
method.
它们都有一个静态SetText方法。
#5
15
This works for me:
这工作对我来说:
You want to do:
你想要做的事:
System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard");
But it causes an error saying it must be in a single thread of ApartmentState.STA.
但是它会导致一个错误,说它一定是在一个线程中的。
So let's make it run in such a thread. The code for it:
让它在这样的线程中运行。的代码:
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();
}
After calling copy_to_clipboard()
, the string is copied into the clipboard, so you can Paste or Ctrl + V and get back the string as String to be copied to the clipboard.
调用copy_to_clipboard()之后,字符串被复制到剪贴板中,因此您可以粘贴或按Ctrl + V,并以字符串的形式将字符串复制到剪贴板中。
#6
10
Using the solution showed in this question, System.Windows.Forms.Clipboard.SetText(...)
, results in the exception:
使用这个问题中显示的解决方案System.Windows.Forms.Clipboard.SetText(…),会导致异常:
Current thread must be set to single thread apartment (STA) mode before OLE calls can be made
在进行OLE调用之前,必须将当前线程设置为单线程单元模式(STA)
To prevent this, you can add the attribute:
要防止这种情况发生,可以添加以下属性:
[STAThread]
to
来
static void Main(string[] args)
#7
4
In Windows Forms, if your string is in a textbox, you can easily use this:
在Windows窗体中,如果您的字符串在文本框中,您可以轻松地使用以下内容:
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();
#8
#9
0
Use try
-catch
, even if it has an error it will still copy.
使用try-catch,即使它有错误,它仍然会复制。
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
If you use a message box to capture the exception, it will show you error, but the value is still copied to clipboard.
如果您使用消息框捕获异常,它将显示错误,但该值仍然被复制到剪贴板。