Портабельность ActiveX-компонентов на примере TCScript Helper
© Copyright |
Эта статья защищена авторским правом, и на её правку наложены ограничения. |
Содержание
Предисловие
Не секрет, что многие пользователи ТС в повседневной жизни используют для своих нужд его переносную копию, где по логике должны быть предусмотрены все нюансы, не нарушающие полноценную работу заложенных в сборку функций. И естественно то, что касаться это должно в том числе и прилагаемых средств автоматизации.
Одним таким средством, довольно известным в кругу местных скриптописцев, является замечательный ActiveX-компонент Script Helper for TC, который помогает расширить функционал WSH-сценариев при работе в окне Total Commander.
Так как системный набор библиотек часто ограничивает потребности разработчиков скриптов, им приходится прибегать к внедрению подобного рода дополнительных ActiveX-компонентов, несомненно требующих регистрации в системе.
Одним из способов обойти такую необходимость является авто-регистрация библиотеки на этапе выполнения скрипта и последующее её отключение (дерегистрация) после отработки. На самом деле при таком подходе возникает несколько потенциальных проблем:
- Во-первых, регистрация библиотек предусмотрена только в режиме работы под учётной записью администратора.
- Во-вторых, садясь за чужую машину нельзя быть уверенным наперёд, что подобные игры с реестром позволительны или вообще могут понравиться владельцу испытуемой системы.
- В-третьих, в ряде компаний любые системные записи могут строго караться администрирующей группой вплоть до жалобы руководству и, как бы странным это не казалось, увольнения нарушителя.
- Ну, и в-четвёртых, это некоторое ограничение скорости работы скрипта, без которого тоже в ряде случаев неплохо было бы обойтись.
Для того, чтобы всего этого избегать, существует способ выполнять скрипты, работающие на COM-технологии, без ущерба системе, рабочим условиям, ну и, наконец, собственной психике.
Называется это технология - Side-by-Side, подразумевающая псевдорегистрацию, которая позволяет COM-серверу предоставлять доступ к своим объектам без занесения соответствующей информации в реестр. Исходная цель данной технологии заключалась в устранении конфликтов оси с dll-сорками, а именно проблемы с кричащим названием DLL hell.
Нужно иметь в виду, что данная технология поддерживается в Windоws не ниже XP-версии. Полагаю, на сегодняшний день это обстоятельство очень мало кого может огорчить.
Техническая часть
Итак, распишу попунктно комплекс мер по подлючению ActiveX-компонентов в формате DLL:
1) Для начала следует скопировать (для компонентов с 32-битной разрядностью, как в нашем случае, при работе в Windows x86 из папки из %Windir%\SYSTEM32 или при работе в Windows x64 из папки %Windir%\SysWOW64) интерпретатор WScript.exe в подходящую директорию на переносном или системном устройстве.
2) После этого скопируйте подключаемую dll-библиотеку в тот же каталог.
3) Рядом создайте файл с базовым именем библиотеки и окончанием ".sxs.manifest". К, примеру, на базе обсуждаемого TCScript.dll манифестом станет TCScript.sxs.manifest.
4) Откройте созданный manifest-файл в текстовом редакторе.
5) Теперь перейдём к самой сложной процедуре, а именно к составлению манифестов.
Здесь, конечно, можно углубиться в теорию с подетальным разжёвыванием терминов и XML-синтаксиса данного документа, но дабы не усложнять путь читателю, ограничимся указанием только необходимых для работы скриптов строк и деталей манифеста. Желающие углубиться в подробности могут ознакомиться со статьями на MSDN.
Итак. Первые две стартовые строки неизменны, и принимают такой вид:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0">
Далее следует элемент
<assemblyIdentity type="win32" name="TCScript.sxs" version="1.0.0.14" />
, где в атрибуте name после знака = (как и в отношении других атрибутов) прописывается базовое имя библиотеки с расширением sxs и его версия в атрибуте version, соответсвенно. Версию той или иной билиотеки можно посмотреть с помощью Листер-плагинов PEViewer или FileInfo.
Следом открываем элемент <file name>, где записывается полное имя dll-файла.
Внутри него должны присутвовать два элемента <typelib> и <comClass>.
Записи version="1.0" и helpdir="" внутри <typelib> будут достаточными.
Что же касается tlbid в <typelib>, а также clsid, progid в <comClass>, то эти вещи придётся смотреть в выше оговоренных плагинах либо других прикладных ПО. В плагине FileInfo это будет вкладка ActiveX/OCX. Как правило, сверху рабочей области страницы, где есть uuid(...), вместо троеточия в фигурных скобках записан tlbid, а снизу - clsid.
Стоит отметить, что значения этих данных меняются от версии к версии, поэтому при обновлении компонента их придётся переписывать.
Для некоторых компонентов в элементе <typelib> также может быть востребован атрибут threadingModel (его значение можно найти на той же странице). В случае TCHelper он не потребуется.
Иногда автор шифрует эту информацию, и тогда узнать о данных атрибутах можно из примеров в сети либо путём временной регистрации с созданием манифестов из спецсредств (см. ниже) или сравнением снимков реестра "до/после" с помощью утилит типа RegShot и System Explorer. В лучшем случае автор предоставляет регистрационные данные, которые можно обозревать плагином PEViewer в разделе REGISTRY на вкладке Ресурсы.
Итоговый вид TCScript.sxs.manifest для версии 1.0.0.14 (см. ссылку ниже) представляется следующим образом:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0">
<assemblyIdentity type="win32" name="TCScript.sxs" version="1.0.0.14"/>
<file name="TCScript.dll">
<typelib
tlbid="{99BD528D-BC20-47E4-A2CC-7D8DEE830EB4}"
version="1.0"
helpdir="" />
<comClass
clsid="{F66C60F1-EB21-4DE6-8472-F725FE7EDC19}"
progid="TCScript.Helper" />
</file>
</assembly>
Примечание: в некоторые библиотеки внедрено сразу несколько классов (каждый со своим ProgID), также требуемых описания в манифесте.
Иногда в определённых библиотеках после закрывающего элемента </file> требуется прописывать строки для элемента <comInterfaceExternalProxyStub>.
Углубляться в эти тонкости здесь не буду, лишь покажу пример для nonnoi_APPEncrypt.dll:
<comInterfaceExternalProxyStub
name="IControlEvents"
iid="{EE85ACDD-7499-4719-A173-FCC56CE6FA1D}"
proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}"
tlbid="{40CC9252-A25A-4D28-A906-9BD3F752934A}" />
6) Далее следует создание манифеста непосредственно для самого интерпретатора WScript.exe с содержанием регистрации всех требуемых библиотек.
В отличии от предшественника исходное расширение интерпретатора на sxs не заменяется, т.е. полное имя будет таким: WScript.exe.manifest.
Составление данного манифеста куда проще, ибо не требует никаких копаний в идентификаторах. Неизменными строками в нём будут:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0">
<assemblyIdentity type="win32" name="wscript.exe" version="1.0.0.0" />
и самый нижний закрывающий элемент </assembly>.
Далее для каждого компонента создаётся запись вида:
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="TCScript.sxs" version="1.0.0.14" />
</dependentAssembly>
</dependency>
, где как и в случае выше для name и version подставляются соответствующие значения.
На примере TCHelper и dsofile итоговый файл с двумя вариантами записи будет выглядеть так:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0">
<assemblyIdentity type="win32" name="wscript.exe" version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="TCScript.sxs" version="1.0.0.14" />
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="dsofile.sxs"
version="2.1.0.0" />
</dependentAssembly>
</dependency>
</assembly>
В помощь по составлению манифестов прилагаю ссылки на вспомогательные средства:
- Side-by-Side Manifest Maker
- Side-by-side Assembly Development Tools
- Microsoft OLE/COM Object Viewer
- MiTeC OLE/COM Object Explorer
- TypeLib Browser
- EXE Explorer
- ActiveXHelper
- TLViewer
Важно! После запуска скрипта информация из задействованных манифестов кэшируется в памяти, в результате после их обновления сервер сценариев вернёт ошибку. Чтобы это быстро исправить, нужно намеренно допустить любую ошибку в WScript.exe.manifest, например, временно дописав лишний символ, и единожды запустить скрипт, после вернуться к правильной редакции.
7) Ну, и последнее приготовление - это непосредственный запуск скриптов.
Там, где востребован сторонний компонент, скрипт необходимо запускать с указанием пути к скопированному ранее интерпретатору.
Расположение самих скриптов значения не имеет. На примере результирующей кнопки для однострочного VBS-скрипта
MsgBox CreateObject("TCScript.Helper").GetInfo("SC")
выглядит это следующим образом:
Код кнопки |
---|
TOTALCMD#BAR#DATA: %COMMANDER_PATH%\Scripts\Components\wscript.exe "%COMMANDER_PATH%\Scripts\ShowCountOfDisplayedItems.vbs" wciconex.dll,84 -1 |
Скачать готовую сборку для TCHelper
Ссылка на обновлённую версию со встроенным интерпретатором
Заключение
Разумеется, на вспомогательном объекте ТС для местной публики свет клином не сошёлся. Полезных компонентов, скомпиллированных в dll, в сети можно найти достаточное количество. Из наиболее востребованных помимо двух указанных могу отметить JSSys3.dll, jsShell.dll, WshExtra.dll, MediaInfoActiveX.dll, WSO.dll, dynwrapx.dll, Chameleon.FileTimesEditor.dll, HTMLParser.dll, newobjectspack1.dll, библиотеки Chilkat, XStandard и других марок, без проблем находящихся Web-поиском.
P.S.: Если возникли вопросы или проблемы при составлении манифестов, прошу обращаться на форум wincmd.ru. Спасибо за внимание!
Flasher
24.11.2015
Ключевые слова: ActiveX, Helper, TCHelper, Хелпер, Portable, Script, VBS, VBScript, JSCript, WSH, WSF, COM, OLE, компонент, портабельность, флешка, съёмный диск, съёмный носитель |