キースヒルのGet-ClipboardとSet-ClipboardのC#実装を、.PSM1ファイルとして純粋なPowerShellに変換したいと思います。
クリップボードで作業しているときにコマンドレットで行うように、PowerShellでSTAスレッドを起動する方法はありますか?
キースヒルのGet-ClipboardとSet-ClipboardのC#実装を、.PSM1ファイルとして純粋なPowerShellに変換したいと思います。
クリップボードで作業しているときにコマンドレットで行うように、PowerShellでSTAスレッドを起動する方法はありますか?
TextBoxには-STAスイッチは必要ありません。
function Get-ClipBoard {
Add-Type -AssemblyName System.Windows.Forms
$tb = New-Object System.Windows.Forms.TextBox
$tb.Multiline = $true
$tb.Paste()
$tb.Text
}
function Set-ClipBoard() {
Param(
[Parameter(ValueFromPipeline=$true)]
[string] $text
)
Add-Type -AssemblyName System.Windows.Forms
$tb = New-Object System.Windows.Forms.TextBox
$tb.Multiline = $true
$tb.Text = $text
$tb.SelectAll()
$tb.Copy()
}
PowerShellCoreおよびWindowsPowerShellv2-v4でクリップボードテキストのサポートを提供するクロスエディション、クロスプラットフォームモジュールについては、下部のセクションを参照してください。
Windows PowerShell v5.1 / PowerShell Core v6.1.0の時点での状況とオプションを要約する試み:
Windows PowerShell v5.0 +:組み込み Get-Clipboard
およびSet-Clipboard
コマンドレットを使用します。
Windows PowerShell v4.0-(v1-v4.0):クリップボードと対話するための組み込みのコマンドレットはありませんが、回避策があります:
標準のコマンドラインユーティリティclip.exe
(W2K3 +サーバー側、Vista +クライアント側)にパイプします[1]:
注:以下で説明するエンコードの問題は別として、入力に... | clip.exe
必ず末尾の改行を追加します。これを回避する唯一の方法は、 cmdの<
入力リダイレクトを介してコンテンツが提供される一時ファイルを使用することです。以下のSet-ClipboardText
関数を参照してください。
ASCII文字(7ビット)のサポートのみが必要な場合:デフォルトで機能します。
OEMエンコーディング(8ビット)サポート(たとえば、米国のIBM437)のみが必要な場合は、最初に以下を実行します。
$OutputEncoding = [System.Text.Encoding]::GetEncoding([System.Globalization.CultureInfo]::CurrentCulture.TextInfo.OEMCodePage)
Unicodeを完全にサポートする必要がある場合は、BOMなしのUTF - 16LEエンコーディングを使用する必要があります。最初に以下を実行します。
$OutputEncoding = New-Object System.Text.UnicodeEncoding $false, $false # UTF-16 encoding *without BOM*
テストの例(PSコンソールはアジア文字を「??」として表示しますが、それでも正しく処理します。たとえば、メモ帳でクリップボードの内容を確認します):
"I enjoyed Thomas Hübl's talk about 中文" | clip # should appear as is on the clipboard
注:$OutputEncoding
上記のように割り当てることは、グローバルスコープでは正常に機能しますが、Windows PowerShell v5.1 / PowerShell Core v6.0.0-rc.2の時点でのバグのため、関数などでは機能しません。https://を参照してください。 github.com/PowerShell/PowerShell/issues/5763
(New-Object ...).psobject.BaseObject
してバグを回避するか、PSv5+[...]:new()
では代わりにを使用します。注:clip.exe
明らかに2つの形式を理解しています:
clip.exe
として扱うため、BOMのないエンコーディングを使用する必要があります。.NETクラスを直接使用するPowerShellベースのソリューションを使用します。
クリップボードへのアクセスは、MTA(マルチスレッドアパートメント)ではなく、STA(シングルスレッドアパートメント)モードのスレッドからのみ発生することに注意してください。
powershell.exe
、-mta
スイッチで呼び出すことで開始できます)。powershell.exe
、-sta
スイッチで呼び出すことで開始できます。PowerShell Core(マルチプラットフォーム)(v6.1.0以降)には、 Windowsで実行している場合でも、クリップボードと対話するための組み込みのコマンドレットがありません。
私のClipboardText
モジュールは
「ポリフィル」機能Get-ClipboardText
を提供し、クリップボードからテキストSet-ClipboardText
を取得および設定します。これらは、Windows PowerShell v2+およびPowerShellCoreで動作します(制限付き。以下を参照)。
最も単純なケース(パッケージ管理モジュールがインストールされているPSv5+またはv3/ v4)では、次のように、PowerShellギャラリーから昇格された/セッションからインストールsudo
できます。
Install-Module ClipboardText
前提条件や手動インストール手順などの詳細については、リポジトリを参照してください。
注:厳密に言えば、関数の名前が組み込みのコマンドレットと異なるため、関数はポリフィルではありません。ただし、名前の接尾辞Textは、これらの関数がテキストのみを処理することを明示するために選択されました。
このコードは、さまざまなサイト、特に@hogeの回答(https://stackoverflow.com/a/1573295/45375)およびhttp://techibee.com/powershell/powershell-script-to-copy-powershell-からの情報に基づいて構築されています。 command-output-to-clipboard / 1316
STAモードのWindowsPowerShellv5 +で実行:
Get-Clipboard
/ Set-Clipboard
)はバックグラウンドで呼び出されます。-MTA
。その他のすべての場合(Windows PowerShell v4-および/またはMTAモード、サポートされているすべてのプラットフォームのPowerShell Core ):
Add-Type
ます。pbcopy
およびpbpaste
xclip
でインストールされている場合; sudo apt-get xclip
してインストールします。Set-ClipboardText
直接またはパイプラインから、任意のタイプのオブジェクトを入力として受け入れることができます(コンソールでレンダリングするのと同じ方法でテキストに変換されます)。
で呼び出して-Verbose
、クリップボードにアクセスするために舞台裏でどのような手法が使用されているかを確認します。
[1]この回答の以前のバージョンでは、次のように誤って主張されていclip.exe
まし
た。-クリップボードにコピーするときに常に改行を追加します(そうではありません)-stdin経由でリダイレクトされたファイル
のUTF-16 LE BOMと、入力が経由でパイプされた場合を正しく処理します(常にBOMをクリップボードにコピーします)。
<
|
clip.exe
私はこれを行う方法をブログに書きました:
http://www.nivot.org/2009/10/14/PowerShell20GettingAndSettingTextToAndFromTheClipboard.aspx
-オシーン
最初にホストを確認する必要があります。ISEはすでにSTAを実行しているため、別のスレッドやシェルを起動する必要はありません(これは、PSCXのToDoリストにある最適化です)。MTAであるコンソールプロンプトの場合、Oisinが示すように、バイナリコードにシェルアウトするか、次のような単純な小さなC#アプリを使用します。
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
class OutClipboard {
[STAThread]
static void Main() {
Clipboard.SetText(Console.In.ReadToEnd());
}
}
また、クリップボードの内容を取得するために、Vista以降にはclip.exeがあります。
2.0の高度な機能でさえ、スクリプト内で独自の.NETスレッドを使用してパーティーを開く準備ができているとは思いません。
PowerShellクックブック: Set-ClipboardのLeeHolmeのレシピをご覧ください。atをSet-Clipboard.ps1として使用するか、PowerShell関数内にコードをドロップするだけです(これが私のPowerShellプロファイルの例です)。
このスクリプトを使用すると、パイプされた完全な出力をクリップボードに取得できます。例:
dir | Set-Clipboard
私はもともとこの答えからリー・ホームの解決策を知りました。
PowerShell 5には、とがGet-Clipboard
ありSet-Clipboard
ます。
PowerShell4しかないWindowsServer2012 R2では、.NETを使用してクリップボードを操作することができました。
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$copied = [System.Windows.Forms.Clipboard]::GetText()
$to_paste = 'Hello World'
[System.Windows.Forms.Clipboard]::SetText($to_paste)