如果我在字符串中有一些文本,我如何将其复制到剪贴板,以便用户可以将其粘贴到另一个窗口(例如,从我的应用程序到记事本)?
当前回答
这对我来说很管用:
你想做的是:
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并将字符串作为string返回,以复制到剪贴板中。
其他回答
System.Windows.Clipboard (PresentationCore.dll)
Winforms: System.Windows.Forms.Clipboard
两者都有一个静态的SetText方法。
System.Windows.Forms.Clipboard.SetText (Windows窗体)或System.Windows.Clipboard.SetText (WPF)
你可以使用System.Windows.Forms.Clipboard.SetText(…)。
使用try-catch,即使它有错误,它仍然会复制。
Try
Clipboard.SetText("copy me to clipboard")
Catch ex As Exception
End Try
如果使用消息框捕获异常,它将显示错误,但值仍然复制到剪贴板。
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.
以下是我们的集中代码:
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版本的某些边缘情况下,需要手动创建数据对象。我现在不记得具体的场景了,在。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 );
}
}
用法如下:
new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();
推荐文章
- 如何强制LINQ Sum()返回0而源集合是空的
- 将值附加到查询字符串
- Selenium c# WebDriver:等待元素出现
- 我如何添加双引号的字符串,是在一个变量?
- 如何创建数组。包含不区分大小写的字符串数组?
- 检查字符串是否包含字符串列表中的元素
- 最好的方法在asp.net强制https为整个网站?
- 将字符串转换为System.IO.Stream
- 如何从枚举中选择一个随机值?
- 驻留在App_Code中的类不可访问
- 在链式LINQ扩展方法调用中等价于'let'关键字的代码
- dynamic (c# 4)和var之间的区别是什么?
- Visual Studio: ContextSwitchDeadlock
- 返回文件在ASP。Net Core Web API
- 自定义HttpClient请求头