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

Posted

技术标签:

【中文标题】如何将字符串的内容复制到 C# 中的剪贴板? [复制]【英文标题】:How do I copy the contents of a String to the clipboard in C#? [duplicate] 【发布时间】:2009-05-22 18:39:36 【问题描述】:

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

【问题讨论】:

没有winforms或wpf:***.com/a/13571530/359135 【参考方案1】:

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

【讨论】:

这是针对 WinForms 的;对于 WPF,请参阅 Jeff Moser 的回答(目前为 2)。 @DannyBeckett 现在只有 1 了。 对于控制台应用程序,您需要使用属性 [STAThread] 装饰 Main 问题是“一些文本”,但为了稳健性:if the string is empty 会发生什么?【参考方案2】:

System.Windows.Forms.Clipboard.SetText(Windows 窗体)或System.Windows.Clipboard.SetText(WPF)

【讨论】:

如果是控制台应用程序呢? 你仍然可以使用任何一个,你只需将 winforms dll 添加为参考程序集。 @Cheeso 用于控制台应用程序 se 回答 below WPF 方法在 .Net 4.6.1 控制台应用程序中对我不起作用,Winforms 方法在我将 [STAThread] 属性添加到 Main() 后完美运行【参考方案3】:

我希望致电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();

【讨论】:

+1,我至少经历过其中一些陷阱。如果我将剪贴板访问包装在 try ... catch (System.Runtime.InteropServices.ExternalException) 中,这对我来说没问题。 @Paul,您能解释一下您的集中式方法吗? 这个答案应该得到比它更多的支持。此外,您应该提出一个自我回答的问题,例如“如何在非 STA 上下文中运行 STA 代码” 我在这里,一年半后,几乎没有记忆从 2/19/16 开始,再次复制这堂课。 什么是数据格式?【参考方案4】:

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

Winforms:System.Windows.Forms.Clipboard

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

【讨论】:

感谢您包含 PresentationCore.dll 参考。默认情况下不包含在控制台应用程序中【参考方案5】:

这对我有用:

你想做的事:

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的形式取回字符串被复制到剪贴板

【讨论】:

正确的钱。谢谢!【参考方案6】:

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

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

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

[STAThread]

static void Main(string[] args)

【讨论】:

【参考方案7】:

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

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

【讨论】:

你不需要放入所有的选择和删除垃圾。只需简单地输入:textBox1.Copy(); 实际上,您确实需要 SelectAll() 和 DeselectAll() 垃圾。根据msdn.microsoft.com/en-us/library/…,复制到剪贴板的是当前选择的文本。 你需要把SelectAll(),否则不行,我就tried in this useless app。不过,在 WPF 应用程序中无需使用 DeselectAll()。 我喜欢这个,因为它使您不必将 STA 属性添加到您的课程中。我只是在一些调试过程中想要这个,我并没有改变我的代码的其他部分只是为了得到一些东西到键盘缓冲区。【参考方案8】:

使用try-catch,即使出现错误仍会复制。

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

End Try

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

【讨论】:

你确定吗?您是否尝试过多次,例如10倍?也许你只是幸运?一般情况下不需要重试(作为一种解决方法)吗?

以上是关于如何将字符串的内容复制到 C# 中的剪贴板? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

在delphi中如何实现将剪贴板中的多行字符串中间加上逗号?

C#中如何动态获取剪贴板中的内容(我想实现如果其中有内容就清空,在C#中不要实现复制,粘贴功能)?

autoit中如何把指定内容复制到剪贴板?

如何将文本文件中的数据复制到剪贴板? [复制]

当我通过 Git Bash 中的 ssh 在远程 Linux 机器上运行命令时,如何将文件的内容直接复制到我的 Windows 剪贴板中?

如何自动选定一个网页显示的全部内容到复制到剪贴板中?