Eri*_*ver 11 c# powershell multithreading sta
我想将Keith Hill的Get-Clipboard和Set-Clipboard的C#实现转换为纯PowerShell作为.PSM1文件.
有没有办法在PowerShell中启动STA线程,就像他在使用剪贴板时在Cmdlet中那样?
小智 15
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()
}
Run Code Online (Sandbox Code Playgroud)
请参阅底部部分,了解跨版本,跨平台模块,该模块在PowerShell Core和Windows PowerShell v2-v4 中提供剪贴板文本支持.
试图总结事务和选项的状态为的Windows PowerShell的V5.1/PowerShell的核心 V6.1.0:
Windows PowerShell v5.0 +:使用内置 Get-Clipboard和Set-Clipboard cmdlet.
Windows PowerShell v4.0-(v1 - v4.0):没有用于与剪贴板交互的内置cmdlet,但有一些解决方法:
管道到标准命令行实用程序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-16 LE编码 ; 先运行以下命令:
$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的数据,因此需要使用BOM- 少编码.使用基于PowerShell的解决方案直接使用.NET类:
请注意,剪贴板访问只能从STA(单线程单元)模式中的线程发生 - 而不是MTA(多线程单元):
powershell.exe使用-mta开关调用来输入MTA模式).powershell.exe使用-sta开关调用来输入STA模式.PowerShell Core(多平台),从v6.1.0开始,没有用于与剪贴板交互的内置cmdlet,即使在Windows上运行也没有.
我的ClipboardText模块提供
"polyfill"功能Get-ClipboardText以及从剪贴板Set-ClipboardText获取和设置文本 ; 它们适用于Windows PowerShell v2 +以及PowerShell Core(有限制,请参见下文).
在最简单的情况下(安装了包管理模块的PSv5 +或v3/v4),您可以从提升/ 会话中的PowerShell库安装它,如下所示sudo:
Install-Module ClipboardText
Run Code Online (Sandbox Code Playgroud)
有关更多信息,包括先决条件和手动安装说明,请参阅存储库.
注意:严格来说,这些函数不是polyfill,因为它们的名称与内置cmdlet不同.但是,选择了名称后缀Text,以便明确表示这些函数仅处理文本.
代码非常感谢来自不同网站的信息,特别是@ hoge的回答(/sf/answers/110130681/)和http://techibee.com/powershell/powershell-script-to-copy-powershell-指令输出到剪贴板/ 1316
在STA模式下在Windows PowerShell v5 +上运行:
Get-Clipboard/ Set-Clipboard)在后台调用.-MTA.在所有其他情况下(Windows PowerShell v4-和/或MTA模式,所有支持的平台上的PowerShell Core):
Add-Type.pbcopy和pbpastexclip, 如果可用并已安装 ; sudo apt-get xclip安装.Set-ClipboardText可以接受任何类型的对象作为输入(然后直接或从管道接收转换为文本的方式与它们在控制台中呈现的方式相同).
调用-Verbose以查看幕后使用的技术来访问剪贴板.
[1]这个答案的早期版本错误地声称clip.exe:
- 在复制到剪贴板时总是附加换行符(它没有)
- 正确处理重定向到stdin的文件中的 UTF-16 LE BOM,<当输入通过管道传输时|(clip.exe 始终将BOM复制到剪贴板).