The problem seems to be that clipboard lives in Gui userland, and my scripts live in Text userland. So the solution I would need to come up with would have to go to the Windows environment in order to access the abstraction that is clipboard, and bring it back to my text environment.
My first cut solution uses a pseudo-netsocket approach - spawn another process and establish two-way communication using PIDs, then paste into its windows interface, and have it send what it receives to my stdin.
It works surprisingly well (in my environment) and although ultimately I decided not to use it for my Cisco project, I have added it to my libaries for process management. Here it is with only minimal error checking for clarity.
Option Explicit
'===========================================================================
'Name: GetClipBoard() function
'Author: Philip Damian-Grint
'Version: 1.0
'Date: 28th Aug 2011
'
'Description:
'
' From a vbs script running under cscript.exe, read the contents of the
' Clipboard into a string.
'===========================================================================
Function GetClipBoard
' First we create a text file to hold our child
dim objFS : Set objFS = CreateObject("Scripting.FileSystemObject")
dim strFName : strFName = objFS.GetTempName
dim objTS : Set objTS = objFS.CreateTextFile( strFName, True )
' Our child requests her parent's PID, and then provides a paste buffer, all off-screen
objTS.WriteLine("dim pid : pid=inputbox(""PID"",,,0,-3000) : " & _
"dim str : str=inputbox(""STR"",,,0,-3000) : " & _
"set shell=wscript.createobject(""wscript.shell"") : " & _
"shell.appactivate pid : wscript.sleep 100 : " & _
"shell.sendkeys str & ""{ENTER}""")
objTS.Close
' Spawn our child as a running process
Dim objWshShell : Set objWshShell = WScript.CreateObject("WScript.Shell")
Dim objChild : Set objChild = objWshShell.exec( "cscript.exe //E:vbscript " & strFName )
Dim intChildPID : intChildPID = clng(objChild.ProcessID)
' Now use our child's PID to find our own
Dim strObjPath : strObjPath = "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2"
Dim objProcess, intParentPID
For Each objProcess In getObject( strObjPath ).instancesOf("Win32_Process")
If intChildPID = (clng(objProcess.processID)) Then
intParentPID= objProcess.parentProcessID : Exit For
End If
Next
' Find our child's first input box, and write our PID to it
Do until objWshShell.AppActivate( intChildPID )
WScript.Sleep 100
Loop : objWshShell.SendKeys intParentPID & "{ENTER}"
' Find our child's second input box, and paste the clipboard contents
Do Until objWshShell.AppActivate( intChildPID )
WScript.Sleep 100
Loop : objWshShell.SendKeys "^v{ENTER}"
' Receive the paste buffer contents from our child
GetClipBoard = WScript.StdIn.ReadLine
' And clear up after our child
objFS.DeleteFile strFName, True
End Function
' Demonstrate the function
wscript.echo "We read: " & GetClipBoard() & " from the clipboard"
This comment has been removed by a blog administrator.
ReplyDelete