开发者

Access clipboard in Windows batch file

开发者 https://www.devze.com 2023-03-23 14:12 出处:网络
Any idea how to access the Windows clipboard using a batch开发者_开发百科 file?To set the contents of the clipboard, as Chris Thornton, klaatu, and bunches of others have said, use %windir%\\system32\

Any idea how to access the Windows clipboard using a batch开发者_开发百科 file?


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


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


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.


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.


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.


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)


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


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


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.


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


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
0

精彩评论

暂无评论...
验证码 换一张
取 消