繁体   English   中英

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

[英]How do I copy the contents of a String to the clipboard in C#?

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

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

我希望调用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();

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

Winforms: System.Windows.Forms.Clipboard

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

这对我有用:

你想做:

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并将字符串作为String返回以复制到剪贴板

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

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

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

[STAThread]

static void Main(string[] args)

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

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

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

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

End Try

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM