¿Cómo copio el contenido de una cadena al portapapeles en C #?

Si tengo algo de texto en una cadena, ¿cómo puedo copiar eso en el portapapeles para que el usuario pueda pegarlo en otra ventana (por ejemplo, desde mi aplicación al Bloc de notas)?

Puede usar System.Windows.Forms.Clipboard.SetText(...) .

System.Windows.Forms.Clipboard.SetText (Winforms) o System.Windows.Clipboard.SetText (WPF)

Desearía que llamar a SetText fuera así de fácil, pero hay bastantes problemas con los que tienes que lidiar. Debe asegurarse de que el subproceso que está llamando se esté ejecutando en STA. A veces puede fallar con un error de acceso denegado y luego funcionar sin problemas segundos después, algo que tiene que ver con los problemas de sincronización COM en el portapapeles. Y si se accede a su aplicación a través de Escritorio remoto, el acceso al portapapeles es incompleto. Utilizamos un método centralizado para manejar todos los escenarios de tesis en lugar de llamar a SetText directamente.

@Stecy: Aquí está nuestro código centralizado:

La clase StaHelper simplemente ejecuta algún código arbitrario en una secuencia en el Single Thread Apartment (STA), requerido por el portapapeles.

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

Luego tenemos una clase específica para configurar el texto en el portapapeles. Es necesario crear un DataObject manualmente en algunos casos DataObject en algunas versiones de Windows / .NET. No recuerdo los escenarios exactos ahora y puede que no se requiera en .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 ); } } 

El uso se ve así:

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

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

Winforms: System.Windows.Forms.Clipboard

Ambos tienen un método SetText estático.

Esto funciona para mí:

Quieres hacer:

 System.Windows.Forms.Clipboard.SetText("String to be copied to Clipboard"); 

Pero provoca un error que dice que debe estar en un solo hilo de ApartmentState.STA.

Así que hagámoslo correr en tal hilo. El código para esto:

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

Después de llamar a copy_to_clipboard() , la cadena se copia en el portapapeles, por lo que puede Pegar o Ctrl + V y recuperar la cadena como Cadena para copiarla en el portapapeles .

Al usar la solución que se muestra en esta pregunta, System.Windows.Forms.Clipboard.SetText(...) , da como resultado la excepción:

El subproceso actual debe establecerse en el modo de apartamento de subproceso único (STA) antes de poder realizar las llamadas OLE

Para evitar esto, puede agregar el atributo:

 [STAThread] 

a

 static void Main(string[] args) 

En Windows Forms, si su cadena está en un cuadro de texto, puede usar esto fácilmente:

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

Clipboard.SetText es lo que quieres.

Use trycatch , incluso si tiene un error, seguirá copiando.

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

Si usa un cuadro de mensaje para capturar la excepción, le mostrará un error, pero el valor aún se copia en el portapapeles.