22

I am looking for a method to place some text onto the clipboard with VBScript. The VBScript in question will be deployed as part of our login script. I would like to avoid using anything that isn't available on a clean Windows XP system.

Edit: In answer to the questions about what this is for.

We wanted to encourage users inside our organization to use the file server to transfer documents instead of constantly sending attachments by email. One of the biggest barriers to this is that it isn't always obvious to people what the correct network path is to a file/folder. We developed a quick script, and attached it to the Windows context menu so that a user can right click on any file/folder, and get a URL that they can email to someone within our organization.

I want the URL displayed in the dialog box to also be placed onto the clipboard.

GetNetworkPath

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Zoredache
  • 37,543
  • 7
  • 45
  • 61
  • Out of curiosity, what is the purpose for putting the information into the clipboard? Could a temporary .txt file be ok for storing whatever data you're working with, that is deleted when you're done? – unrealtrip Oct 14 '08 at 18:09

15 Answers15

32

Another solution I have found that isn't perfect in my opinion, but doesn't have the annoying security warnings is to use clip.exe from a w2k3 server.

Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo hello world | clip", 0, TRUE

Example with a multiline string as per question below : Link1

Dim string
String = "text here" &chr(13)& "more text here"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c echo " & String & " | clip", 0, TRUE
Zoredache
  • 37,543
  • 7
  • 45
  • 61
  • 2
    It's wonderful! But what about put a multiline variable instead of 'hello world' ? – Marco Panichi May 07 '12 at 07:23
  • 1
    Just checked - clip is available on Windows 7. – cup Jan 18 '14 at 16:59
  • 2
    this will fail because there is not way to pass *lots* of chars in a CMD shell argument list... for example "http://x.com/?var1&var2" the `&` will break that script. – gcb May 06 '14 at 19:30
  • @gcb yup, you are right. That wasn't part of my original answer, someone from the community edited that in. I agree there are many string values that could be passed that would result in it breaking. Any ideas about how we could fix the example to actually work with arbitrary values? – Zoredache May 06 '14 at 19:39
  • Works with Windows 10 :) THX – Thorsten Niehues Oct 20 '15 at 09:33
  • just wanted to provide a **thank you** like the others. I needed a way to copy my windows 10 key from to the clipboard so I could paste it. As the code that I found online, for converting product id to windows key, only wanted to display the key in a message box. This of course meant you had to manually copy it from the box. Now with this, I run the code modified with your solution and then I can just perform a paste. If i can find that posting again, I am for sure going to mention that people should head over to your solution also. thanks again. – famousKaneis Oct 05 '16 at 03:25
  • Look deeper at the answers. There is an answer marked as accepted. I choose the answer I did since I think most of the other answers, including mine are kinda hacky. – Zoredache Dec 19 '22 at 17:56
15

Using Microsoft's clip.exe is the closest to having a clean Windows XP system solution. However you don't have to call CMD.EXE to host it in order to use it. You can call it directly and write to its input stream in your script code. Once you close the input stream clip.exe will write the contents straight to the clipboard.

Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("clip")
Set oIn = oExec.stdIn
oIn.WriteLine "Something One"
oIn.WriteLine "Something Two"
oIn.WriteLine "Something Three"
oIn.Close

If you need to wait for clip to be finished before your script can continue processing then add

' loop until we're finished working.
Do While oExec.Status = 0
    WScript.Sleep 100
Loop

And don't forget to release your objects

Set oIn = Nothing
Set oExec = Nothing
klaatu
  • 219
  • 2
  • 3
  • 1
    Fantastic answer, but setting objects to Nothing is almost always pointless. http://blogs.msdn.com/b/ericlippert/archive/2004/04/28/when-are-you-required-to-set-objects-to-nothing.aspx – Tmdean Apr 27 '15 at 18:22
  • 1
    @Tmdean not true especially in terms of database tasks, you don't want resources to be left open after they are no longer needed. What Eric is talking about is usage inside functions that have their own scope, as they go out of the scope the objects will be destroyed so no need to manually de-reference them. – user692942 Nov 21 '16 at 11:38
11

The closest solution I have found so far is a method to use IE to get and set stuff on the clipboard. The problem with this solution is the user gets security warnings. I am tempted to move 'about:blank' to the local computer security zone so I don't get the warnings, but I am not sure what the security implications of that would be.

Set objIE = CreateObject("InternetExplorer.Application")
objIE.Navigate("about:blank")
objIE.document.parentwindow.clipboardData.SetData "text", "Hello This Is A Test"
objIE.Quit

http://www.microsoft.com/technet/scriptcenter/resources/qanda/dec04/hey1215.mspx

Zoredache
  • 37,543
  • 7
  • 45
  • 61
  • http://stackoverflow.com/a/21239166/185851 shows you how to use IE and a temporary file in order to copy text onto the clipboard without generating a pop-up warning. – Richard Jan 20 '14 at 16:29
9

No security warnings, full let and get access:

'create a clipboard thing
 Dim ClipBoard
 Set Clipboard = New cClipBoard

 ClipBoard.Clear  
 ClipBoard.Data = "Test"

Class cClipBoard
        Private objHTML

                Private Sub Class_Initialize
                        Set objHTML = CreateObject("htmlfile")
                End Sub

                Public Sub Clear()
                        objHTML.ParentWindow.ClipboardData.ClearData()
                End Sub

                Public Property Let Data(Value)
                        objHTML.ParentWindow.ClipboardData.SetData "Text" , Value
                End Property

                Public Property Get Data()
                        Data = objHTML.ParentWindow.ClipboardData.GetData("Text")
                End Property

                Private Sub Class_Terminate
                        Set objHTML = Nothing
                End Sub

End Class

Example Usage.

' Create scripting object
Dim WShell, lRunUninstall
Set WShell = CreateObject("WScript.Shell")
WShell.sendkeys "^c"
WScript.Sleep 250
bWindowFound = WShell.AppActivate("Microsoft Excel")
 WShell.sendkeys ClipBoard.Data
swyx
  • 2,378
  • 5
  • 24
  • 39
  • This worked for me. Shorter version: https://microsoft.public.scripting.vbscript.narkive.com/nNLRUHlK/turning-clipboard-contents-into-a-variable-in-a-vbs-file – Justin Putney Oct 28 '20 at 18:35
8

To avoid the security warnings associated with Internet Explorer and clipboard access, I would recommend you use the Word application object and its methods to put your data onto the clipboard. Of course you can only use this on a machine that has MS Word installed, but these days that's most of them. (*In spite of the fact that you asked for stuff on a 'clean' system :) *)

' Set what you want to put in the clipboard '
strMessage = "Imagine that, it works!"

' Declare an object for the word application '
Set objWord = CreateObject("Word.Application")

' Using the object '
With objWord
   .Visible = False         ' Don't show word '
   .Documents.Add           ' Create a document '
   .Selection.TypeText strMessage   ' Put text into it '
   .Selection.WholeStory        ' Select everything in the doc '
   .Selection.Copy          ' Copy contents to clipboard '
   .Quit False          ' Close Word, don't save ' 
End With

You can find detail on the MS Word application object and its methods here: http://msdn.microsoft.com/en-us/library/aa221371(office.11).aspx

unrealtrip
  • 670
  • 4
  • 13
5

Microsoft doesn't give a way for VBScript to directly access the clipboard. If you do a search for 'clipboard'on this site you'll see:

Although Visual Basic for Applications supports the Screen, Printer, App, Debug, Err, and Clipboard objects, VBScript supports only the Err object. Therefore, VBScript does not allow you to access such useful objects as the mouse pointer or the clipboard. You can, however, use the Err object to provide runtime error handling for your applications.

So using notepad indirectly is probably about the best you'll be able to do with just VBScript.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tloach
  • 8,009
  • 1
  • 33
  • 44
5

Here's another version of using the "clip" command, which avoids adding a carriage return, line feed to the end of the string:

strA= "some character string"

Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "cmd /C echo . | set /p x=" & strA & "| c:\clip.exe", 2

s = "String: """ & strA & """ is on the clipboard."
Wscript.Echo s

I've only tested this in XP. clip.exe was downloaded from Link and placed in C:\.

Peter Talbot
  • 51
  • 1
  • 1
4

I've found a way to copy multi line information to clipboard by vbscript/cmd.

Sequence:

  • with VBS generate the final "formatted string" that you need copy to clipboard
  • generate a (txt) file with the "formatted string"
  • use type command from cmd to paste information to clip by pipe

Example script:

Function CopyToClipboard( sInputString )

    Dim oShell: Set oShell = CreateObject("WScript.Shell")
    Dim sTempFolder: sTempFolder = oShell.ExpandEnvironmentStrings("%TEMP%")
    Dim sFullFilePath: sFullFilePath = sTempFolder & "\" & "temp_file.txt"

    Const iForWriting = 2, bCreateFile = True
    Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
    With oFSO.OpenTextFile(sFullFilePath, iForWriting, bCreateFile)
        .Write sInputString
        .Close
    End With

    Const iHideWindow = 0, bWaitOnReturnTrue = True
    Dim sCommand: sCommand = "CMD /C TYPE " & sFullFilePath & "|CLIP"
    oShell.Run sCommand, iHideWindow, bWaitOnReturnTrue

    Set oShell = Nothing
    Set oFSO = Nothing

End Function

Sub Main

    Call CopyToClipboard( "Text1" & vbNewLine & "Text2" )

End Sub

Call Main
n3rd4i
  • 183
  • 1
  • 4
3

The easiest way is to use built-in mshta.exe functionality:

sText = "Text Content"
CreateObject("WScript.Shell").Run "mshta.exe ""javascript:clipboardData.setData('text','" & Replace(Replace(sText, "\", "\\"), "'", "\'") & "');close();""", 0, True

To put to clipboard a string containing double quote char ", use the below code:

sText = "Text Content and double quote "" char"
CreateObject("WScript.Shell").Run "mshta.exe ""javascript:clipboardData.setData('text','" & Replace(Replace(Replace(sText, "\", "\\"), """", """"""), "'", "\'") & "'.replace('""""',String.fromCharCode(34)));close();""", 0, True
omegastripes
  • 12,351
  • 4
  • 45
  • 96
2

Take a look at this post. It describes a hacky approach to read from the clipboard, but I imagine it could be adapted to also write to the clipboard as well, such as changing the Ctrl+V to Ctrl+A then Ctrl+C.

GreenGiant
  • 4,930
  • 1
  • 46
  • 76
2

I devised another way to use IE and yet avoid security warnings...

By the way.. this function is in JavaScript.. but u can easily convert it to VBScript..

function CopyText(sTxt) {
    var oIe = WScript.CreateObject('InternetExplorer.Application');
    oIe.silent = true;
    oIe.Navigate('about:blank');
    while(oIe.ReadyState!=4) WScript.Sleep(20);
    while(oIe.document.readyState!='complete') WSript.Sleep(20);
    oIe.document.body.innerHTML = "<textarea id=txtArea wrap=off></textarea>";
    var oTb = oIe.document.getElementById('txtArea');
    oTb.value = sTxt;
    oTb.select();
    oTb = null;
    oIe.ExecWB(12,0);
    oIe.Quit();
    oIe = null;
}
Srikanth P
  • 41
  • 1
  • This works, got my vote. I don't know why people vote this down, the only downside is that it takes a few miliseconds to initialize the IE instance..but other than that, great! Note to others: If you like javascript, and are on windows, then jscript is definately worth a look, in few words its' a javascript edition of vbscript. – Jakob Sternberg Oct 29 '13 at 17:12
2

Here is Srikanth's method translated into vbs

function SetClipBoard(sTxt)
    Set oIe = WScript.CreateObject("InternetExplorer.Application")
    oIe.silent = true
    oIe.Navigate("about:blank")
    do while oIe.ReadyState <> 4
        WScript.Sleep 20
    loop

    do while oIe.document.readyState <> "complete"
        WScript.Sleep 20
    loop

    oIe.document.body.innerHTML = "<textarea id=txtArea wrap=off></textarea>"
    set oTb = oIe.document.getElementById("txtArea")
    oTb.value = sTxt
    oTb.select
    set oTb = nothing
    oIe.ExecWB 12,0
    oIe.Quit
    Set oIe = nothing
End function


function GetClipBoard()
    set oIe = WScript.CreateObject("InternetExplorer.Application")
    oIe.silent = true
    oIe.Navigate("about:blank")
    do while oIe.ReadyState <> 4
        WScript.Sleep 20
    loop

    do while oIe.document.readyState <> "complete"
        WScript.Sleep 20
    loop 

    oIe.document.body.innerHTML = "<textarea id=txtArea wrap=off></textarea>"
    set oTb = oIe.document.getElementById("txtArea")
    oTb.focus   
    oIe.ExecWB 13,0
    GetClipBoard = oTb.value
    oTb.select
    set oTb = nothing
    oIe.Quit
    Set oIe = nothing
End function
1

In your Class ClipBoard, neither the Clear sub nor the Let Data sub work. I mean they have no effect on Windows Clipboard. Actually, and ironically so, the only sub that works is the one you have not included in your example, that is Get Data! (I have tested this code quite a few times.)

However, it's not your fault. I have tried to copy data to clipboard with ClipboardData.SetData and it's impossible. At least not by creating an "htmlfile" object. Maybe it works by creating an instance of "InternetExplorer.Application" as I have seen in a few cases, but I have not tried it. I hate creating application instances for such simple tasks!

Alkis

Alkis
  • 49
  • 5
0

If it's just text can't you simply create a text file and read in the contents when you need it?

Another alternative and clearly a kludge, would be to use the SendKeys() method.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeffery Hicks
  • 301
  • 1
  • 5
0

No security warnings and no carriage return at the end of line

' value to put in Clipboard
mavaleur = "YEAH"

' current Dir
path = WScript.ScriptFullName
GetPath = Left(path, InStrRev(path, "\"))

' Put the value in a file
Set objFSO=CreateObject("Scripting.FileSystemObject")
outFile=GetPath & "fichier.valeur"
Set objFile = objFSO.CreateTextFile(outFile,True)
objFile.Write mavaleur
objFile.Close

' Put the file in the Clipboard
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "cmd.exe /c clip < " & outFile, 0, TRUE

' Erase the file
Set objFSO = CreateObject("Scripting.FileSystemObject")
objFSO.DeleteFile outFile
cmoiquoi
  • 1
  • 2