如何将字符串的内容复制到C#中的剪贴板?

时间:2009-05-22 18:39:36

标签: c# .net clipboard

如果我在String中有一些文本,如何将其复制到剪贴板,以便用户可以将其粘贴到另一个窗口(例如,从我的应用程序到记事本)?

8 个答案:

答案 0 :(得分:315)

您可以使用System.Windows.Forms.Clipboard.SetText(...)

答案 1 :(得分:129)

答案 2 :(得分:64)

我希望打电话给SetText那么容易,但是你需要处理的问题很多。您必须确保您调用它的线程正在STA中运行。它有时会因访问被拒绝而失败,然后在几秒钟后工作而没有问题 - 与剪贴板中的COM计时问题有关。如果通过远程桌面访问您的应用程序,则对剪贴板的访问是粗略的。我们使用集中式方法来处理所有这些场景,而不是直接调用SetText

@Stecy:这是我们的集中代码:

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中可能不需要它。

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();

答案 3 :(得分:22)

WPF:System.Windows.Clipboard(PresentationCore.dll)

Winforms:System.Windows.Forms.Clipboard

两者都有静态SetText方法。

答案 4 :(得分:16)

这对我有用:

你想这样做:

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()后,字符串将被复制到剪贴板中,因此您可以粘贴或 Ctrl + V 并将字符串作为返回要复制到剪贴板的字符串

答案 5 :(得分:13)

使用此问题中显示的解决方案System.Windows.Forms.Clipboard.SetText(...)会导致异常:

  

在进行OLE调用之前,必须将当前线程设置为单线程单元(STA)模式

为防止这种情况,您可以添加以下属性:

[STAThread]

static void Main(string[] args)

答案 6 :(得分:6)

在Windows窗体中,如果您的字符串位于文本框中,则可以轻松使用:

textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();

答案 7 :(得分:-2)

使用try - catch,即使它仍有错误,它仍会复制。

Try
   Clipboard.SetText("copy me to clipboard")
Catch ex As Exception

End Try

如果使用消息框捕获异常,它将显示错误,但该值仍会复制到剪贴板。