在Windows批处理文件中访问剪贴板

ran*_*m21 25 windows clipboard batch-file

知道如何使用批处理文件访问Windows剪贴板吗?

roj*_*ojo 22

要设置剪贴板的内容,如Chris Thornton,klaatu和其他人说过,请使用%windir%\system32\clip.exe.


更新2:

对于快速单行,您可以执行以下操作:

powershell -sta "add-type -as System.Windows.Forms; [windows.forms.clipboard]::GetText()"
Run Code Online (Sandbox Code Playgroud)

for /F如果需要,捕获并使用循环进行解析.这不会像下面的JScript解决方案那样快速执行,但它确实具有简单的优点.


更新的方案:

感谢Jonathan指出htmlfile用于检索剪贴板的神秘COM对象的功能.可以调用批处理+ JScript混合来检索剪贴板的内容.实际上,它只需要一行JScr​​ipt和cscript一行来触发它,并且比之前提供的PowerShell/.NET解决方案快得多.

@if (@CodeSection == @Batch) @then

@echo off
setlocal

set "getclip=cscript /nologo /e:JScript "%~f0""

rem // If you want to process the contents of the clipboard line-by-line, use
rem // something like this to preserve blank lines:
for /f "delims=" %%I in ('%getclip% ^| findstr /n "^"') do (
    setlocal enabledelayedexpansion
    set "line=%%I" & set "line=!line:*:=!"
    echo(!line!
    endlocal
)

rem // If all you need is to output the clipboard text to the console without
rem // any processing, then remove the "for /f" loop above and uncomment the
rem // following line:
:: %getclip%

goto :EOF

@end // begin JScript hybrid chimera
WSH.Echo(WSH.CreateObject('htmlfile').parentWindow.clipboardData.getData('text'));
Run Code Online (Sandbox Code Playgroud)

旧解决方案:

通过使用.NET,可以从Windows控制台检索剪贴板文本,而无需任何第三方应用程序.如果已powershell安装,则可以通过创建虚构文本框并粘贴到其中来检索剪贴板内容.(来源)

Add-Type -AssemblyName System.Windows.Forms
$tb = New-Object System.Windows.Forms.TextBox
$tb.Multiline = $true
$tb.Paste()
$tb.Text
Run Code Online (Sandbox Code Playgroud)

如果没有powershell,您仍然可以编译一个简单的.NET应用程序来将剪贴板文本转储到控制台.这是一个C#示例.(灵感)

using System;
using System.Threading;
using System.Windows.Forms;
class dummy {
    [STAThread]
    public static void Main() {
        if (Clipboard.ContainsText()) Console.Write(Clipboard.GetText());
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个结合了这两种方法的批处理脚本.如果powershell存在%PATH%,请使用它.否则,找到C#编译器/链接器并构建一个临时的.NET应用程序.正如您在批处理脚本注释中所看到的,您可以使用for /f循环捕获剪贴板内容,或者只是将它们转储到控制台.

:: clipboard.bat
:: retrieves contents of clipboard

@echo off
setlocal enabledelayedexpansion

:: Does powershell.exe exist within %PATH%?
for %%I in (powershell.exe) do if "%%~$PATH:I" neq "" (
    set getclip=powershell "Add-Type -AssemblyName System.Windows.Forms;$tb=New-Object System.Windows.Forms.TextBox;$tb.Multiline=$true;$tb.Paste();$tb.Text"
) else (
rem :: If not, compose and link C# application to retrieve clipboard text
    set getclip=%temp%\getclip.exe
    >"%temp%\c.cs" echo using System;using System.Threading;using System.Windows.Forms;class dummy{[STAThread]
    >>"%temp%\c.cs" echo public static void Main^(^){if^(Clipboard.ContainsText^(^)^) Console.Write^(Clipboard.GetText^(^)^);}}
    for /f "delims=" %%I in ('dir /b /s "%windir%\microsoft.net\*csc.exe"') do (
        if not exist "!getclip!" "%%I" /nologo /out:"!getclip!" "%temp%\c.cs" 2>NUL
    )
    del "%temp%\c.cs"
    if not exist "!getclip!" (
        echo Error: Please install .NET 2.0 or newer, or install PowerShell.
        goto :EOF
    )
)

:: If you want to process the contents of the clipboard line-by-line, use
:: something like this to preserve blank lines:
for /f "delims=" %%I in ('%getclip% ^| findstr /n "^"') do (
    set "line=%%I" & set "line=!line:*:=!"
    echo(!line!
)

:: If all you need is to output the clipboard text to the console without
:: any processing, then remove the above "for /f" loop and uncomment the
:: following line:

:: %getclip%

:: Clean up the mess
del "%temp%\getclip.exe" 2>NUL
goto :EOF
Run Code Online (Sandbox Code Playgroud)


Ref*_*ann 5

瘦身(在足够新的 Windows 版本上):

set _getclip=powershell "Add-Type -Assembly PresentationCore;[Windows.Clipboard]::GetText()"
for /f "eol=; tokens=*" %I in ('%_getclip%') do set CLIPBOARD_TEXT=%I
Run Code Online (Sandbox Code Playgroud)
  1. 第一行声明一个powershell命令行开关。
  2. 第二行运行并将此命令行开关的控制台输出捕获到CLIPBOARD_TEXT环境变量中(cmd.exe进行bash样式反引号`捕获的最接近方法)

2017-12-04 更新:

感谢 @Saintali 指出 PowerShell 5.0 添加Get-Clipboard为顶级 cmdlet,因此现在可以作为单行代码使用:

for /f "eol=; tokens=*" %I in ('powershell Get-Clipboard') do set CLIPBOARD_TEXT=%I