1 (изменено: Xameleon, 2009-10-03 13:04:50)

Тема: HTA: Мультисокетный WEB сервер в HTA

Доброго времени суток товарищи.

Вступление
Всем кому влом читать всю дальнейшую ахинею - ниже ссылка на архив того, что получилось - Мультисокетный WEB сервак.

скачать

Простенький пока что. Грузит HTML-ки, картинки и просто файлы. В дальнейшем хочу добавить обработку запроса 206 для докачки файла, обработку ASP (Предполагаю, что ScriptControl вполне подойдёт) ну и остальные функции.

Админам и модераторам: Заранее прошу прощения, что не кинул сразу в коллекцию, т.к надеюсь на активное участие разработчиков и помощь в доделке, а в коллекции дискуссии запрещены.

В архиве:
Server.hta - сам сервак.
Stop server.vbs - скрипт остановки сервера (в принципе скрипт получает полный доступ к объектам в Server.hta, так что потом можно сделать полноценное управление сервером, а так же наблюдать за состоянием всех сокетов)
Socket.wsc - "волшебный" контейнер сокета
каталог wwwroot - в нём странички и картинки

Что запускать ?
1) Запускать - Server.hta
2) Если никаких ошибок не вылезло (компонетов нужных нет или ещё что то), то зайти в браузер и набрать http://localhost
3) В идеальном случае должна появиться главная страница сайта

* Если ошибок не произошло, но и страница не грузится - возможно у вас в брандмауэре не разрещён 80 порт. Его нужно добавить в исключения

Как всё делалось иля левой ногой за правым ухом. Уж очень захотелось поделиться переживаниями ))
Тут в голову стукнула идея попробывать создать скриптовый WEB сервер. Думаю такая идея посещала не только меня и наверняка уже были такие реализации. Ведь в принципе всё для этого есть. Winsock отлично с этим справляется. Но всё же решил и сам попробывать. Упёрся в то, что винсок один и если на него "толпой" запросы накидать, то он не справится конечно, а "настоящий" веб сервер конечно делает множество сокетов для обработки запросов. Попытался создать массив сокетов и повесить их все на одни и теже события. Вешаться то они вешаются, но только в самом событии узнать какой из объектов его породил - я никак не мог. . Попробывал в каждом событии по циклу прогонять сокеты и смотреть их состояние. Тормоза.... и сбои... Т.к несколько сокетов могут иметь одинаковое состояние в одно и тоже время. Так что не вариант... В идеальном случае хотелось бы, чтобы в каждое событие передавалась ссылка на объект сгенеривший событие (EventObject), но исходные события винсока я поправить не могу. Стал думать. Вспомнил про всемогущий WSC. Ведь в нём можно так же ловить события от объектов:

<object id="Winsock" progid="MSWinsock.Winsock" events="True" />

Создал Socket.WSC. Стал думать как высунуть его события обратно в скрипт. И тут новая проблема: События у WSC не имеют параметров. Т.е нельзя сделать FireEvent(EventName,param1,param2), а можно только FireEvent("EventName"). Стал думать - как бы зацепиться за процедуры в скрипте. Почитал ещё структуру WSC и наткнулся на статью где в WSC передают объект WScript. Отлично ! Передал... Но у WScript нет связки с процедурами в скрипте. Т.е нельзя сделать WScript.MyProc Мда... Но ведь процедуры принадлежат к кому то. Конечно принадлежат. Они связаны с объектом Me ! Попробывал в скрипте вызвать Me.MyProc. Однако ж работает !. Передал объект Me в WSC. Завязал события:

Private Sub Winsock_ConnectionRequest(ByVal requestID)
    Script.Socket_ConnectionRequest Self, requestID
End Sub

Сразу возникает вопрос (наверное ), что за объекты Script и Self в коде. Script - это Me из родительского скрипта, а Self - это ссылка на Me от cамого WSC. Решил передавать её как ссылку на сокет. Мда... не совсем понятно наверное. В общих чертах - Socket.WSC ловит стандартные события винсока внутри себя и через связку со скриптом транслирует их в процедуры в server.hta.
Не захотелось мне все свойства винсока описывать в WSC, поэтому просто высунул его как property

<property name="Winsock" />

В итоге в самом скрипте я получил

Sub Socket_ConnectionRequest(EventObject, requestID)
End Sub

EventObject и есть ссылка на сам сокет, а EventObject.Winsock - ссылка на Винсок внутри сокета.
Ну а дальше обычная обработка каждого сокета.
Первый стоит постоянно на прослушке, а DataArrival раздаёт остальным сокетам коннект.

Под конец добавил стандартную связку HTA и скрипта для остановки сервера через WebBrowser control. Если кто не знает - вот тема где это обсуждалось:просмотреть

Вот вроде и всё.

P.S Очень жду отзывов, предложений по модификации и улучшению. С радостью готов ответить на любые вопросы - если что то непонятно расписал. Потому как расписал не всё. Слишком много получится. ))

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

2

Re: HTA: Мультисокетный WEB сервер в HTA

Правильно ли я понял, что при подключении к слушающему сокету WinSock создаёт отдельный сокет соединения, который вы сохраняете в Dictionary?

3 (изменено: Xameleon, 2009-10-03 18:11:53)

Re: HTA: Мультисокетный WEB сервер в HTA

Почти так , но не совсем. Слушающий WinSock только ловит событие запроса в процедуре ConnectionRequest, но сам ничего не создаёт. Вместо этого в этой же процедуре через GetObject создаётся экземпляр объекта из Socket.WSC - "оболочка" для Винсока. Внутри этого объекта есть свой Winsock. И уже этому винсоку как раз передаётся requestID (ID запроса). В итоге каждый созданый Socket.WSC становится самостоятельным обработчиком событий. И каждый раз когда в нём происходит событие он транслирует его в основной скрипт Server.HTA, при этом передавая ссылку на свой внутренний винсок. Каждая созданная оболочка добавляется в коллекцию Sockets. В основном скрипте есть процедура Socket_Close. И как только сокет "отработал" и закрылся, то он удаляется из коллекции.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

4

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon - ты мегомоск !!!
Щас спать не буду, пока не врублюсь во всё... 
По-мне, дык это просто КРУТБЛ !!!

Времени не хватает... :-(

5 (изменено: Xameleon, 2009-10-03 20:04:07)

Re: HTA: Мультисокетный WEB сервер в HTA

2 Евген:
О боги. Вот уж чего чего - а спать точно надо ). Тем более в выходные.

P.S

Сейчас наткнулся на то, что ADODB.Stream грузит в память файл целиком. Не гуд. Думаю как собрать на скриптах читалку файлов блоками.
Если кто подскажет - буду очень благодарен )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

6 (изменено: kaster, 2009-10-03 20:12:57)

Re: HTA: Мультисокетный WEB сервер в HTA

А у меня при запуске Server.hta выдает ошибку

---------------------------
Windows Script Component - file:///C:/Documents%20and%20Settings/username/Рабочий%20стол/test/foldertree/tmp/Socket.wsc
---------------------------
[13,24] Недопустимое значение атрибута : progid
---------------------------
ОК   
---------------------------
autoit@conference.jabber.ru - Конференция скриптового языка AutoIt на jabber.ru

7 (изменено: Xameleon, 2009-10-03 20:44:02)

Re: HTA: Мультисокетный WEB сервер в HTA

Это значит у вас не зарегистрирован MSWinsock.Winsock.

Вот архив с винсоком. В комплекте батник для регистрации.

Winsock.zip

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

8 (изменено: kaster, 2009-10-03 21:22:48)

Re: HTA: Мультисокетный WEB сервер в HTA

Спасибо, зарегил. Вот следующая ошибка

---------------------------
Windows Script Component - file:///C:/Documents%20and%20Settings/username/Рабочий%20стол/test/foldertree/tmp/Socket.wsc
---------------------------
Не удается создать объект
---------------------------
ОК   
---------------------------
autoit@conference.jabber.ru - Конференция скриптового языка AutoIt на jabber.ru

9 (изменено: Xameleon, 2009-10-03 22:24:29)

Re: HTA: Мультисокетный WEB сервер в HTA

А вот про причину это пока не знаю . Надо подумать.

А такой код срабатывает ?

Set Winsock = CreateObject("MSWinsock.Winsock")
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

10

Re: HTA: Мультисокетный WEB сервер в HTA

Ух, с каждым разом все интереснее

---------------------------
Windows Script Host
---------------------------
Сценарий:    G:\prog\1.vbs
Строка:    1
Символ:    1
Ошибка:    Класс не лицензирован для использования 
Код:    80040112
Источник:     (null)

---------------------------
ОК   
---------------------------
autoit@conference.jabber.ru - Конференция скриптового языка AutoIt на jabber.ru

11

Re: HTA: Мультисокетный WEB сервер в HTA

Мда... Новости пока не утишительные....

Вот ссылка где разбирается такая же проблема, но с MSComDlg.CommonDialog....

В кратце:

Уважаемый rem-andrew!
Ошибка: Класс не лицензирован для использования означает лишь то, что вы не имеете лицензию на использование объекта MSComDlg.CommonDialog.
-----
Вопросы распространения лицензий решает Microsoft, это не в моей юрисдикции. Я не вижу смысла в том, чтобы лишать других людей возможности использовать данный скрипт из-за того, что вы не обладаете лицензией.
--------
Вот англоязычный вариант ответа на вопрос о лицензировании объекта MSComDlg.CommonDialog:
Цитата:
"MSComDlg.CommonDialog is a licensed control and will only work from WSH hosted script
on a box with a development license installed by a MS dev tool like VStudio or VB.
Compiled applications embed a runtime license but WSH isn't a compiled environment."
---------
Поэтому, если у вас имеется лицензия на разработку (установлен VB или MSVS), Вы можете смело использовать данный скрипт. Об этом я говорил в предыдущих постах.
Цитата:
Сообщение:307185 -> 306275, Отправлено: 25/07/2005 13:48
"в разных случаях Ваша проблема решалась переустановкой MSVS (включенная галочка ActiveX), либо установкой MSVS SP5"

Как с этим бороться пока не знаю (

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

12 (изменено: Xameleon, 2009-10-04 00:03:20)

Re: HTA: Мультисокетный WEB сервер в HTA

Решение нашёл. Надо в реестр импортировать лицензию по пути

HKEY_CLASSES_ROOT\Licenses\стёрто злобным модератором

Перезалил архив. Теперь в нём всё есть )
скачать
Надо лишь заного запустить register.bat

Нет-нет, напрямую, пожалуйста, не надо: всё ж таки Правила форума, п.2.9..

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

13

Re: HTA: Мультисокетный WEB сервер в HTA

Ну, можно далеко не ходить ; тот же Google, думаю, поможет и в этом случае.

14 (изменено: Xameleon, 2009-10-04 00:14:55)

Re: HTA: Мультисокетный WEB сервер в HTA

Как раз там и нашёл. Просто не сразу

P.S Кстати хотел спросить - а есть ли manifest на винсок, чтобы его не регить ?
P.P.S К сожалению про манифесты мало, что знаю, поэтому возможно вопрос не имеет смысла.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

15

Re: HTA: Мультисокетный WEB сервер в HTA

Общий путь таков: RegMon или ProcMon от бывшего Sysinternals, слежение за реестром, фильтр на «Path»+«contains»+«\SOFTWARE\Classes\Licenses», запуск кода из поста #9 приводит к нужному имени.

P.S. Порадовало, что на конференциях самой MS сие лежит практически в открытом виде . Но мы так не будем делать .

16

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon пишет:

P.S Кстати хотел спросить - а есть ли manifest на винсок, чтобы его не регить ?

Я совсем в этом деле не специалист. Тут: WSH: Использование COM-сервера без его регистрации в системе вроде бы начали, и пока остановились; посмотрите, может быть этого материала уже достаточно для решения вопроса?!

Я попозже обязательно посмотрю и постараюсь понять, как сие работает; мне в первую очередь интересно вот это:

Упёрся в то, что винсок один и если на него "толпой" запросы накидать, то он не справится конечно, а "настоящий" веб сервер конечно делает множество сокетов для обработки запросов. Попытался создать массив сокетов и повесить их все на одни и теже события. Вешаться то они вешаются, но только в самом событии узнать какой из объектов его породил - я никак не мог. hmm. Попробывал в каждом событии по циклу прогонять сокеты и смотреть их состояние. Тормоза.... и сбои... Т.к несколько сокетов могут иметь одинаковое состояние в одно и тоже время. Так что не вариант... В идеальном случае хотелось бы, чтобы в каждое событие передавалась ссылка на объект сгенеривший событие (EventObject), но исходные события винсока я поправить не могу. Стал думать. Вспомнил про всемогущий WSC. Ведь в нём можно так же ловить события от объектов:

и т.д. Дело в том, что шёл практически один-в-один по тому же пути с объектом «WshRemote», но так и не смог довести дело до конца (я делал класс, который при создании экземпляра объекта создаёт объект «WshRemote», привязывается к его событиям и… тут выяснилось, что процедуры обработчики должны быть уровня глобального модуля, а созданные мною процедуры-обработчики внутри самого класса для VBScript не годятся, он к ним не привязывается). Так что, буду глядеть-учиться.

17

Re: HTA: Мультисокетный WEB сервер в HTA

Ура... Все заработало! Спасибо

autoit@conference.jabber.ru - Конференция скриптового языка AutoIt на jabber.ru

18 (изменено: Xameleon, 2009-10-04 01:48:34)

Re: HTA: Мультисокетный WEB сервер в HTA

to kaster:
Мда... видать придётся ещё покорпеть с винсоком. Косяк однако.

to alexii:

alexii пишет:

я делал класс, который при создании экземпляра объекта создаёт объект «WshRemote», привязывается к его событиям

Готов помочь и поучаствовать Заинтересовался.

alexii пишет:

Так что, буду глядеть-учиться.

alexii пишет:

и… тут выяснилось, что процедуры обработчики должны быть уровня глобального модуля, а созданные мною процедуры-обработчики внутри самого класса для VBScript не годятся, он к ним не привязывается). Так что, буду глядеть-учиться.

Ммм.. Ну а если "принудительно привязать" ?

Script.vbs

'Получаем путь до родительского каталога
Dim ParentFolderName
ParentFolderName = GetParentFolderName(WScript.ScriptFullName)
'Создаём наш WSC компонент
Set TestWsc = GetObject("script:" & ParentFolderName & "Test.wsc")

'Создаём класс модуль
Dim TestClass
Set TestClass = New clsTestClass

'Передаём ссылку на наш класс в WSC компонент
Set TestWsc.CallBackClass = TestClass

'Вызываем метод WSC компонента
TestWsc.TestProc "пример"

'Описание класс модуля
Class clsTestClass
    Function TestProc(param)
        MsgBox param
    End Function
End Class

'Функция получения родительского пути
Private Function GetParentFolderName(ByVal Path)
    Dim LastSlash1Pos,LastSlash2Pos
    LastSlash1Pos = InstrRev(Path,"\")
    LastSlash2Pos = InstrRev(Path,"/")
    if LastSlash1Pos < LastSlash2Pos Then LastSlash1Pos = LastSlash2Pos
    if LastSlash1Pos = 0 Then LastSlash1Pos = Len(Path)
    GetParentFolderName = Left(Path,LastSlash1Pos-1) & "\"
End Function

Test.wsc

&#65279;<?xml version="1.0"?>
<component>

  <?component error="true" debug="true"?>

  <registration
    description="Test"
    progid="Test.WSC"
    version="1.00"
    >
  </registration>
  <public>
    <property name="CallBackClass" />
    <method name="TestProc" />
  </public>

  <script language="VBScript">
    <![CDATA[
    'Процедура которая транслирует ответ обратно.

    Sub TestProc(Param)
      CallBackClass.TestProc("Возвращено из Test.wsc: " & Param)
    End Sub
    ]]>
  </script>

</component>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

19 (изменено: NikR, 2009-10-04 02:22:39)

Re: HTA: Мультисокетный WEB сервер в HTA

Сейчас наткнулся на то, что ADODB.Stream грузит в память файл целиком. Не гуд. Думаю как собрать на скриптах читалку файлов блоками.
Если кто подскажет - буду очень благодарен )

http://www.script-coding.com/WSH/FileSy … tml#7.3.2.
Read нормально работает с нетекстовыми символами, а вот ReadAll, бывает, глючит.

P.S Кстати хотел спросить - а есть ли manifest на винсок, чтобы его не регить ?

Нет смысла в манифесте, если в нём нельзя указать лицензию. А можно ли - вопрос.

20

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon, мега огромное спасибо за столь ценный скрипт. Нашел то, что давным давно искал. Способ создания дополнительного потока, и передача ссылки на основной. Обязательно буду использовать этот подход.

Еще раз огромное спасибо за этот пример.

XC Engine
Web automation via Internet Explorer

21 (изменено: Xameleon, 2009-10-04 12:54:13)

Re: HTA: Мультисокетный WEB сервер в HTA

to Luceus: Аналогично. Сам искал как это сделать. А тут наткнулся на пост The gray Cardinal и сразу стало понятнее как делать. )

2 NikR:

NikR пишет:

Read нормально работает с нетекстовыми символами, а вот ReadAll, бывает, глючит.

Хм.. А я пока в гугле искал, всё время натыкался на фразы

FilesSystemObject can't read/write binary files !


Пытаюсь читать файл в режиме TristateTrue (Unicode)
Пока получаю покорёженное тело файла ) Буду искать дальше.

Нет смысла в манифесте, если в нём нельзя указать лицензию. А можно ли - вопрос.

Ммм. Ясно. А вообще для общего понимания процесса, можете объяснить, что я не так делаю ?
1) Скачал regsvr42.exe
2) Сгенерил ей манифест на MSWINSCK.OCX
3) Как понял нужен ещё и манифест на WScript.exe. (т.к он выполняет скрипт и создаёт объекты через CreateObject.) Создал и его. Взял из поста max7
4) Пытаюсь создать винсок через CreateObject. Получаю стандартное сообщение

Невозможно создание объекта контейнером ActiveX...

Вот код манифеста.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
    type="win32"
    name="MSWINSCK.ocx"
    version="1.0.0.0" />

<file name="MSWINSCK.ocx">

    <comClass
        description="Microsoft WinSock Control, version 6.0 (SP6)"
        clsid="{248DD896-BB45-11CF-9ABC-0080C7E7B78D}"
        threadingModel="Apartment"
        progid="MSWinsock.Winsock"
        tlbid="{248DD890-BB45-11CF-9ABC-0080C7E7B78D}" />

    <comClass
        description="Microsoft WinSock Control, version 6.0 (SP6)"
        clsid="{39977C62-C383-463D-AF61-C71220634656}"
        threadingModel="Apartment"
        progid="MSWinsock.Winsock"
        tlbid="{248DD890-BB45-11CF-9ABC-0080C7E7B78D}" />

    <comClass
        description="Microsoft WinSock Control, version 6.0 (SP6)"
        clsid="{6E5311A1-325D-4FFD-9AF4-B373F02AE458}"
        threadingModel="Apartment"
        progid="MSWinsock.Winsock"
        tlbid="{248DD890-BB45-11CF-9ABC-0080C7E7B78D}" />

    <comClass
        description="Winsock General Property Page Object"
        clsid="{248DD897-BB45-11CF-9ABC-0080C7E7B78D}" />

    <typelib tlbid="{248DD890-BB45-11CF-9ABC-0080C7E7B78D}"
        version="1.0"
        helpdir="C:\WINDOWS\HELP" />

</file>

<comInterfaceExternalProxyStub
    name="IMSWinsockControl"
    iid="{248DD892-BB45-11CF-9ABC-0080C7E7B78D}"
    proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
    baseInterface="{00000000-0000-0000-C000-000000000046}"
    tlbid="{248DD890-BB45-11CF-9ABC-0080C7E7B78D}" />

<comInterfaceExternalProxyStub
    name="DMSWinsockControlEvents"
    iid="{248DD893-BB45-11CF-9ABC-0080C7E7B78D}"
    proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"
    baseInterface="{00000000-0000-0000-C000-000000000046}"
    tlbid="{248DD890-BB45-11CF-9ABC-0080C7E7B78D}" />

</assembly>
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

22

Re: HTA: Мультисокетный WEB сервер в HTA

FilesSystemObject can't read/write binary files !

Формально верно, а на практике у меня читал.

Альтернатива - ADO.Stream.Read
http://msdn.microsoft.com/en-us/library … S.85).aspx

23

Re: HTA: Мультисокетный WEB сервер в HTA

Так я как раз от ADO.Stream хочу отказаться или использовать его в связке с чем то.

По причине, которую я выше озвучил:

Сейчас наткнулся на то, что ADODB.Stream грузит в память файл целиком. Не гуд. Думаю как собрать на скриптах читалку файлов блоками.
Если кто подскажет - буду очень благодарен )

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

24

Re: HTA: Мультисокетный WEB сервер в HTA

При попытке зарегистрировать wsc компоненту, появилась следующая ошибка:

Ошибка DllInstall в C:\WINDOWS\system32\scrobj.dll
Возвращен код: 0xc0000005

В чем может быть проблема?

XC Engine
Web automation via Internet Explorer

25

Re: HTA: Мультисокетный WEB сервер в HTA

Не знаю, у меня код из поста #1 заработал сразу и без проблем .

26

Re: HTA: Мультисокетный WEB сервер в HTA

Алексей, код у меня тоже заработал без проблем. Но когда я попытался зарегистрировать wsc из примера как COM объект, у меня произошла ошибка. Такую же ошибку я получаю, когда пытаюсь зарегистрировать любой wsc как COM.

Кто-нибудь сталкивался с этим?

XC Engine
Web automation via Internet Explorer

27

Re: HTA: Мультисокетный WEB сервер в HTA

Странный эффект. Не наблюдал.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

28

Re: HTA: Мультисокетный WEB сервер в HTA

Спасибо за ответы. Буду смотреть.

Xameleon, попробовал пример немного модифицировать, и думал, что использование wsc дает возможность выполнять код в паралельном режиме - ошибся. Все равно код выполняется линейно (( Есть ли какие-либо скрытые возможности, что бы сделать выполнение кода не в линейном режиме?

Сейчас остается только один вариант - запуск дополнительного процесса, и обработка результатов в нем. Обмен между скриптами вести через переменные окружения.

XC Engine
Web automation via Internet Explorer

29 (изменено: Xameleon, 2009-10-05 15:24:16)

Re: HTA: Мультисокетный WEB сервер в HTA

Luceus Ммм... Смотря какие условия конкретной задачи поставлены. В принципе события позволяют что то подобное сделать. Если озвучите, что нужно добиться - будет проще найти решение

К примеру - http://forum.script-coding.com/viewtopic.php?id=993 В этом примере скрипт продолжает крутиться в цикле в то время как у IE происходят события. Так же можно попробывать поизощряться с htmlfile объектом. У его окна остаются SetTimeOut и SetInterVal - которые наверное можно поюзать для этих целей.

P.S Не уверен, что сработает, но попробывать можно.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

30

Re: HTA: Мультисокетный WEB сервер в HTA

Luceus, а какой командой Вы регистрируете? Случайно, не так?

regsvr32 /i Socket.wsc

У меня только она приводит к ошибке:

---------------------------
RegSvr32
---------------------------
Ошибка DllInstall в С:\WINDOWS\system32\scrobj.dll.
Возвращен код: 0x80004005
---------------------------
ОК   
---------------------------

Если регистрируете через контекстное меню через пункт "Подключить", то нужно глянуть, какая реально команда стоит в реестре по адресу HKEY_CLASSES_ROOT\scriptletfile\Shell\Register\command. Должно быть так:

"С:\WINDOWS\system32\REGSVR32.EXE" /i:"%1" "С:\WINDOWS\system32\scrobj.dll"

31

Re: HTA: Мультисокетный WEB сервер в HTA

YMP, я регистрирую через контекстное меню, как вы и описали - выбираю пункт "Подключить". И выводится такая ошибка. Я обязательно посмотрю дома, так как на работе такой проблемы нет.

Спасибо.

XC Engine
Web automation via Internet Explorer

32 (изменено: NikR, 2009-10-05 21:37:18)

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon: Вы ведь использовали Read без параметров, а я имею ввиду Read(кол-во байт) и EOF.
Цитата из ссылки (не заметили?):

The Read method reads a specified number of bytes

33 (изменено: Xameleon, 2009-10-05 22:11:36)

Re: HTA: Мультисокетный WEB сервер в HTA

to NikR: Да это для простоты кода пока что ). Сейчас уже сделал блоковое чтение по 64 килобайта. Но проблема в том, что до чтения через Read надо делать LoadFromFile. И вот тут то как раз стрим грузит весь файл в память целиком (. Это легко можно увидеть в диспетчере задач по резкому увеличению размера занимаемой памяти процессом mshta.exe. И размер подпрыгивает именно на размер файла.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

34

Re: HTA: Мультисокетный WEB сервер в HTA

YMP, проверил. Дома в реестре отсутствовало "Shell" в "scriptlet" папке. Попробовал выполнить как вы описали в командной строке - ошибка осталась прежняя.

Можно ли как-то переустановить WSC/WSH scripting??

Спасибо.

XC Engine
Web automation via Internet Explorer

35

Re: HTA: Мультисокетный WEB сервер в HTA

Luceus пишет:

Дома в реестре отсутствовало "Shell" в "scriptlet" папке.

Ну, в scriptlet и у меня этого нет, я говорил о scriptletfile.

Luceus пишет:

Попробовал выполнить как вы описали в командной строке

А какую именно команду вводили, как в точности она выглядит?

Script Components входят в установку Windows Script. Ссылки есть в этой теме. Как именно переустановить — не знаю. Возможно, alexii подскажет.

36

Re: HTA: Мультисокетный WEB сервер в HTA

Да, вроде бы никак, только поверх, убедившись, что ни wscript.exe, ни cscript.exe в процессах не светятся, и закрыв максимум приложений перед установкой. Перегрузиться. Если опять не работает, попробовать третий пункт отсюда.

37 (изменено: JSmаn, 2009-11-20 17:02:46)

Re: HTA: Мультисокетный WEB сервер в HTA

Мне очень понравилась реализация веб-сервера. Добавил возможность использования серверных  скриптов JScript и VBScript, а также использование кириллицы.

Парсер обрабатывает HTML- страницы с разметкой ASP. Допускается использование нескольких скриптовых языков одновременно. Поддерживается использование не только стандартных тегов: <script language="jscript" runat="server" /> и <script language="vbscript" runat="server" />, но и «краткий стиль»: <% %>, <%@ language="vbscript" %>, <%="text" %>. В скриптах можно использовать «Response.Write».

Планирую сделать поддержку объектов ASP и таблицу адресов (вместе c Xameleon).

Архив включает в себя полное описание алгоритма парсинга. Примечание: парсинг ведется только для файлов с расширением .htm.

Также обратите внимание на файл Parser.wsf. В контейнер <resource id="ASPContent"> Вы можете поместить содержимое asp и увидеть результат работы в Response.Buffer.

http://slil.ru/28230091

38

Re: HTA: Мультисокетный WEB сервер в HTA

Отличная создания идея HTA web server и хорошая реализация VBS, но можно HTA web server реализовать на JS заранее благодарен !!! (Очень нужно)

39 (изменено: VSVLAD, 2011-04-30 23:01:21)

Re: HTA: Мультисокетный WEB сервер в HTA

Сервер очень хороший   Решил сделать похожее, только на VB6. Кому интересно берите.

- Тестовый сайт в комплекте, настройки сервера хранятся в cfg файлах.
- Мультсокетность
- Исполнение скриптов через самописный класс ScriptControl
- Журналирование
- Работает в трее

http://zalil.ru/30957643
обновлено 30 апрель 2011

40

Re: HTA: Мультисокетный WEB сервер в HTA

Перезалейте пожалуйста winsock и сервер.

41

Re: HTA: Мультисокетный WEB сервер в HTA

2 Ottiwell_Wood: С ума сойти. Кому то ещё нужен этот код. Ок. Сегодня вечерком окажусь дома и исходники с докачкой поищу и солью.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

42

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon, извините, но куда вы их слили?:/

43

Re: HTA: Мультисокетный WEB сервер в HTA

Прошу прощения. Закрутился на работе. Голова кругом. Забыл совсем.

Вот последнее что я ковырял из кода. Сервер с докачкой. Выкладываю "портянкой кода", дабы в дальнейшем материал не пропадал. Проверить не смог, т.к ОС - Windows 7 x64. Нужен WScript.exe под 32-битную. Ссылку на MSWINSCK.OCX не публикую. Администрация против. Рекомендую поискать в интернете.


Option Explicit

'Константы объекта MSWinsock.Winsock.1
Const sckClosed = 0 	'				Default. Closed 
Const sckOpen = 1 						'Open 
Const sckListening = 2 					'Listening 
Const sckConnectionPending = 3			'Connection pending 
Const sckResolvingHost = 4 				'Resolving host 
Const sckHostResolved = 5 				'Host resolved 
Const sckConnecting = 6 				'Connecting 
Const sckConnected = 7 					'Connected 
Const sckClosing = 8 					'Peer is closing the connection 
Const sckError = 9 						'Error 

'Константы объекта SAPI.spFileStream
Const SSFMOpenForRead = 0 				'Opens an existing file as read-only.
Const SSFMOpenReadWrite = 1 			'Opens an existing file as read-write. Not supported for wav files.
Const SSFMCreate = 2 					'Opens an existing file as read-write. Else, it creates the file then opens it as read-write. Not supported for wav files.
Const SSFMCreateForWrite = 3 			'Creates file even if file exists and so destroys or overwrites the existing file.

Const SSSPTRelativeToStart = 0			'Calculates the stream offset relative from the start of the stream.
Const SSSPTRelativeToCurrentPosition = 1'Calculates the stream offset relative from the current position.
Const SSSPTRelativeToEnd = 2			'Calculates the stream offset relative from the end of the stream.

'Настройки сервера
Dim LocalPort: LocalPort = 81
Dim RootFolderPath: RootFolderPath = "wwwroot"
Dim SocketsCount: SocketsCount = 10
Dim DefaultDocuments: DefaultDocuments = Array("index.htm","index.html")
Dim ChunkSize: ChunkSize = 204800 '65536
Dim MaxHeaderSize: MaxHeaderSize = 65536 
'Глобальные переменные
Dim FileSystemObject, ExitDo, ScriptFullName, CurrentFolderPath, ContentTypes, WshShell

ReDim Sockets(SocketsCount)

Dim Streams

Initialize

'Процедура инициализации сервера
Sub Initialize()
	Dim FolderExists, TestPath
	Set FileSystemObject = CreateObject("Scripting.FileSystemObject")
	
	'Получаем путь до текущего каталога
	CurrentFolderPath = FileSystemObject.GetParentFolderName(WScript.ScriptFullName)
	
	'Проверяем существование корневого каталога сервера
	if Not FileSystemObject.FolderExists(RootFolderPath) Then
		'Если не нашли, то пробуем достроить путь до полный пути в текущем каталоге
		TestPath = FileSystemObject.BuildPath(CurrentFolderPath,RootFolderPath)
		if FileSystemObject.FolderExists(TestPath) Then
			RootFolderPath = TestPath
		Else
			Err.Raise vbObjectError + 1,"","Корневой каталог не найден."
		End if		
	End if
		
	Set Streams = CreateObject("Scripting.Dictionary")
	'Инициализируем сокеты
	
	'Создаём слушающий сокет
	Set Sockets(0) = WScript.CreateObject("MSWinsock.Winsock.1","Socket_")

	'Включаем слушанье порта
	Sockets(0).localPort = 81
	Sockets(0).Listen

	'Создаём отвечающие сокеты
	Dim i
	For i=1 to SocketsCount
		Set Sockets(i) = WScript.CreateObject("MSWinsock.Winsock.1","Socket_")
	Next

	'Создаём коллекцию типов содержимого
	Set ContentTypes = CreateObject("Scripting.Dictionary")
	
	'Создаём объект для чтения реестра
	Set WshShell = CreateObject("WScript.Shell")

	'RegisterGlobalObject me

	'Начинаем цикл ядра сервера
	Do
		'Делаем паузу, чтобы не нагружать процессор компьютера.
		WScript.Sleep 100
	Loop Until ExitDo 'Err.Number <> 0
End Sub

'Событие получения запроса
Sub Socket_ConnectionRequest(ByVal requestID)
	'On Error Resume Next
	Dim i
	For i = 1 to SocketsCount
		if Sockets(i).State = sckClosed Then 
			Sockets(i).Accept(requestID)
			Exit Sub
		End if
	Next
	if err.Number <> 0 Then AppendToLog "MainSocket_ConnectionRequest " & Err.Description
End Sub

'Событие прихода данных
Sub Socket_DataArrival(ByVal bytesTotal)
	'On Error Resume Next
	Dim RequestData, Headers, HeaderParts, method, url, protocol, FilePath, TestPath, DefaultDocument, File, ExtensionName, NewFileStream, StartPos, EndPos, i, Range, ValueParts, ResponseData, buffer
	'Получаем данные запроса
	me.GetData RequestData, vbString, MaxHeaderSize

	AppendToLog "<-" & vbCrlf & RequestData

	'Разбираем заголовок
	Headers = Split(RequestData,vbCrlf)
	'Проверяем верность формата заголовка
	if Ubound(Headers) < 0 Then 
		me.SendData "HTTP/1.0 400 Bad Request" & vbCrlf & vbCrlf & "400 Bad Request"
		Exit Sub
	End if
	'Получаем первый заголовок
	HeaderParts = Split(Headers(0)," ")
	if Ubound(HeaderParts) < 2 Then 
		me.SendData "HTTP/1.0 400 Bad Request" & vbCrlf & vbCrlf & "400 Bad Request"
		Exit Sub
	End if
	'Получаем метод передачи данных
	method = UCase(HeaderParts(0))
	
	Select Case method
	Case "GET"
	Case "HEAD"
	Case Else
		me.SendData "HTTP/1.0 400 Bad Request" & vbCrlf & vbCrlf & "400 Bad Request"
		Exit Sub
	End Select
	
	'Выделяем url
	url = HeaderParts(1)
	'Получаем протокол
	protocol = HeaderParts(2)
	
	'Проверяем - указано ли имя файла
	if FileSystemObject.GetFileName(url) <> "" Then
		'Достраиваем путь до физического файла на диске
		TestPath = FileSystemObject.BuildPath(RootFolderPath,url)
		'Проверяем существование файла
		if FileSystemObject.FileExists(TestPath) Then FilePath = TestPath
	Else
		For Each DefaultDocument in DefaultDocuments
			TestPath = FileSystemObject.BuildPath(RootFolderPath,DefaultDocument)
			if FileSystemObject.FileExists(TestPath) Then
				FilePath = TestPath
				Exit For
			End if
		Next
	End if
	
	'Если файл не найден
	if FilePath = "" Then
		me.sendData protocol & " 404 Not Found" & vbCrlf & vbCrlf & "404 Not Found"
		Exit Sub
	End if

	Set File = FileSystemObject.getfile(FilePath)
	ExtensionName = LCase(FileSystemObject.GetExtensionName(File.Name))

	Set NewFileStream = New clsFileStream
	NewFileStream.OpenFile File.Path
	Set Streams(me.sockethandle) = NewFileStream
	
	StartPos = 0
	EndPos = File.Size
	'Перебираем заголовки начиная со второго
	For i = 1 to Ubound(Headers)
		'Делим заголовок на части
		HeaderParts = Split(Headers(i),":",2)
		'Обрабатываем заголовки
		if Ubound(HeaderParts) = 1 Then
			Select Case LCase(HeaderParts(0))
			Case "range"
				'Ликвидируем пробелы, обрезаем часть bytes= и делим заголовок по "-"
				Range = HeaderParts(1)
				Range = Replace(Range," ","")
				Range = Replace(Range,"bytes=","")
				ValueParts = Split(Range,"-",2)
				if Ubound(ValueParts) = 1 then
					if isNumeric(ValueParts(0)) Then 
						StartPos = CDbl(ValueParts(0))
						if isNumeric(ValueParts(1)) Then EndPos = CDbl(ValueParts(1))
					End if
				End if
			End Select
		End if
	Next

	'Если требуется выполнить докачку
	if Range <> "" Then
		NewFileStream.Position = EndPos
		NewFileStream.SetEOS
		NewFileStream.Position = StartPos
		ResponseData = protocol & " 206 Partial Content" & vbCrlf & _
					   "Content-Type: " & GetContentType(ExtensionName) & vbCrlf & _
					   "Content-Range: bytes " & StartPos & "-" & EndPos - 1 & "/" &  File.Size & vbCrlf & _
					   "Content-Length: " & EndPos - StartPos & vbCrlf
	Else
		ResponseData = protocol & " 200 OK" & vbCrlf & _
					   "Accept-Ranges: bytes" & vbCrlf & _
					   "Content-Type: " & GetContentType(ExtensionName) & vbCrlf & _
					   "Content-Length: " & EndPos & vbCrlf
	End if

	AppendToLog "->" & vbCrlf & ResponseData
	
	me.SendData ResponseData & vbCrlf
	NewFileStream.Read buffer, ChunkSize
	me.sendData buffer

	if err.Number <> 0 Then AppendToLog "ProcessRequest " & Err.Description
End Sub

'Событие окончания отправки данных
Sub Socket_SendComplete()
	'On Error Resume Next
	Dim FileStream, Buffer, sockethandle, Stream
	sockethandle = me.sockethandle
	if Streams.Exists(sockethandle) Then
		Set Stream = Streams(sockethandle)
		if me.state = sckClosing or me.state = sckError or Stream.AtEndOfStream Then 
			Stream.Close
			me.Close
			Exit Sub
		End if
		Stream.Read buffer, ChunkSize
		if me.state = sckConnected Then me.sendData buffer
	End if
	if err.Number <> 0 Then AppendToLog "Socket_SendComplete " & Err.Description
End Sub

Sub Socket_SendProgress(ByVal bytesSent, ByVal bytesRemaining)
	'On Error Resume Next
	if err.Number <> 0 Then AppendToLog "Socket_SendProgress " & Err.Description
End Sub

Sub Socket_Error(ByVal Number, Description, ByVal Scode, ByVal Source, ByVal HelpFile, ByVal HelpContext, CancelDisplay)
	'On Error Resume Next
	'AppendToLog "Socket error event"
	'me.Close
	if err.Number <> 0 Then AppendToLog "Socket_Error " & Err.Description
End Sub

Sub Socket_Close()
	Dim sockethandle
	sockethandle = me.sockethandle
	AppendToLog "Socket close event"
	if Streams.Exists(sockethandle) Then Streams(sockethandle).Close
End Sub

'Sub Socket_Connect()

'End Sub


Function GetContentType(ext)
	'On Error Resume Next
	GetContentType = ContentTypes(ext)
	if GetContentType = "" Then
		GetContentType = WshShell.RegRead("HKEY_CLASSES_ROOT\." & ext & "\Content Type")
		if GetContentType = "" Then GetContentType = "octet/stream"
		ContentTypes(ext) = GetContentType
	End if
End Function

'Класс для потокового чтения файлов
Class clsFileStream
    Private spFileStream, mvar_size, mvar_Position, mvar_AtEndOfStream, NumberOfBytes

    'Инициализация класса
    Private Sub Class_Initialize()
        Set spFileStream = CreateObject("SAPI.spFileStream")
    End Sub

    'Свойство установки и получения позиции в файле
    Public Property Let Position(byval value)
        mvar_Position = CDbl(spFileStream.Seek(value, SSSPTRelativeToStart))
		If value >= mvar_size Then 
			mvar_AtEndOfStream = True
		Else
			mvar_AtEndOfStream = False
		End if
    End Property

    Public Property Get Position()
        Position = mvar_Position
    End Property

    'Функция открытия файла
    Function OpenFile(FileName)
        On Error Resume Next
        mvar_size = Empty
        mvar_AtEndOfStream = False
        spFileStream.Close
        OpenFile = spFileStream.Open(FileName, SSFMOpenForRead)
        mvar_size = Cdbl(spFileStream.Seek(0, SSSPTRelativeToEnd))
        spFileStream.Seek 0, SSSPTRelativeToStart
    End Function

    'Свойство - размер файла
    Public Property Get Size()
        Size = mvar_size
    End Property
	
	Sub SetEOS
		mvar_size = mvar_Position
	End Sub
	
    'свойство - Флаг окончания данных
    Public Property Get AtEndOfStream()
        'if mvar_Position => mvar_size Then AtEndOfStream = True 
		AtEndOfStream = mvar_AtEndOfStream
    End Property

    Function Read(buffer, ByVal NumberOfBytes)
		On Error Resume Next
    '    mvar_Position = mvar_Position + NumberOfBytes
        'Если позиция чтения превышает размер файла, то смещаем курсор на допустимую позицию
        If mvar_Position + NumberOfBytes > mvar_size Then
            NumberOfBytes = mvar_size - mvar_Position
            mvar_AtEndOfStream = True
        End If
        mvar_Position = mvar_Position + NumberOfBytes
		Read = spFileStream.Read(buffer, NumberOfBytes)
    End Function
	
	Sub Close
		On Error Resume Next
		spFileStream.Close
	End Sub
End Class

Function AppendToLog(Text)
	Dim FSO
	Set FSO = CreateObject("Scripting.FileSystemObject")
	FSO.OpenTextFile(FileSystemObject.BuildPath(CurrentFolderPath,"log.txt"),8,True).WriteLine Now & ":" & Text
End Function
Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

44

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon пишет:

…дабы в дальнейшем материал не пропадал…

…стоит помещать в Коллекцию.

45

Re: HTA: Мультисокетный WEB сервер в HTA

alexii думал об этом, но пример ещё до конца не "допилен". Совесть не позволяет пихать что попало в святыню.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

46

Re: HTA: Мультисокетный WEB сервер в HTA

Спасибо!

47 (изменено: Ottiwell_Wood, 2011-05-05 22:48:21)

Re: HTA: Мультисокетный WEB сервер в HTA

Xameleon, не могли бы вы описать метод Post?
Я хочу добавить графический интерфейс и всё такое...

48

Re: HTA: Мультисокетный WEB сервер в HTA

А что именно Вас интересует ? Метод передачи POST применяется очень разносторонне. При передаче текстовых данных это одно, при передаче двоичных данных - другое.

Вот примеры справочной информации:
http://forum.script-coding.com/viewtopi … 8233#p8233
http://www.codenet.ru/webmast/php/HTTP-POST.php#part_3

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

49

Re: HTA: Мультисокетный WEB сервер в HTA

Насчёт ADODB.Stream: у нас есть и assembler-программисты! Никто что-ли не может сварганить какой нибудь ActiveX'ик?

50 (изменено: alexii, 2014-02-02 18:56:51)

Re: HTA: Мультисокетный WEB сервер в HTA

на Win7 x32

GetContentType = WshShell.RegRead("HKEY_CLASSES_ROOT\." & ext & "\Content Type")

выдает ошибку, так как в реестре не оказалось "Content Type" для ".zip"
для себя вот так подправил:

Function GetContentType(ext)
    On Error Resume Next
    GetContentType = ContentTypes(ext)
    if GetContentType = "" Then
        GetContentType = WshShell.RegRead("HKEY_CLASSES_ROOT\." & ext & "\Content Type")
        if GetContentType = "" Then GetContentType = "octet/stream"
        ContentTypes(ext) = GetContentType
    End if
        On Error Goto 0
End Function

51

Re: HTA: Мультисокетный WEB сервер в HTA

sergey_kan, оформите код тегом "code", как это требуют Правила форума.