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


当前回答

你可以使用System.Windows.Forms.Clipboard.SetText(…)。

其他回答

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

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

End Try

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

System.Windows.Clipboard (PresentationCore.dll)

Winforms: System.Windows.Forms.Clipboard

两者都有一个静态的SetText方法。

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

在OLE调用之前,当前线程必须设置为单线程公寓(STA)模式

为了防止这种情况,你可以添加属性:

[STAThread]

to

static void Main(string[] args)

你可以使用System.Windows.Forms.Clipboard.SetText(…)。

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