文字列をクリップボードにコピーする
.NETでクリップボードにアクセスする場合「System.Windows.Forms.Clipboard」オブジェクトを利用します。
ただし、Clipboard クラスは、STA(Single Thread Apartment)モードに設定されているスレッドでしか使用できません。
PowerShellのApartmentStateはMTA(Multi Thread Apartment)モードですので、Clipboardクラスは利用できない事になります。
PowerShellのApartmentStateを確認する
PS C:\> [System.Threading.Thread]::CurrentThread.ApartmentState MTA
ClipBoardクラスを利用してみると・・・
PS C:\> [void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") PS C:\> [System.Windows.Forms.Clipboard]::SetDataObject("コピー") "1" 個の引数を指定して "SetDataObject" を呼び出し中に 例外が発生しました: "OLE が呼び出される前に、現在のスレッドが Single Thread Apartment (STA) モードに設定されていなければなりません。 Main 関数に STAThreadAttribute が設定されていることを確認してください。" 発生場所 行:1 文字:48 + [System.Windows.Forms.Clipboard]::SetDataObject( <<<< "コピー")
・・・となります。
IEのCOMオブジェクトを利用する
以前、クリップボードに文字列をコピーする方法として、VBCodeProviderを利用してVB.NETのコードを実行するサンプルを紹介しました。
MonadからVB.NETのコードを実行(2) - PowerShell Memo
実は、VBCodeProviderを利用しなくても、IEオブジェクトを利用すれば、より簡単に同様の処理を実現できる事に気づきました。
文字列をクリップボードにコピーする(IEオブジェクトを利用する)
function CopyTo-ClipBoard([String]$strTagert) { $OLECMDID_COPY = 12 $OLECMDID_SELECTALL = 17 $OLECMDEXECOPT_DODEFAULT = 0 $ie = new-object -com InternetExplorer.Application $ie.navigate("about:blank") $ie.document.body.innerText = $strTagert $ie.execWB($OLECMDID_SELECTALL,$OLECMDEXECOPT_DODEFAULT) $ie.execWB($OLECMDID_COPY,$OLECMDEXECOPT_DODEFAULT) $ie.quit() }
使用方法
CopyTo-Clipboard [コピーする文字列]
使用例
$text = "PowerShell Memo" CopyTo-Clipboard $text