文字列にテキストがある場合、ユーザーが別のウィンドウに貼り付けることができるように(たとえば、アプリケーションからメモ帳に)クリップボードにコピーするにはどうすればよいですか?
System.Windows.Forms.Clipboard.SetText(...)
を使用できます。
System.Windows.Forms.Clipboard.SetText
(Windowsフォーム)または System.Windows.Clipboard.SetText
(WPF)
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の一部のバージョンのEdgeの場合には、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 そして、文字列をクリップボードにコピーされる文字列として返します。
この質問に示されているソリューションSystem.Windows.Forms.Clipboard.SetText(...)
を使用すると、例外が発生します。
OLE呼び出しを行う前に、現在のスレッドをシングルスレッドアパートメント(STA)モードに設定する必要があります
これを防ぐために、属性を追加できます。
[STAThread]
に
static void Main(string[] args)
Windowsフォームでは、文字列がテキストボックスにある場合、これを簡単に使用できます。
textBoxcsharp.SelectAll();
textBoxcsharp.Copy();
textBoxcsharp.DeselectAll();