1

Тема: WSH: непонятки с записью в буфер обмена в CreateObject("htmlfile")

Объясните непонятки. Одним из виденных мной в Интернете способов работы с Буфером Обмена в WSH (Windows Script Host) является способ с использованием объекта "htmlfile" -- примерно так (код на VBS):

Option Explicit ' обязательное объявление переменных

Dim bSuccess ' рез-тат записи в Буфер (успех/провал -- True/False)
Dim oHTML    ' объект MSHTML.HTMLDocument
Dim someText ' наш текст для записи в Буфер
Dim ClipContent ' сюда запишем содержимое из Буфера

Set oHTML = WScript.CreateObject("htmlfile") ' создали объект

someText = "Text for ClipBoard"
oHTML.ParentWindow.ClipboardData.ClearData("Text") ' очистили Буфер
' записали в Буфер
bSuccess = oHTML.ParentWindow.ClipboardData.SetData("Text", someText)
' взяли из Буфера
ClipContent = oHTML.ParentWindow.ClipboardData.GetData("Text")

If bSuccess = True Then
   MsgBox "Запись в Буфер успешна"
Else
   MsgBox "Запись в Буфер НЕ успешна"
End If

MsgBox "Взяли из Буфера:" & Chr(13) & ClipContent, vbOKOnly

Set oHTML = Nothing ' уничтожили объект

Но в WSH эта шняга реально работает только на чтение, т.е. текст из Буфера берется (GetData), но не записывается (SetData).

При этом в VBA MS-OFFICE этот способ нормально работает и на чтение и на запись. Примерно так (тоже из Интернета с кое-где моими комментариями):

Function Clipboard(Optional s As String) As String

    ' fx Clipboard записывает в Буфер Обмена значение к-л переменной
    ' (строковое или числовое) или считывает из Буфера находящееся
    ' там значение в переменную.
    '
    ' Запись в Буфер  : Clipboard SomeVar
    ' Чтение из Буфера: SomeVar = Clipboard
    '
    ' NOTE: если fx Clipboard вызыв-ся без арг-та s, то его значение
    ' Len(s) будет = 0

    Dim v As Variant
    Dim obHTML As Object ' MSHTML.HTMLDocument

    v = s ' Cast to variant for 64-bit VBA support

    Set obHTML = CreateObject("htmlfile") ' New MSHTML.HTMLDocument

    With obHTML.parentWindow.clipboardData

        If Len(s) > 0 Then
            .setData "text", v ' запись в Буфер
        ElseIf Len(s) = 0 Then
            Clipboard = .getData("text") ' чтение из Буфера
        Else
            MsgBox "fx Clipboard: такого не должно быть"
        End If

    End With ' obHTML

    Set obHTML = Nothing

End Function

ВОПРОС: почему в WSH запись в буфер не работает, а в VBA OFFICE работает?

2 (изменено: 3wedsmncjklvjvd73734, 2025-11-27 08:16:26)

Re: WSH: непонятки с записью в буфер обмена в CreateObject("htmlfile")

EgorS
Потому что в браузере Микрософта этот скрипт встроен. И что бы обезопасить юзера было сделано ограничение на запись в клип непосредственно из vbs.
Но т.к. сам объект "браузер" (или другой СОМ объект) имеет доступ к клипу, то в vbs если его объявить то можно писать в клип. Почему так сделано "коряво"?
Думаю, микрософт предоставил самому юзеру определиться с возможностью, определить ограничения vbs в браузере. Мол пусть vbs выполняется в браузере , как работа с html данными, но из браузера на волю (на внешнюю среду ОС) ни нагой.
Т.е. Микрософт в браузере ввёл ограничение. И предоставил возможность самому юзеру определиться.
1-Выполнять/Запрешать vbs коды,
2-Выполнять/Запрешать ActiveX
А в самой ОС, он (Микрософт) сразу запретил. При этом тоже самое сделал и через WMI (Windows Management Instrumentation).
Пример использования записи в клип на vbs через "браузер" HTA


Dim clipboardText,html
Set html = CreateObject("htmlfile")
dim a 
a=CreateObject( "WScript.Shell" ).Run("mshta.exe javascript:eval(""document.parentWindow.clipboardData.setData('text','Эта запись сделана в клипбоард для EgorS ');close()"")", 0, True ) 
clipboardText =html.ParentWindow.ClipboardData.GetData("text")
WScript.Echo clipboardText 

Кстати , тут есть эта тема про клип.
--> VBS: Работа с буфером обмена (clipboard) https://forum.script-coding.com/viewtop … mp;login=1
И где-то тут на форуме тоже я читал что , в режиме текста можно через клип перебрасывать что угодно, через преобразование данных в текст через в коде64.
Имея в ОС HTA (браузер) можно работать с клип не устанавливая МСоффис.
Но можно работать с клипом в vbs непосредственно с клипом/,

Кстати.
Можно записать в клип непосредственно через стандартную процедуру ДОСа
ввода-вывода

text = 22
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("clip")
Set oIn = oExec.stdIn
oIn.WriteLine text
oIn.Close

Проверьте.
Теперь там будет записано "22"

Clip
Перенаправляет выходные данные команды из командной строки в буфер обмена Windows. Эту команду можно использовать для копирования данных непосредственно в любое приложение, которое может получать текст из буфера обмена. Вы также можете вставить эти текстовые выходные данные в другие программы.
https://learn.microsoft.com/ru-ru/windo … ands/clip

ремарка.
ПЕРЕВОД.


  • VBScript не поддерживает буфер обмена. Большинство хостов, на которых работает VBScript, например Internet Explorer, предоставляют доступ через хост. Таким образом, VBScript, работающий в IE или HTA, может использовать поддержку буфера обмена в IE. Хосты для сценариев не поддерживают буфер обмена. Вы можете использовать файл vbs для запуска IE через COM-автоматизацию, перехода на локальную страницу (чтобы обойти предупреждения системы безопасности), а затем использовать буфер обмена в IE.

Так же вы можете передовать данные не только через буфер обмена но и через другие объекты. Например через Рабочий стол или через проводник.
Причём в VBS через них передаётся всё, а не только текст как в буфере обмена.-->
WSH: обмен данными и объектами между скриптами — 2
https://forum.script-coding.com/viewtop … 34#p162734

3

Re: WSH: непонятки с записью в буфер обмена в CreateObject("htmlfile")

Благодарю, что откликнулись. Написано много — прочитал, но ничего не понял :). Единственное, что понял: «Хосты для сценариев не поддерживают буфер обмена.» — то есть среда, где исполняются .JS/.VBS-файлы (aka "сценарии") не даёт доступ к буферу, а среда VBA — даёт? Но тогда почему в .JS/.VBS-сценариях всё-таки можно _брать_ из буфера… В общем непонятки так и остались.

Насчёт предложенного вами способа писать в буфер через CLIP.EXE. Мне этот способ известен, но он мне не нравится, так как там на мгновение мелькает окно консоли (CMD в Win2000/XP или DOS в Win9x). Кроме того (вот тут я точно не помню, поэтому могу ошибаться, но искать уточнять инфу щас лень), CLIP.EXE — это же вроде отдельная утилита, которая штатно есть только начиная кажется с Vista, а в Win2000/XP и Win98/Me её надо ещё добавить, взяв из Resource Kit'ов для соответственно Win2000 и Win98 (для Win2000 и Win98 нужны свои CLIP.EXE). Это, конечно, мелочь, но лишний гемор на чистой системе помнить еще об этих "добавках"…

P.S. А сам для себя наиболее удобным способом записи в буфер в сценариях JS/VBS я счёл способ с MSHTA (тот, что у вас обозначен как «Пример использования записи в клип на vbs через "браузер" HTA») — только он у вас там какой-то громоздкий, у меня проще:

Option Explicit ' обязательное объявление переменных

' --- описываем переменные --->

Dim strText     ' as String -- текст, который запишем в буфер
Dim WshShell    ' as "WScript.Shell"

Dim Command     ' as String  -- команда для WshShell.Run
Dim WindowStyle ' as Integer -- стиль окна для WshShell.Run
Dim Wait        ' as Boolean -- ждать ли завершения WshShell.Run

' <-- конец описания перем. ---

strText = "Text for ClipBoard"

Set WshShell = WScript.CreateObject("WScript.Shell") 'созд. объект

  Command = "mshta.exe ""javascript:clipboardData.setData('Text','" & strText & "');close();"""
  WindowStyle = 2 ' -- [1]
  Wait = True     ' -- [2]
  WshShell.Run Command, WindowStyle, Wait

Set WshShell = Nothing ' уничтожили объект

WScript.Echo "Теперь в Буфере должно быть:", vbCr, vbCr, strText

WScript.Quit ' выход

' ------
' NOTES
' ------
'
' [1] х/з, что означают разные виды WindowsStyle, я оставил 2 т.к.
'     оно было в примере, на основе которого я сделал этот скрипт:
'     - http://forum.oszone.net/thread-215086.html
'     на MDSN WindowStyle = 2 описан так: Activates the window and
'     displays it as a minimized window.
'     - http://msdn.microsoft.com/en-us/library/d5fk67ky%28v=vs.84%29.aspx
'
' [2] третий парам. метода Run задаёт, будет ли скрипт ждать, пока
'     запущенный им процесс (в данном случае mshta.exe) не закончит
'     работу: True -- скрипт ждёт завершения процесса.

4 (изменено: 3wedsmncjklvjvd73734, 2025-11-27 23:37:09)

Re: WSH: непонятки с записью в буфер обмена в CreateObject("htmlfile")

EgorS
1- Clip уже встроен во все версии win10 , не проверял как там у  w11. Сам clip предназначен для командной строки ДОС-а. О чём и поведала ссылка на Микрософт (см выше пост).
2- HTA это тоже встроенная такая же внешняя прога, как и clip. Отличие только одно. Она объектно ориентированная и так же как и Clip встроена во все версии w10 и w11.
...
3- Все ЭТИ внешние проги, это отдельный запуск их в среде VBS. Это так же как запуск паинбруша в VBS и "проигрывание" в ней командами по нажатию клавиш. Но конечно HTA более удобней чем DDL интерфейс. А с вызовом например MSWord-а конечно проще. Кстати в винах тоже встроен WordPad, в котором тоже есть работа как и в MSWord-е работа с буфером обмена.
4- Вы так и не среагировали на моё предложение рассмотреть работу вместо буфера обмена по передачи данных в VBS через встроенные "проводник" и рабочий стол".
.. Возможно вы так и не поняли задумку ТОЙ темы.
Короче.
Все известные способы по передачи данных ориентированы на использование буфера обмена.
Если вы писали проги на VB5 VB6, то должны были заметить один нюанс, в свойствах объектах как форма или кнопка, есть такие параметры которые можно задать и програмно менять как титлы, каптион или другие установки. Которые имеют тип строковых данных. Я например через них передавал данные переменных ,  между другими формами или прогами.
Так вот. У микрософта т.к. все объекты так же имеют объектно ориентированный интерфейс тоже имеют такие свойства. Поэтому если если посмотрите в реестре по ссылке

\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\

то обнаружите множество таких объектов.
+ в VBS встроена функция объявления объектов не только через "класс.имякласса", но и через CLSID.
  Например WinWord.
В VBS это будет выглядеть так.

Set wordApp = CreateObject("Word.Application")

.
Но можно и так
По ссылке

Компьютер\HKEY_CLASSES_ROOT\Word.Application\CLSID

можно увидеть этот CLSID.

{000209FF-0000-0000-C000-000000000046}

И если вы в свой код вставите этот CLSID то это будет тоже самое что и

 "Word.Application"
Set wordApp = CreateObject("New:{000209FF-0000-0000-C000-000000000046}")

.
И можете после этого так же управлять этим Вордом как и в стандартном объявлении по имени класса. Ремарка. Проверил этот пример- он не пашет вот так с наскока...
Поэтому исходя из этого были найдены некоторые объекты вина с их CLSID, такие как например
"Проводник" и "Рабочий стол", которые можно также как и винворд объявлять в VBS через CLSID. И у которых так же как и в VB6 есть некоторые методы и свойства внутри этих объектов, через которые можно так же передавать как и через буфер обмена данные.
При этом Через эти свойства передаются не только стандартные типы данных, но такие как ОБЪЕКТЫ целиком.
Вот например я в том примере -->
https://forum.script-coding.com/viewtop … 34#p162734
Применял для передачи через "рабочий стол" объект FSO, у которого есть функция "показ пути". Эта функция показывает путь из которого была запущен VBS с вызовом этого объекта.
Если например в коде запустите

Set FSO = CreateObject("Scripting.FileSystemObject")

То функция показа пути вам выдаст путь откуда был запущен этот VBS код.

GetAbsolutePathName(".")


А т.к. через такие объекты как "проводник, рабочий стол"
передаётся ПОЛНОСТЬЮ объект, а не данные, то другой скрип VBS получает его как объект, запущенный в другом скрипте..
Короче.
Я запустил вызов fso в одном скрипте. потом не закрывая этот скрит, запустил другой скрипт который был расположен совершенно на другом физ. диске и в другой папке.
И которые получил через проводник полностью путь того первого запущенного VBS скрипта который первый объявил этот FSO.
Первый скрипт был запущен с диска "D:\temp1". Второй скрипт был запущен с диска "Е:\temp3"
Второй скрипт получил объект FSO от первого скрипта и он показал путь "D:\temp1", хотя сам этот fso во втором скрипте находился на пути  "Е:\temp3".
  Понятно объяснил?
Ещё пример.
Объявляете в первой скрипте массив данных. заполняете его там в скрипте. и передаёте через "проводник или рабочий стол" его целиком (переменную этого массива).
Тут слово "передаёте" надо трактовать как посылаете в свойства "проводник, рабочий стол" SetProperty эту всю переменную массива (имя её). 
А другой скрип VBS через  "проводник или рабочий стол" получает этот массив полностью со всеми данными и работает с ними через функцию GetProperty имя переменной массива .
И так можно передавать целые объекты между любыми прогами в которых есть встроенный VBS.
...
Это удобнее чем использовать буфер обмена.
Чем ещё полезна эта фича? А тем что второй скрипт будет выполняться и "переговариваться" между первым скриптом не зависимо , выполнена ли следующая функция в скрипте или нет...
Т.е. это своеобразная многопоточность.
Лучше конечно передавать через "рабочий стол". Он будет хранить объекты (данные), даже если VBS скрипт будет закрыт. И потеряет эти данные только после закрытия вина целиком.
Хотя я может и не прав. потому что скорее всего рабоч стол хранит в себе адрес памяти переменной. И после закрытия кода, этот адрес освобождается.

5

Re: WSH: непонятки с записью в буфер обмена в CreateObject("htmlfile")

3wedsmncjklvjvd73734 пишет:

Вы так и не среагировали на моё предложение рассмотреть работу вместо буфера обмена по передаче данных в VBS через встроенные "проводник" и рабочий стол".
.. Возможно вы так и не поняли задумку ТОЙ темы.
Это удобнее чем использовать буфер обмена.
Чем ещё полезна эта фича? А тем что второй скрипт будет выполняться и "переговариваться" между первым скриптом не зависимо, выполнена ли следующая функция в скрипте или нет...

Я, честно говоря, и не думал там что-то понимать, потому что мне никогда не нужно было обмениваться данными между несколькими одновременно работающими скриптами и уж тем более перекидывать между ними какие-то объекты. Просто иногда бывает надо из скрипта скопировать некие строковые данные в Буфер Обмена. Эту задачу я для себя давно решил — я перепробовал несколько способов: и с CLIP.EXE и с созданием скрытого окна Internet Explorer и еще там с чем-то и остановился на способе с mshta.exe (почему именно на нём — не помню, но остальные показались мне чем-то неудобными). Так что теоретически этот вопрос для меня был давно закрыт...

Но! Недавно, ползая по Интернету, я случайно наткнулся на способ записи в Буфер в VBA MS-Office через CreateObject("htmlfile"). Я в VBA его никогда не использовал, потому что там это особо не надо, а если надо, то привычнее юзать библиотеку "MS-Forms 2.0". Но там что-то писали, что то ли в новых Office эту библиотеку похерили, то ли она криво работает в 64-битных Office, то ли что-то ещё, но что вот сейчас лучше использовать этот способ (с "htmlfile"). Для меня это тоже неактуально, потому что я юзаю Office 2000/2003 ("риббон"-интерфейс из Office 2007+ ненавижу, это мог придумать только выдающийся дегенерат), но я смутно припомнил, что я когда-то пытался писать в Буфер через "htmlfile" в VBS/JS-скриптах и там это не работало. Раскопал старые записи -- да, всё верно, способ тот же самый. И мне просто стало интересно, почему в VBA он работает, а в скриптах — нет. Но ясности по-прежнему нет :)

6 (изменено: 3wedsmncjklvjvd73734, 2025-11-28 02:04:13)

Re: WSH: непонятки с записью в буфер обмена в CreateObject("htmlfile")

EgorS
VBA не встроен в систему. VBS может непосредственно работать с WMI -->https://wutils.com/wmi/, который может при помощи объектного ориентирования лезть в кишки всего компа и не только.
Поэтому весь этот WMI заточен "только чтение". Возможно что первоначально и в VBS была возможность писать в буфер обмена, но вот хакеры паршивые постоянно искали дыры. И Микрософту из-за этого постоянно приходиться постоянно всё ЭТО урезать выпуская очередные сервис паки с закрытием этих дыр.
Например, до какой то версии вин10 в VBS была функция изготовления VHD,VHDX виртуальных дисков. А теперь после выхода Hyper-V ver2.0 Эта функция исчезла. Теперь в VBS , эти вирт диски только, чтение об их инфы и всё. Приходиться для работы с ними запускать внутри VBS "diskpart" , или переходи на PowerShell.
ремарка.
VBS так встроен в ОС что при установки ОС , выполняются уже  встроенные vbs  установочные файлы. А вот при установки ОС никакого PowerShell или VBA с VB.NET кодов нет. Т.е. этот VBS очень глубоко в ОС вшит, по сравнению с PowerShell или с VB.NET. И эти  PowerShell или  VB.NET, только тогда в ОС начинают глубоко копать , когда сам юзер лично их не включит в ОС. И скорее всего это из-за браузера, который поддерживает VBS и который выполняет главным обозревателем в ОС вина. Микрософт так и заявлял в начале про вин10, что мол ОС эта теперь будет полностью интегрирована с гиперссылками в браузере и все теперь будет работать через них.