Access clipboard in Windows batch file
Asked Answered
B

12

34

Any idea how to access the Windows clipboard using a batch file?

Benignity answered 26/7, 2011 at 15:6 Comment(5)
possible duplicate of how to pass clipboard to batch in xpRoomy
Can you give us the scenario/reason you are trying to find this out?Cerise
I want to be able to highlight text from a web browser, copy it to the clipboard, then run a batch file that parses the clipboard text, formats it, then adds the formatted text to a specific file based on keywords in the clipboard text. I'd rather not use a third party application and just access the clipboard straight from the batch file.Benignity
You can't do that directly. However, you could open Notepad to paste the text and save it to a disk file, that CAN be processed by the batch file...Wellordered
superuser.com/questions/1049363/…Sheriff
O
29

To set the contents of the clipboard, as Chris Thornton, klaatu, and bunches of others have said, use %windir%\system32\clip.exe.


Update 2:

For a quick one-liner, you could do something like this:

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

Capture and parse with a for /F loop if needed. This will not execute as quickly as the JScript solution below, but it does have the advantage of simplicity.


Updated solution:

Thanks Jonathan for pointing to the capabilities of the mysterious htmlfile COM object for retrieving the clipboard. It is possible to invoke a batch + JScript hybrid to retrieve the contents of the clipboard. In fact, it only takes one line of JScript, and a cscript line to trigger it, and is much faster than the PowerShell / .NET solution offered earlier.

@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'));

Old solution:

It is possible to retrieve clipboard text from the Windows console without any 3rd-party applications by using .NET. If you have powershell installed, you can retrieve the clipboard contents by creating an imaginary textbox and pasting into it. (Source)

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

If you don't have powershell, you can still compile a simple .NET application to dump the clipboard text to the console. Here's a C# example. (Inspiration)

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

Here's a batch script that combines both methods. If powershell exists within %PATH%, use it. Otherwise, find the C# compiler / linker and build a temporary .NET application. As you can see in the batch script comments, you can capture the clipboard contents using a for /f loop or simply dump them to the console.

:: 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
Okinawa answered 1/4, 2013 at 16:15 Comment(3)
WARNING WARNING WARNING - Powershell TextBox only holds 32,767 characters, and the $tb.Paste() command will just truncate with no warning. The JavaScript solution didn't seem to have this limitation.Grenadines
Note: This answer deals with accessing text content in the clipboard. It's also possible to interact with the file drop list via Batch + PowerShell polyglot for file / folder copypaste operations. See https://mcmap.net/q/271384/-can-copy-amp-paste-be-emulated-in-windows-cmd for details.Okinawa
Obviously, to update the clipboard, you can use powershell -sta "add-type -as System.Windows.Forms; [windows.forms.clipboard]::SetText(\"new text\")"Guenzi
Y
7

Slimming it down (on a new enough version of Windows):

set _getclip=powershell "Add-Type -Assembly PresentationCore;[Windows.Clipboard]::GetText()"
for /f "eol=; tokens=*" %I in ('%_getclip%') do set CLIPBOARD_TEXT=%I
  1. First line declares a powershell commandlet.
  2. Second line runs and captures the console output of this commandlet into the CLIPBOARD_TEXT enviroment variable (cmd.exe's closest way to do bash style backtick ` capture)

Update 2017-12-04:

Thanks to @Saintali for pointing out that PowerShell 5.0 adds Get-Clipboard as a top level cmdlets, so this now works as a one liner:

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

Yeta answered 18/2, 2015 at 9:54 Comment(5)
When I try this I get an error: Exception calling "GetText" with "0" argument(s): "Current thread must be set to single thread apartment (STA) mode before OLE calls can be made.", "At line:1 char:65 + Add-Type -Assembly PresentationCore;[Windows.Clipboard]::GetText <<<< ()", "+ CategoryInfo: NotSpecified: (:) [], MethodInvocationException", "+ FullyQualifiedErrorId : DotNetMethodException"Estranged
@KevinFegan I can't repro. I guess my console is STA. Can you give context, I want to improve my answerYeta
Oddly, now, when I execute your 2 lines, it completes without error (although "%CLIPBOARD_TEXT%" is empty). When I run: powershell "Add-Type -Assembly PresentationCore;[Windows.Clipboard]::GetText()", I get the error message I described above (in red).Estranged
The first line can be simplified to set _getclip=powershell Get-ClipboardEpenthesis
For a batch file it should be for /f "eol=; tokens=*" %%I in ('powershell Get-Clipboard') do set CLIPBOARD_TEXT=%%ICanvas
C
3

The clip command is good to pipe text to the clipboard, but it can't read from the clipboard. There is a way in vbscript / javascript to read / write the clipboard but it uses automation and an invisible instance if Internet Explorer to do it so its pretty fat.

The best tool I've found for working the clipboard from script is Nirsoft's free NirCmd tool.

http://www.nirsoft.net/utils/nircmd.html

Its like a swiss army knife of batch commands all in one small .exe file. For clipboard commands you would say someting like

nircmd clipboard [Action] [Parameter]

Plus you can directly refer to clipboard contents in any of its commands using its ~$clipboard$ variable as an argument. Nircmd also has commands in it to run other programs or commands from so it is possible to use it to pass the clipboard contents as an argument to other batch commands this way.

Clipboard actions:

      set - set the specified text into the clipboard. 
 readfile - set the content of the specified text file into the clipboard. 
    clear - clear the clipboard. 
writefile - write the content of the clipboard to a file. (text only) 
  addfile - add the content of the clipboard to a file. (text only) 
saveimage - Save the current image in the clipboard into a file. 
copyimage - Copy the content of the specified image file to the clipboard. 
  saveclp - Save the current clipboard data into Windows .clp file. 
  loadclp - Load Windows .clp file into the clipboard. 

Note that most programs will always write a plain text copy to the clipboard even when they are writing a special RTF or HTML copy to the clipboard but those are written as content using a different clipboard format type so you may not be able to access those formats unless your program explicitly requests that type of data from the clipboard.

Cruciferous answered 15/5, 2012 at 21:3 Comment(0)
N
2

Best way I know, is by using a standalone tool called WINCLIP .

You can get it from here: Outwit

Usage:

  • Save clipboard to file: winclip -p file.txt

  • Copy stdout to clipboard: winclip -c Ex: Sed 's/find/replace/' file | winclip -c

  • Pipe clipboard to sed: winclip -p | Sed 's/find/replace/'

  • Use winclip output (clipboard) as an argument of another command:

    FOR /F "tokens=* usebackq" %%G in ('winclip -p') Do (YOUR_Command %%G ) Note that if you have multiple lines in your clipboard, this command will parse them one by one.

You might also want to take a look at getclip & putclip tools: CygUtils for Windows but winclip is better in my opinion.

Noyade answered 5/3, 2019 at 4:47 Comment(0)
Y
2

An example batch file that is working in win 11, I had to read several answers in this topic to find the solution and get the clipboard. The specific application is YouTube download of the URL in the clipboard.

@echo off

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

youtube-dl -f 18 %CLIPBOARD_TEXT%

pause
Yammer answered 10/6, 2023 at 19:44 Comment(0)
P
1

With Vista or higher, it's built in. Just pipe output to the "clip" program. Here's a writeup (by me): http://www.clipboardextender.com/general-clipboard-use/command-window-output-to-clipboard-in-vista The article also contains a link to a free utility (written by Me, I think) called Dos2Clip, which can be used on XP.

EDIT: I see that I've gotten the question backwards, my solution OUTPUTS to the clipboard, doesn't read it. sorry!

Update: Along with Dos2Clip, is Clip2Dos (in the same zip), which will send the clipboard text to stdout. So this should work for you. Pascal source is included in the zip.

Pulp answered 26/7, 2011 at 21:33 Comment(0)
A
1

To retrive clipboard content from your batch script: there is no "pure" batch solution.

If you want an embed 100% batch solution, you will need to generate the other language file from your batch.

Here is a short and batch embed solution which generate a VB file (Usually installed on most windows)

Affiance answered 3/12, 2014 at 17:6 Comment(3)
I like the use of the htmlfile COM object as a solution, but I can't find any documentation for it. My Google-fu is failing me. Any clue where I can find a full list of the htmlfile properties and methods?Okinawa
With PowerShell, use $g = New-Object -ComObject htmlfile and $g | Get-Member be warned there is a lot of lines returned.Disinclination
@Okinawa found something better msdn.microsoft.com/en-us/library/…Disinclination
O
1

Since all answers are confusing, here my code without delays or extra windows to open stream link copied from clipboard:

@ECHO OFF
//Name of TEMP TXT Files
SET TXTNAME=CLIP.TXT
//VBA SCRIPT
:: VBS SCRIPT
ECHO.Set Shell = CreateObject("WScript.Shell")>_TEMP.VBS
ECHO.Set HTML = CreateObject("htmlfile")>>_TEMP.VBS
ECHO.TXTPATH = "%TXTNAME%">>_TEMP.VBS
ECHO.Set FileSystem = CreateObject("Scripting.FileSystemObject")>>_TEMP.VBS 
ECHO.Set File = FileSystem.OpenTextFile(TXTPATH, 2, true)>>_TEMP.VBS
ECHO.File.WriteLine HTML.ParentWindow.ClipboardData.GetData("text")>>_TEMP.VBS
ECHO.File.Close>>_TEMP.VBS
cscript//nologo _TEMP.VBS

:: VBS CLEAN UP
DEL _TEMP.VBS

SET /p streamURL=<%TXTNAME%

DEL %TXTNAME%

:: 1) The location of Player
SET mvpEXE="D:\Tools\Programs\MVP\mpv.com"

:: Open stream to video player
%mvpEXE% %streamURL%


@ECHO ON
Osmanli answered 3/10, 2015 at 19:2 Comment(0)
E
1

Piping output to the clipboard is provided by clip, as others have said. To read input from the clipboard, use the pclip tool in this bundle. And there's tons of other good stuff in there.

So for example, you're going through an online tutorial and you want to create a file with the contents of the clipboard...

c:\>pclip > MyNewFile.txt

or you want to execute a copied command...

c:\>pclip | cmd
Exum answered 3/3, 2016 at 10:14 Comment(0)
P
1

Here's one way with mshta:

@echo off
:printClip
for /f "usebackq tokens=* delims=" %%i in (
   `mshta "javascript:Code(close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(clipboardData.getData('Text'))));"`
) do (
 echo cntent of the clipboard:
 echo %%i
)

the same thing for accessing it directly from console:

for /f "usebackq tokens=* delims=" %i in (`mshta "javascript:Code(close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(clipboardData.getData('Text'))));"`) do @echo %i
Paralytic answered 11/11, 2020 at 12:45 Comment(0)
P
0

This might not be the exact answer, but it will be helpful for your Quest.

Original post: Visit https://groups.google.com/d/msg/alt.msdos.batch/0n8icUar5AM/60uEZFn9IfAJ Asked by Roger Hunt Answered by William Allen


Much Cleaner Steps:

Step 1) create a 'bat' file named Copy.bat in desktop using any text editors and copy and past below code and save it.

  @ECHO OFF
  SET FN=%1
  IF ()==(%1) SET FN=H:\CLIP.TXT

  :: Open a blank new file
  REM New file>%FN%

  ECHO.set sh=WScript.CreateObject("WScript.Shell")>_TEMP.VBS
  ECHO.sh.Run("Notepad.exe %FN%")>>_TEMP.VBS
  ECHO.WScript.Sleep(200)>>_TEMP.VBS
  ECHO.sh.SendKeys("^+{end}^{v}%%{F4}{enter}{enter}")>>_TEMP.VBS
  cscript//nologo _TEMP.VBS

  ECHO. The clipboard contents are:
  TYPE %FN%

  :: Clean up
  DEL _TEMP.VBS
  SET FN=

Step 2) create a Blank text file (in my case 'CLIP.txt' in H Drive) or anywhere, make sure you update the path in Copy.bat file under 'FN=H:\CLIP.txt' with your destination file path.

That's it.

So, basically when you copy any text from anywhere and run Copy.bat file from desktop, it updates CLIP.txt file with the Clipboard contents in it and saves it.

Uses:

I use it to transfer data from remotely connected machines where copy/paste is disabled between different connections; where shared drive (H:) is common to all Connections.

Pankhurst answered 17/11, 2014 at 14:5 Comment(0)
S
0

Multiple lines

The problem is resolved, but disappointment remains.

I was forced to split one command into two.

First of them well understands the text and service characters, but does not understand the backspace.

The second understands backspace, but does not understand many service characters.

Can anyone unite them?

Notepad ++, in the place where it should open, is commented out because sometimes the window does not get access to enter characters and therefore you need to make sure that it is active.

Of course, it is better to enter characters using the PID of the notebook process, but ...

The request from wmic opens for a long time, so do not close the notepad window until the bat file is closed.

    @echo off
    set "like=Microsoft Visual C++"
    set "flag=0"
    start /max C:\"Program Files\Notepad++\notepad++.exe" -nosession -multiInst
    ( set LF=^
    %= NEWLINE =%
    )
    set ^"NL=^^^%LF%%LF%^%LF%%LF%^^"
    ::------------------
    setlocal enabledelayedexpansion
    for /f "usebackq delims=" %%i in ( `wmic /node:"papa" product where "Name like '%%%like%%%'" get * ^| findstr /r /v "^$"`) do (
        for /f tokens^=1^ delims^=^" %%a in ("%%i") do set str=%%a
        if "!flag!"=="0" ( 
            ::start /max C:\"Program Files\Notepad++\notepad++.exe" -nosession -multiInst& set "flag=1" 
            for /f "delims=" %%i in ('mshta "javascript:new         ActiveXObject('WScript.Shell').SendKeys('{BS}{BS}{BS}{BS}');close(new         ActiveXObject('Scripting.FileSystemObject'));"') do set   
            set flag=1
        )
        @set /P "_=%%str%%"<NUL|clip
        for /f "delims=" %%i in ('mshta "javascript:new         ActiveXObject('WScript.Shell').SendKeys('^v');close(new         ActiveXObject('Scripting.FileSystemObject'));"') do set
        (echo %%NL%%)|clip  
        for /f "delims=" %%i in ('mshta "javascript:new         ActiveXObject('WScript.Shell').SendKeys('^v');close(new         ActiveXObject('Scripting.FileSystemObject'));"') do set 
    )
    setlocal disabledelayedexpansion
Shirleenshirlene answered 28/5, 2020 at 18:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.