从 VBScript 使用剪贴板

Posted

技术标签:

【中文标题】从 VBScript 使用剪贴板【英文标题】:Use clipboard from VBScript 【发布时间】:2010-09-12 19:26:09 【问题描述】:

我正在寻找一种使用VBScript 将一些文本放到剪贴板上的方法。有问题的 VBScript 将作为我们登录脚本的一部分进行部署。我想避免使用在干净的 Windows XP 系统上不可用的任何东西。

编辑: 回答有关此用途的问题。

我们希望鼓励我们组织内的用户使用文件服务器来传输文档,而不是不断地通过电子邮件发送附件。最大的障碍之一是人们并不总是清楚文件/文件夹的正确网络路径是什么。我们开发了一个快速脚本,并将其附加到 Windows 上下文菜单中,以便用户可以右键单击任何文件/文件夹,并获取一个 URL,他们可以通过电子邮件将其发送给我们组织内的某个人。

我希望对话框中显示的 URL 也可以放在剪贴板上。

GetNetworkPath

【问题讨论】:

出于好奇,将信息放入剪贴板的目的是什么?临时 .txt 文件是否可以用于存储您正在使用的任何数据,完成后将其删除? 【参考方案1】:

另一个我认为并不完美但没有烦人的安全警告的解决方案是使用 w2k3 服务器中的 clip.exe。

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

按照以下问题的多行字符串示例: 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

【讨论】:

太棒了!但是放置一个多行变量而不是 'hello world' 呢? 刚刚检查过 - 剪辑在 Windows 7 上可用。 这将失败,因为无法在 CMD shell 参数列表中传递 lots 的字符...例如“x.com/?var1&var2”& 将中断那个脚本。 @gcb 是的,你是对的。那不是我最初答案的一部分,社区中的某个人将其编辑了。我同意可以传递许多字符串值,这会导致它中断。关于我们如何修复示例以实际使用任意值的任何想法? 适用于 Windows 10 :) THX【参考方案2】:

使用 Microsoft 的 clip.exe 是最接近于干净的 Windows XP 系统的解决方案。但是,您不必调用 CMD.EXE 来托管它以使用它。您可以直接调用它并在脚本代码中写入其输入流。关闭输入流后,clip.exe 会将内容直接写入剪贴板。

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

如果您需要等待剪辑完成才能继续处理脚本,请添加

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

别忘了释放你的对象

Set oIn = Nothing
Set oExec = Nothing

【讨论】:

很棒的答案,但是将对象设置为 Nothing 几乎总是毫无意义的。 blogs.msdn.com/b/ericlippert/archive/2004/04/28/… @Tmdean 不正确,尤其是在数据库任务方面,您不希望资源在不再需要后保持打开状态。 Eric 所说的是在具有自己作用域的函数内部使用,当它们超出作用域时,对象将被销毁,因此无需手动取消引用它们。【参考方案3】:

到目前为止,我发现的最接近的解决方案是使用 IE 在剪贴板上获取和设置内容的方法。此解决方案的问题是用户收到安全警告。我很想将“about:blank”移动到本地计算机安全区域,所以我没有收到警告,但我不确定这会带来什么安全隐患。

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

【讨论】:

***.com/a/21239166/185851 向您展示了如何使用 IE 和临时文件将文本复制到剪贴板而不产生弹出警告。【参考方案4】:

为避免与 Internet Explorer 和剪贴板访问相关的安全警告,我建议您使用 Word 应用程序对象及其方法将数据放到剪贴板上。当然,您只能在安装了 MS Word 的机器上使用它,但现在大部分都是这样。 (*尽管您要求在“干净”系统上提供东西:) *)

' 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

您可以在此处找到有关 MS Word 应用程序对象及其方法的详细信息:http://msdn.microsoft.com/en-us/library/aa221371(office.11).aspx

【讨论】:

【参考方案5】:

没有安全警告,完全允许和获取访问权限:

'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

示例用法。

' 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

【讨论】:

这对我有用。较短的版本:microsoft.public.scripting.vbscript.narkive.com/nNLRUHlK/…【参考方案6】:

Microsoft 没有让 VBScript 直接访问剪贴板。如果您在 this 网站上搜索 'clipboard',您会看到:

虽然 Visual Basic for Applications 支持 Screen、Printer、App、Debug、Err 和 Clipboard 对象,但 VBScript 仅支持 Err 对象。因此,VBScript 不允许您访问诸如鼠标指针或剪贴板之类的有用对象。但是,您可以使用 Err 对象为您的应用程序提供运行时错误处理。

因此,间接使用记事本可能是您仅使用 VBScript 所能做的最好的事情。

【讨论】:

【参考方案7】:

这是使用“clip”命令的另一个版本,它避免在字符串末尾添加回车、换行:

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

我只在 XP 中测试过。 clip.exe是从Link下载的,放在C:\

【讨论】:

【参考方案8】:

我找到了一种通过 vbscript/cmd 将多行信息复制到剪贴板的方法。

顺序:

使用 VBS 生成您需要复制到剪贴板的最终“格式化字符串” 使用“格式化字符串”生成 (txt) 文件 使用 cmd 中的 type 命令通过管道将信息粘贴到剪辑

示例脚本:

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

【讨论】:

【参考方案9】:

最简单的方法是使用内置的mshta.exe 功能:

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

要将包含双引号字符" 的字符串放入剪贴板,请使用以下代码:

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

【讨论】:

【参考方案10】:

我设计了另一种使用 IE 并避免安全警告的方法...

顺便说一下..这个函数是用JavaScript编写的..但是你可以很容易地把它转换成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;

【讨论】:

这行得通,得到了我的投票。我不知道为什么人们对此投反对票,唯一的缺点是初始化 IE 实例需要几毫秒..但除此之外,太棒了!其他人注意:如果您喜欢 javascript,并且在 windows 上,那么 jscript 绝对值得一看,简而言之,它是 vbscript 的 javascript 版本。【参考方案11】:

这是Srikanth的方法翻译成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

【讨论】:

【参考方案12】:

看看this post。它描述了一种从剪贴板 read 的 hacky 方法,但我想它也可以适应写入剪贴板,例如将 Ctrl+V 更改为 Ctrl+A 然后 Ctrl+C。

【讨论】:

【参考方案13】:

在您的班级ClipBoard 中,Clear 子程序和 Let Data 子程序都不起作用。我的意思是它们对 Windows Clipboard 没有影响。实际上,具有讽刺意味的是,唯一有效的子程序是您的示例中未包含的子程序,即获取数据! (我已经多次测试了这段代码。)

但是,这不是你的错。我曾尝试使用 ClipboardData.SetData 将数据复制到剪贴板,但这是不可能的。至少不是通过创建“htmlfile”对象。正如我在少数情况下看到的那样,它可能通过创建“InternetExplorer.Application”的实例来工作,但我还没有尝试过。我讨厌为如此简单的任务创建应用程序实例!

阿尔克斯

【讨论】:

【参考方案14】:

如果只是文本,您不能简单地创建一个文本文件并在需要时读取内容吗?

另一种选择,显然是一个杂项,是使用SendKeys() 方法。

【讨论】:

【参考方案15】:

行尾没有安全警告和回车

' 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

【讨论】:

以上是关于从 VBScript 使用剪贴板的主要内容,如果未能解决你的问题,请参考以下文章

使用 GetText 从剪贴板获取文本 - 避免空剪贴板出错

如何从剪贴板读取文本?

使用 python/win32 从/到剪贴板复制和粘贴

ruby 使用AnyStyle解析器从剪贴板解析引用,并将相应的bibtex记录返回到剪贴板

使用javascript将文本从div复制到剪贴板

从剪贴板获取数据并重新设置 - WINAPI,C [重复]