C# 转换基思山';s PowerShell获取剪贴板并将剪贴板设置为PSM1脚本
我想将Keith Hill的Get Clipboard和Set Clipboard的C#实现转换为纯PowerShell的.PSM1文件 在使用剪贴板时,有没有办法像在Cmdlet中那样在PowerShell中启动STA线程C# 转换基思山';s PowerShell获取剪贴板并将剪贴板设置为PSM1脚本,c#,powershell,multithreading,sta,C#,Powershell,Multithreading,Sta,我想将Keith Hill的Get Clipboard和Set Clipboard的C#实现转换为纯PowerShell的.PSM1文件 在使用剪贴板时,有没有办法像在Cmdlet中那样在PowerShell中启动STA线程 我刚刚在博客上写了如何做到这一点: -在中,您应该首先检查主机。ISE已经运行了STA,因此无需启动另一个线程或外壳(这是一个优化,在我的PSCX待办事项列表中)。对于控制台提示,即MTA,我将使用二进制代码,如Oisin所示,或者使用一个简单的小C#应用程序,如: u
我刚刚在博客上写了如何做到这一点:
-在中,您应该首先检查主机。ISE已经运行了STA,因此无需启动另一个线程或外壳(这是一个优化,在我的PSCX待办事项列表中)。对于控制台提示,即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线程
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()
}
看看PowerShell食谱中的Lee Holme食谱:。您可以将at用作Set-Clipboard.ps1,也可以将代码放在PowerShell函数中(从我的PowerShell配置文件中) 该脚本将允许您将完整的管道输出获取到剪贴板,例如:
dir | Set-Clipboard
我最初是从了解到Lee Holme的解决方案的。有关在PowerShell Core和Windows PowerShell v2-v4中提供剪贴板文本支持的解决方案,请参见底部部分
尝试总结自Windows PowerShell v5.1/PowerShell Core v6.1.0以来的状态和选项:
Install-Module ClipboardText
- Windows PowerShell v5.0+:使用内置和cmdlet
- Windows PowerShell v4.0-(v1-v4.0):没有用于与剪贴板交互的内置cmdlet
Install-Module ClipboardText
- 使用PowerShell社区扩展(PSCX;),它附带了几个与剪贴板相关的cmdlet,这些cmdlet不仅仅用于处理文本
- 管道到标准命令行实用程序
(W2K3+服务器端、Vista+客户端)[1]:clip.exe
- 注:除了下面讨论的编码问题外,
总是在输入后追加一个尾随的换行符;避免这种情况的唯一方法是使用一个临时文件,其内容是通过PowerShell 5中的cmd的…|clip.exe
提供的,我们现在有了
和获取剪贴板
在Windows Server 2012 R2上,我们只有PowerShell 4,我可以使用.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)
这不适用于$text的大值。无法执行程序“powershell.exe”:文件名或扩展名太长。好吧,我想还是坚持使用二进制cmdlet,或者直接使用剪贴板方法(或者使用默认为STA模式的ISE)启动powershell.exe本身,或者,您可以修改我的函数,从临时文件读取/写入。我刚刚更新了我的博客文章,使用临时文件-这避免了您的问题。现在对文本大小没有限制。与其在子powershell进程中调用[windows.forms.clipboard]::SetText(),不如使用clip.exe更有效。在这一点上,我不妨使用C#cmdlet。考虑到线程限制,这似乎是最好的方法。有没有办法在STA线程上启动作业?嘿,我只是在查看作业文档,没有发现任何可以让你控制作业属性的内容。我开始工作时会尝试一下。好主意,但很有效。。。只需在脚本中添加一行代码,以确保加载System.Windows.Forms。呵呵,这是不断升级的技术。好的,我的下一篇文章将是一个多格式剪贴板模块,没有临时文件,可以处理的不仅仅是文本。
- 注:除了下面讨论的编码问题外,