Use el portapapeles de VBScript

Estoy buscando un método para colocar texto en el portapapeles con VBScript . El VBScript en cuestión se implementará como parte de nuestro script de inicio de sesión. Me gustaría evitar el uso de cualquier cosa que no esté disponible en un sistema limpio de Windows XP.

Editar: En respuesta a las preguntas sobre para qué es esto.

Queríamos alentar a los usuarios de nuestra organización a utilizar el servidor de archivos para transferir documentos en lugar de enviar archivos adjuntos constantemente por correo electrónico. Una de las mayores barreras para esto es que no siempre es obvio para las personas cuál es la ruta de red correcta para un archivo / carpeta. Desarrollamos un guión rápido y lo adjuntamos al menú contextual de Windows para que un usuario pueda hacer clic derecho en cualquier archivo / carpeta y obtener una URL que pueda enviar por correo electrónico a alguien de nuestra organización.

Quiero que la URL que se muestra en el cuadro de diálogo también se coloque en el portapapeles.

GetNetworkPath

Microsoft no permite que VBScript acceda directamente al portapapeles. Si realiza una búsqueda de 'clipboard' en este sitio, verá:

Aunque Visual Basic para Aplicaciones admite los objetos Pantalla, Impresora, Aplicación, Depuración, Err y Portapapeles, VBScript solo admite el objeto Err. Por lo tanto, VBScript no le permite acceder a objetos útiles como el puntero del mouse o el portapapeles. Sin embargo, puede usar el objeto Err para proporcionar un manejo de errores de tiempo de ejecución para sus aplicaciones.

Entonces, usar el bloc de notas indirectamente es probablemente lo mejor que puedes hacer con solo VBScript.

Otra solución que he encontrado que no es perfecta en mi opinión, pero que no tiene las advertencias de seguridad molestas es usar clip.exe de un servidor w2k3.

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

http://www.petri.co.il/quickly_copy_error_and_display_messages.htm

Ejemplo con una cadena multilínea según la pregunta a continuación

 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 

La solución más cercana que he encontrado hasta ahora es un método para usar IE para obtener y configurar cosas en el portapapeles. El problema con esta solución es que el usuario recibe advertencias de seguridad. Estoy tentado de moverme ‘en blanco’ a la zona de seguridad informática local para no recibir las advertencias, pero no estoy seguro de cuáles serían las implicaciones de seguridad de eso.

 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

Usar el clip.exe de Microsoft es lo más cercano a tener una solución limpia de sistema de Windows XP. Sin embargo, no es necesario llamar a CMD.EXE para alojarlo para poder usarlo. Puede llamarlo directamente y escribir en su flujo de entrada en su código de secuencia de comandos. Una vez que cierre la secuencia de entrada, clip.exe escribirá los contenidos directamente en el portapapeles.

 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 

Si necesita esperar a que el clip finalice antes de que su script pueda seguir procesando, agregue

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

Y no olvides lanzar tus objetos

 Set oIn = Nothing Set oExec = Nothing 

Para evitar las advertencias de seguridad asociadas con Internet Explorer y el acceso al portapapeles, le recomendaría que use el objeto de la aplicación Word y sus métodos para poner sus datos en el portapapeles. Por supuesto, solo puede usar esto en una máquina que tenga instalado MS Word, pero en la actualidad es la mayoría de ellos. (* A pesar de que solicitaste cosas en un sistema “limpio” 🙂 *)

 ' 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 

Puede encontrar detalles sobre el objeto de la aplicación MS Word y sus métodos aquí: http://msdn.microsoft.com/en-us/library/aa221371(office.11).aspx

Aquí hay otra versión del uso del comando “clip”, que evita agregar un retorno de carro, avance de línea al final de la cadena:

 strA= "some character string" 

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

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

Solo he probado esto en XP. clip.exe se descargó de http://www.petri.co.il/downloads/clip.zip y se colocó en C: \.

He encontrado una manera de copiar información de varias líneas al portapapeles mediante vbscript / cmd.

Secuencia:

  • con VBS genere la “cadena formateada” final que necesita copiar al portapapeles
  • generar un archivo (txt) con la “cadena formateada”
  • use el comando type de cmd para pegar información para clip por tubería

Script de ejemplo:

 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 

Sin advertencias de seguridad, acceso completo y acceso:

 '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 

Ejemplo de uso

 ' 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 

Inventé otra forma de usar IE y aún así evitar advertencias de seguridad …

Por cierto … esta función está en JavaScript … pero puedes convertirla fácilmente a 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 = ""; var oTb = oIe.document.getElementById('txtArea'); oTb.value = sTxt; oTb.select(); oTb = null; oIe.ExecWB(12,0); oIe.Quit(); oIe = null; } 

Aquí está el método de Srikanth traducido a 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 = "" 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 = "" 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 

La forma más fácil es usar la funcionalidad incorporada de mshta.exe :

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

Para poner en el portapapeles una cadena que contenga una comilla doble " , use el siguiente código:

 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 

Echa un vistazo a esta publicación . Describe un enfoque raro para leer desde el portapapeles, pero imagino que podría adaptarse para escribir también en el portapapeles, como cambiar Ctrl + V a Ctrl + A y luego Ctrl + C.

En su Class ClipBoard , ni el subpaso Clear ni el submenú Let Data funcionan. Quiero decir que no tienen ningún efecto en el Clipboard Windows. En realidad, e irónicamente, el único submarino que funciona es el que no ha incluido en su ejemplo, ¡es Get Data! (He probado este código bastantes veces).

Sin embargo, no es tu culpa. Intenté copiar datos en el portapapeles con ClipboardData.SetData y es imposible. Al menos no creando un objeto “htmlfile”. Tal vez funcione creando una instancia de “InternetExplorer.Application” como he visto en algunos casos, pero no lo he intentado. ¡Odio crear instancias de aplicaciones para tareas tan simples!

Alkis

Si solo se trata de texto, ¿no puede simplemente crear un archivo de texto y leer en el contenido cuando lo necesite?

Otra alternativa y claramente un kludge, sería usar el método SendKeys() .

Sin advertencias de seguridad y sin devolución de carro al final de la línea

 ' 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