Как скопировать содержимое строки в буфер обмена на С#?

Если у меня есть текст в String, как я могу скопировать его в буфер обмена, чтобы пользователь мог вставить его в другое окно (например, из моего приложения в блокнот)?

Ответ 1

Вы можете использовать System.Windows.Forms.Clipboard.SetText(...).

Ответ 3

Я хочу, чтобы вызов SetText был таким простым, но есть немало проблем, с которыми вам приходится иметь дело. Вы должны убедиться, что поток, который вы вызываете, включен в STA. Иногда это может быть неудачно с ошибкой отказа в доступе, а затем работать через несколько секунд без проблем - что-то связанное с проблемами синхронизации времени в буфере обмена. И если ваше приложение доступно через доступ к удаленному рабочему столу, доступ к буфере обмена является отрывочным. Мы используем централизованный метод для обработки всех этих сценариев вместо прямого вызова 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();
}

Тогда у нас есть специальный класс для установки текста в буфер обмена. Создание 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 );
    }
}

Использование выглядит следующим образом:

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

Ответ 4

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

Winforms: System.Windows.Forms.Clipboard

Оба имеют статический метод SetText.

Ответ 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(...), приводит к исключению:

Текущий поток должен быть установлен в режим однопоточной квартиры (STA) до того, как вызовы OLE могут быть сделаны

Чтобы предотвратить это, вы можете добавить атрибут:

[STAThread]

к

static void Main(string[] args)

Ответ 7

В Windows Forms, если ваша строка находится в текстовом поле, вы можете легко использовать это:

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

Ответ 9

Используйте try - catch, даже если он имеет ошибку, он все равно будет скопирован.

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

End Try

Если вы используете окно сообщения для получения исключения, оно покажет вам ошибку, но значение все равно будет скопировано в буфер обмена.