Je voudrais convertir l’implémentation C # de Get-Clipboard et Set-Clipboard en Keith Hill en PowerShell pur sous forme de fichier .PSM1.
Existe-t-il un moyen de créer un thread STA dans PowerShell comme il le fait dans son applet de commande lors de l’utilisation du Presse-papiers?
Le blog post
Le code
TextBox ne nécessite pas de commutateur -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)] [ssortingng] $text ) Add-Type -AssemblyName System.Windows.Forms $tb = New-Object System.Windows.Forms.TextBox $tb.Multiline = $true $tb.Text = $text $tb.SelectAll() $tb.Copy() }
Reportez-vous à la section inférieure pour connaître le module multi-édition et multiplate-forme offrant une prise en charge du texte du presse-papier dans PowerShell Core et dans Windows PowerShell v2 – v4.
Tentative de synthèse de la situation et des options de Windows PowerShell v5.1 / PowerShell Core v6.1.0 :
Windows PowerShell version 5.0 + : utilisez les applets de commande Get-Clipboard
et Set-Clipboard
intégrées.
Windows PowerShell v4.0- (v1 – v4.0): aucune applet de commande intégrée pour interagir avec le Presse-papiers , mais il existe des solutions de contournement :
Pipe vers l’ utilitaire de ligne de commande standard clip.exe
(W2K3 + côté serveur, Vista + côté client) [1]:
Remarque: Outre les problèmes d’encodage abordés ci-dessous, ... | clip.exe
... | clip.exe
ajoute invariablement une nouvelle ligne de fin à l’entrée; le seul moyen d’éviter cela consiste à utiliser un fichier temporaire dont le contenu est fourni via la redirection d’entrée <
cmd - reportez Set-ClipboardText
fonction Set-ClipboardText
ci Set-ClipboardText
dessous.
Si seul le support de caractères ASCII (7 bits) est requirejs: fonctionne par défaut.
Si seule la prise en charge du codage OEM (8 bits) (par exemple, IBM437 aux États-Unis) est nécessaire, exécutez d'abord les tâches suivantes:
$OutputEncoding = [System.Text.Encoding]::GetEncoding([System.Globalization.CultureInfo]::CurrentCulture.TextInfo.OEMCodePage)
Si un support complet Unicode est requirejs, un codage UTF-16 LE sans nomenclature doit être utilisé; lancez d'abord le suivant:
$OutputEncoding = New-Object System.Text.UnicodeEncoding $false, $false # UTF-16 encoding *without BOM*
Exemple à tester (la console PS affiche les caractères asiatiques sous la forme "??", mais les gère toujours correctement - vérifiez le contenu du Presse-papiers dans le Bloc-notes, par exemple):
"I enjoyed Thomas Hübl's talk about 中文" | clip # should appear as is on the clipboard
Remarque: L'atsortingbution à $OutputEncoding
comme ci-dessus fonctionne $OutputEncoding
dans l'étendue globale , mais pas autrement, comme dans une fonction , en raison d'un bogue de Windows PowerShell version 5.1 / PowerShell Core v6.0.0-rc.2 - voir https: //github.com/PowerShell/PowerShell/issues/5763
(New-Object ...).psobject.BaseObject
pour contourner le bogue ou - dans PSv5 + - utilisez plutôt [...]:new()
. Note: clip.exe
comprend apparemment 2 formats:
clip.exe
traite toujours une nomenclature en tant que données , d'où la nécessité d'utiliser un codage sans nomenclature. Utilisez une solution basée sur PowerShell avec utilisation directe des classes .NET :
Notez que l'access au Presse-papiers ne peut se produire qu'à partir d'un thread en mode STA (single-threaded apartment) - par opposition à MTA (multi-threaded apartment):
-mta
powershell.exe
avec le commutateur -mta
). -sta
powershell.exe
avec le commutateur -sta
. PowerShell Core (multiplate-forme), à compter de la v6.1.0 , n’a pas d’applet de commande intégré pour l’interaction avec le Presse-papiers , même lorsqu’il est exécuté sous Windows .
Le module My ClipboardText
fournit des fonctions "polyfill" Get-ClipboardText
et Set-ClipboardText
pour obtenir et définir du texte à partir du presse-papiers . ils fonctionnent sur Windows PowerShell v2 + ainsi que sur PowerShell Core (avec des limitations, voir ci-dessous).
Dans le cas le plus simple (PSv5 + ou v3 / v4 avec les modules de gestion de paquet installés), vous pouvez l' installer à partir de la galerie PowerShell à partir d'une session surélevée / sudo
comme suit :
Install-Module ClipboardText
Pour plus d'informations, y compris sur les prérequirejs et les instructions d'installation manuelle, voir le référentiel .
Remarque: À proprement parler, les fonctions ne sont pas des tâches multiples , étant donné que leurs noms diffèrent des applets de commande intégrées. Cependant, le suffixe de nom Text a été choisi de manière à indiquer explicitement que ces fonctions traitent uniquement du texte.
Le code s'appuie sur des informations provenant de différents sites, notamment la réponse de @ hoge ( https://stackoverflow.com/a/1573295/45375 ) et http://techibee.com/powershell/powershell-script-to-copy-powershell- commande-sortie-vers-presse-papiers / 1316
Sous Windows PowerShell v5 + en mode STA :
Get-Clipboard
/ Set-Clipboard
) sont appelées en arrière-plan. -MTA
. Dans tous les autres cas (Windows PowerShell v4 et / ou en mode MTA, PowerShell Core sur toutes les plateformes sockets en charge):
clip.exe
pour définir le texte et une solution WSH / JScript pour obtenir du texte. pbcopy
et pbpaste
xclip
, si disponible et installé ; sudo apt-get xclip
pour installer. Set-ClipboardText
peut accepter n'importe quel type d'object (s) en tant qu'entrée (qui est / est ensuite convertie en texte de la même manière que dans la console), directement ou à partir du pipeline.
Appelez avec -Verbose
pour voir quelle technique est utilisée en coulisse pour accéder au presse-papiers.
[1] Une version antérieure de cette réponse affirmait à tort que clip.exe
:
- ajoute toujours un saut de ligne lors de la copie dans le presse-papier (PAS)
- gère correctement les nomenclatures UTF-16 LE dans les fichiers redirigés vers stdin via <
vs lorsque l'entrée est acheminée via |
( clip.exe
copie également toujours la nomenclature dans le presse-papiers).
Je viens de bloguer comment faire cela:
http://www.nivot.org/2009/10/14/PowerShell20GettingAndSettingTextToAndFromTheClipboard.aspx
-Oisin
Vous devriez d’abord vérifier votre hôte. ISE exécute déjà STA, il n’est donc pas nécessaire de créer un autre thread ou un autre shell (optimisation figurant dans ma liste de tâches pour PSCX). Pour l’invite de la console, qui est MTA, alors je voudrais passer au code binary comme le montre Oisin ou utiliser une simple petite application C # comme:
using System; using System.Runtime.InteropServices; using System.Windows.Forms; class OutClipboard { [STAThread] static void Main() { Clipboard.SetText(Console.In.ReadToEnd()); } }
Et pour obtenir le contenu du presse-papiers, Vista et les versions ultérieures ont clip.exe.
Je ne pense pas que même les fonctions avancées 2.0 soient prêtes à laisser les gens faire la fête avec leurs propres threads .NET dans un script.
Jetez un coup d’œil à la recette de Lee Holme dans PowerShell Cookbook: Set-Clipboard . Vous pouvez utiliser at comme Set-Clipboard.ps1 ou simplement déposer le code dans une fonction PowerShell ( voici un exemple tiré de mon profil PowerShell).
Le script vous permettra d’obtenir la sortie complète de la tuyauterie dans le presse-papiers, par exemple:
dir | Set-Clipboard
J’ai initialement appris la solution de Lee Holme grâce à cette réponse .