11

キースヒルのGet-ClipboardとSet-ClipboardのC#実装を、.PSM1ファイルとして純粋なPowerShellに変換したいと思います。

クリップボードで作業しているときにコマンドレットで行うように、PowerShellでSTAスレッドを起動する方法はありますか?

ブログ投稿
コード

4

6 に答える 6

16

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()
}
于 2009-10-15T15:54:21.270 に答える
9

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):クリップボードと対話するための組み込みのコマンドレットはありませんが、回避策があります:

    • PowerShell Community Extensions(PSCX; http://pscx.codeplex.com/ )を使用します。これには、テキストの処理だけでなく、クリップボード関連のコマンドレットがいくつか付属しています。
    • 標準のコマンドラインユーティリティ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つの形式を理解しています:

        • システムの現在のOEMコードページ(例:IBM 437)
        • UTF-16 LE( "Unicode")
        • 残念ながら、常にBOMをデータclip.exeとして扱うため、BOMのないエンコーディングを使用する必要があります。
        • 上記のエンコーディングは、入力を正しく検出することに関してのみ重要であることに注意してください。クリップボードに入ると、入力文字列は、UTF-16 LE、 "ANSI"、およびOEMのすべてのエンコーディングで使用できます。
    • .NETクラスを直接使用するPowerShellベースのソリューションを使用します

      • クリップボードへのアクセスは、MTA(マルチスレッドアパートメント)ではなく、STA(シングルスレッドアパートメント)モードのスレッドからのみ発生することに注意してください。

        • v3:STAがデフォルトです(MTAモードはpowershell.exe-mtaスイッチで呼び出すことで開始できます)。
        • v2およびv1:MTAがデフォルトです。STAモードはpowershell.exe-staスイッチで呼び出すことで開始できます。
        • エルゴ:堅牢な機能は、どちらのモードのセッションからもクリップボードにアクセスできる必要があります。
  • PowerShell Core(マルチプラットフォーム)(v6.1.0以降)には、 Windowsで実行している場合でも、クリップボードと対話するため組み込みのコマンドレットがありません。

    • 回避策は、プラットフォーム固有のユーティリティまたはAPIを使用することです。以下を参照してください。

私の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)はバックグラウンドで呼び出されます。
      STAモード(COMスレッドモデル)はv3以降のデフォルトですが、コマンドラインオプションを使用してMTA(マルチスレッドモード)にオプトインできることに注意してください-MTA
  • その他のすべての場合(Windows PowerShell v4-および/またはMTAモード、サポートされているすべてのプラットフォームのPowerShell Core ):

    • ウィンドウズ:
      • でコンパイルされたアドホックC#コードを介して、WindowsAPIを呼び出すAP/Invokeベースのソリューションが使用されAdd-Typeます。
    • Unixライクなプラットフォーム:ネイティブユーティリティは舞台裏で呼び出されます:
      • macOS:pbcopyおよびpbpaste
      • Linux:、利用可能xclipインストールされている場合;
        たとえば、Ubuntuでは、を使用sudo apt-get xclipしてインストールします。
  • Set-ClipboardText直接またはパイプラインから、任意のタイプのオブジェクトを入力として受け入れることができます(コンソールでレンダリングするのと同じ方法でテキストに変換されます)。

  • で呼び出して-Verbose、クリップボードにアクセスするために舞台裏でどのような手法が使用されているかを確認します。


[1]この回答の以前のバージョンでは、次のように誤って主張されていclip.exeまし
た。-クリップボードにコピーするときに常に改行を追加します(そうではありません)-stdin経由でリダイレクトされたファイル
のUTF-16 LE BOMと、入力が経由でパイプされた場合を正しく処理します(常にBOMをクリップボードにコピーします)。 <|clip.exe

于 2013-03-22T22:54:11.563 に答える
4

私はこれを行う方法をブログに書きました:

http://www.nivot.org/2009/10/14/PowerShell20GettingAndSettingTextToAndFromTheClipboard.aspx

-オシーン

于 2009-10-14T15:54:17.667 に答える
1

最初にホストを確認する必要があります。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スレッドを使用してパーティーを開く準備ができているとは思いません。

于 2009-10-14T16:35:10.877 に答える
1

PowerShellクックブック: Set-ClipboardのLeeHolmeのレシピをご覧ください。atをSet-Clipboard.ps1として使用するか、PowerShell関数内にコードをドロップするだけです(これが私のPowerShellプロファイルの例です)。

このスクリプトを使用すると、パイプされた完全な出力をクリップボードに取得できます。例:

dir | Set-Clipboard

私はもともとこの答えからリー・ホームの解決策を知りました。

于 2013-01-26T19:11:43.163 に答える
0

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)
于 2019-11-25T21:05:01.587 に答える