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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/899350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 22:07:43  来源:igfitidea点击:

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

c#.netclipboard

提问by Elie

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)?

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

采纳答案by ravuya

You can use System.Windows.Forms.Clipboard.SetText(...).

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

回答by bsneeze

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

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

Winforms: System.Windows.Forms.Clipboard

Winforms: System.Windows.Forms.Clipboard

Both have a static SetTextmethod.

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

回答by Paul Alexander

I wish calling SetTextwere 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 SetTextdirectly.

我希望打电话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 DataObjectmanually 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.

然后我们有一个特定的类来设置剪贴板上的文本。DataObject在某些版本的 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 );
    }
}

Usage looks like this:

用法如下所示:

new SetClipboardHelper( DataFormats.Text, "See, I'm on the clipboard" ).Go();

回答by Magnetic_dud

In Windows Forms, if your string is in a textbox, you can easily use this:

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

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

回答by Leroy

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

必须先将当前线程设置为单线程单元 (STA) 模式,然后才能进行 OLE 调用

To prevent this, you can add the attribute:

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

[STAThread]

to

static void Main(string[] args)

回答by benli1212

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.

但是它会导致一个错误,说它必须在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+ Vand get back the string as String to be copied to the clipboard.

调用后copy_to_clipboard(),字符串被复制到剪贴板,因此您可以粘贴或Ctrl+V并取回字符串作为要复制到剪贴板的字符串。

回答by Abu Faisal

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.

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