Что скажете про DllRegisterServerEx?
От: retalik www.airbandits.com/
Дата: 16.09.02 14:03
Оценка:
Всем привет!

Имеется задача: узнать семантику вызова загадочной функции DllRegisterServerEx, о которой на MSDN практически ни слова нет. Она с недавних пор экспортируется из COM-серверов Microsoft с нетривиальной инициализацией...

Черт, лучше скажу, зачем это надо.

Дано: имеется скриптовый компонент (WSC), который условно назовем "CodeColorer.wsc". Он правильно написан и содержит в себе море JScript-ового кода. При вызове "regsvr32 CodeColorer.wsc" он правильно регистрируется в системе и доступен по ProgId (если regsvr32.exe достаточно свежей версии).
Необходимо: те же действия выполнить программно, регистрацией scrobj.dll (в которой и содержится код работы с WSC).

Вот такой код, в лоб, не проходит:

#include <windows.h>

HRESULT (*pReg)( LPCSTR pszCmdLine );

void main()
{
    
    HMODULE h=LoadLibrary("scrobj.dll");
    if(!h) return;
    (void *&)pReg=GetProcAddress(h, "DllRegisterServerEx");
    if(!pReg) return;
    pReg("CodeColorer.wsc");
}

При этом появляется загадочное сообщение "Не удается создать обработчик интерфейса: Automation".
Внимание, вопрос: что же в приведенном коде неправильно?

PS: Поскольку на виртуальное пиво никто не купится, предлагаю в качестве награды крупные оценки
Успехов,
Виталий.
Re: Что скажете про DllRegisterServerEx?
От: TK Лес кывт.рф
Дата: 16.09.02 14:16
Оценка:
Здравствуйте retalik, Вы писали:

R>Всем привет!


R>Имеется задача: узнать семантику вызова загадочной функции DllRegisterServerEx, о которой на MSDN практически ни слова нет. Она с недавних пор экспортируется из COM-серверов Microsoft с нетривиальной инициализацией...


R>Черт, лучше скажу, зачем это надо.


R>Дано: имеется скриптовый компонент (WSC), который условно назовем "CodeColorer.wsc". Он правильно написан и содержит в себе море JScript-ового кода. При вызове "regsvr32 CodeColorer.wsc" он правильно регистрируется в системе и доступен по ProgId (если regsvr32.exe достаточно свежей версии).

R>Необходимо: те же действия выполнить программно, регистрацией scrobj.dll (в которой и содержится код работы с WSC).

R>Вот такой код, в лоб, не проходит:



R>При этом появляется загадочное сообщение "Не удается создать обработчик интерфейса: Automation".

R>Внимание, вопрос: что же в приведенном коде неправильно?

Так может создать dll с нужным именем и функцией. Запустить из отладчика и посмотреть, что будет в стеке лежать...

Хотя, я бы этот CodeColorer.wsc держал в ресурсе и о регистрации даже-бы и не думал... Он, что на столько большой?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Что скажете про DllRegisterServerEx?
От: retalik www.airbandits.com/
Дата: 16.09.02 14:21
Оценка:
Здравствуйте TK, Вы писали:
TK>Так может создать dll с нужным именем и функцией. Запустить из отладчика и посмотреть, что будет в стеке лежать...
Ты знаешь, я так и делал. Вызывается DllRegisterServerEx с (одним ли?) параметром LPCSTR — именем файла...
То есть, то же самое, что и в приведенном куске.

TK>Хотя, я бы этот CodeColorer.wsc держал в ресурсе и о регистрации даже-бы и не думал... Он, что на столько большой?

Не понял — а как потом создавать из VBA объект, который реализован в CodeColorer.wsc?
Успехов,
Виталий.
Re[3]: Что скажете про DllRegisterServerEx?
От: TK Лес кывт.рф
Дата: 16.09.02 14:31
Оценка: 19 (2)
Здравствуйте retalik, Вы писали:

R>Здравствуйте TK, Вы писали:

TK>>Так может создать dll с нужным именем и функцией. Запустить из отладчика и посмотреть, что будет в стеке лежать...
R>Ты знаешь, я так и делал. Вызывается DllRegisterServerEx с (одним ли?) параметром LPCSTR — именем файла...
R>То есть, то же самое, что и в приведенном куске.

...

TK>>Хотя, я бы этот CodeColorer.wsc держал в ресурсе и о регистрации даже-бы и не думал... Он, что на столько большой?

R>Не понял — а как потом создавать из VBA объект, который реализован в CodeColorer.wsc?

что-то вида:


Set oColorer = GetObject("script:CodeColorer.wsc") 'И никаких регистраций
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: Что скажете про DllRegisterServerEx?
От: George Seryakov Россия  
Дата: 16.09.02 14:47
Оценка: 35 (2)
Здравствуйте retalik, Вы писали:


R>
R>#include <windows.h>

R>HRESULT (*pReg)( LPCSTR pszCmdLine );

R>void main()
R>{
R>    
R>    HMODULE h=LoadLibrary("scrobj.dll");
R>    if(!h) return;
R>    (void *&)pReg=GetProcAddress(h, "DllRegisterServerEx");
R>    if(!pReg) return;
R>    pReg("CodeColorer.wsc");
R>}
R>

R>При этом появляется загадочное сообщение "Не удается создать обработчик интерфейса: Automation".
R>Внимание, вопрос: что же в приведенном коде неправильно?

CoInitialize не пробовал вызвать?
GS
Re[4]: Что скажете про DllRegisterServerEx?
От: retalik www.airbandits.com/
Дата: 17.09.02 09:09
Оценка:
Здравствуйте TK, Вы писали:
R>>Не понял — а как потом создавать из VBA объект, который реализован в CodeColorer.wsc?

TK>что-то вида:

TK>
TK>Set oColorer = GetObject("script:CodeColorer.wsc") 'И никаких регистраций
TK>

А можно рабочий пример?
У меня на машине не зарегистрирован протокол script:. Если ты имел в виду javascript:, то из wsc он вызывать код не хочет (да и, в любом случае, открывает совсем не нужное окно IE).
Оценку я все же поставил, надеюсь на продолжение

PS: как вызвать из приложения код на JS, я, в общем, знаю. Но мне очень хочется уметь регистрировать скриптлеты самостоятельно (да и интерес заел: что это за функция такая секретная?).

PPS: сейчас поищу в исходниках ActivePerl (там вполне может быть ее реализация для модуля PerlScript).
Успехов,
Виталий.
Re[2]: Что скажете про DllRegisterServerEx?
От: retalik www.airbandits.com/
Дата: 17.09.02 09:19
Оценка:
Здравствуйте George Seryakov, Вы писали:
GS>CoInitialize не пробовал вызвать?

О, шаман! Конечно же, нет

Кстати, иногда DllRegisterServer вызывается и без этого. Например, какой-то популярный инсталлятор (чуть ли не InstallShield) этого не делал, и сложные COM-модули не регистрировались. Но меня это не оправдывает

Добавил CoInitialize. Теперь вызывает AV, причем в дебаге поймал сообщение о порче стека. Ага, переделал описание на
HRESULT (WINAPI *pReg)( LPCSTR pszCmdLine );

, все равно валится при выходе из программы , но регистрирует! Осталось совсем чуть-чуть...
DllRegisterServerEx:
5D35A056  sub         esp,10h 
5D35A059  mov         eax,dword ptr [esp+14h] 
5D35A05D  lea         ecx,[esp] 
5D35A060  push        esi  
. . .
5D35A09A  pop         esi  
5D35A09B  add         esp,10h 
5D35A09E  ret         4

Разве это не похоже на stdcall с одним параметром?
Успехов,
Виталий.
Re[5]: Что скажете про DllRegisterServerEx?
От: TK Лес кывт.рф
Дата: 17.09.02 09:28
Оценка: 63 (5)
Здравствуйте retalik, Вы писали:

R>Здравствуйте TK, Вы писали:

R>>>Не понял — а как потом создавать из VBA объект, который реализован в CodeColorer.wsc?

TK>>что-то вида:

TK>>
TK>>Set oColorer = GetObject("script:CodeColorer.wsc") 'И никаких регистраций
TK>>

R>А можно рабочий пример?

Alert.vbs
ScriptPath = "file://" & Replace(WScript.ScriptFullName, "vbs", "wsc")

Set oAlert = GetObject("script:" & ScriptPath)
oAlert.Message = "My Message"
oAlert.Show (Now)


Alert.wsc
<?xml version="1.0"?>
<component>
    <public>
        <property name="Message" />
        <method name="Show" />
    </public>
    
    <script language="VBScript">
    <![CDATA[
        Dim Message
        Function Show (Time)
            MsgBox Message & ":" & Time
        End Function 
    ]]>
    </script>
</component>


Все сложить в одну папку. запускать *.vbs

R>У меня на машине не зарегистрирован протокол script:. Если ты имел в виду javascript:, то из wsc он вызывать код не хочет (да и, в любом случае, открывает совсем не нужное окно IE).


Должен быть script {06290BD3-48AA-11D2-8432-006008C3FBFC}
R>Оценку я все же поставил, надеюсь на продолжение



R>PS: как вызвать из приложения код на JS, я, в общем, знаю. Но мне очень хочется уметь регистрировать скриптлеты самостоятельно (да и интерес заел: что это за функция такая секретная?).


Хотя, по мне лучше когда приложение можно распространять копированием... Все-таки это удобнее...


R>PPS: сейчас поищу в исходниках ActivePerl (там вполне может быть ее реализация для модуля PerlScript).


Вряд-ли...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[5]: Это моникер из SCROBJ.DLL
От: Vi2 Удмуртия http://www.adem.ru
Дата: 17.09.02 09:35
Оценка: 16 (1)
Здравствуйте retalik, Вы писали:

R>У меня на машине не зарегистрирован протокол script:. Если ты имел в виду javascript:, то из wsc он вызывать код не хочет (да и, в любом случае, открывает совсем не нужное окно IE).


А это и есть та SCROBJ.DLL, которую ты пытаешься зарегистрировать.

HKCR\script = s 'Moniker to a Windows Script Component'
    CLSID = s '{06290BD3-48AA-11D2-8432-006008C3FBFC}'

HKCR\CLSID\{06290BD3-48AA-11D2-8432-006008C3FBFC} = s 'Moniker to a Windows Script Component'
    Implemented Categories = s ''
        {7DD95801-9882-11CF-9FA9-00AA006C42C4} = s ''
    InprocServer32 = s 'D:\WINNT\System32\SCROBJ.DLL'
        ThreadingModel = s 'Apartment'
    ProgID = s 'script'
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[6]: Это моникер из SCROBJ.DLL
От: retalik www.airbandits.com/
Дата: 17.09.02 12:49
Оценка:
Здравствуйте Vi2, Вы писали:
R>>У меня на машине не зарегистрирован протокол script:. Если ты имел в виду javascript:, то из wsc он вызывать код не хочет (да и, в любом случае, открывает совсем не нужное окно IE).
Vi2>А это и есть та SCROBJ.DLL, которую ты пытаешься зарегистрировать.

Спасибо, нашел.
Я стормозил, думал, что это Pluggable Protocol, а это, оказывается, URL Moniker

Спасибо, ребята! Но, если узнаете про DllRegisterServerEx, дайте знать
Успехов,
Виталий.
Re[7]: Это моникер из SCROBJ.DLL
От: TK Лес кывт.рф
Дата: 17.09.02 13:16
Оценка:
Здравствуйте retalik, Вы писали:

R>Спасибо, ребята! Но, если узнаете про DllRegisterServerEx, дайте знать


Вот упорный-то Чем тебе GetObject("script:...") то не нравится?

HRESULT (WINAPI* DllRegisterServerEx)(LPCSTR pszCmdLine);

void main()
{
    CoInitialize(NULL);
    HMODULE hScrObj = LoadLibrary("scrobj.dll");    
    DllRegisterServerEx = (HRESULT (WINAPI*)(LPCSTR pszCmdLine)) GetProcAddress(hScrObj, "DllRegisterServerEx");
    DllRegisterServerEx("D:\\Test\\Alert.wsc");
}



Set oComponent = CreateObject ("Component.TestScript")
MsgBox oComponent.Factorial(5)



<?XML version="1.0"?>
<component>
<registration
   progid="Component.TestScript"
   description="My Test Component"
   version="1"/>

<public>
   <property name="name"/>
   <method name="factorial"/>
</public>

<script language="VBScript">
   <![CDATA[
   Function factorial(n)
      If isNumeric(n) Then
         If n <= 1 Then
            factorial = 1
         Else
            factorial = n*factorial(n-1)
         End If
      Else
         factorial = -2   ' Error code.
      End If
   End Function
   ]]>
</script>
</component>
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[8]: Это моникер из SCROBJ.DLL
От: retalik www.airbandits.com/
Дата: 19.09.02 06:47
Оценка:
Здравствуйте TK, Вы писали:

Извиняюсь за продолжительное молчание — дела были, а ответить нужно было подробно

TK>Вот упорный-то Чем тебе GetObject("script:...") то не нравится?

Да я инсталлятор пишу, и хотелось добавить в него возможность регистрации скриптлетов.

[skip]

Так вот, проверил еще раз: как я уже писал в ответе GS, не нравится тем, что падает с AV. В отладчике при выполнении CRT-кода завершения лезет какая-то мура. То ли стек портится (вряд ли, так как сразу после вызова он проверяется, и ошибку не выдает), то ли регистры... Поэтому я и подозреваю, что это не STDCALL(LPCSTR).

Теперь — о симптомах. При вызове твоего кода с твоим компонентом все замечательно регистрируется. При вызове твоего кода с этим... кгхм... CodeColorer все замечательно регистрируется,.. а потом "память не может быть read".
Вот полный текст программки:
#include <windows.h>

#pragma comment(lib, "user32")
#pragma comment(lib, "ole32")

HRESULT (WINAPI* DllRegisterServerEx)(LPCSTR pszCmdLine);

void main(int argc, char** argv)
{
    if(argc!=2) return;
    CoInitialize(NULL);
    HMODULE hScrObj = LoadLibrary("scrobj.dll");    
    (void*&)DllRegisterServerEx = GetProcAddress(hScrObj, "DllRegisterServerEx");
    if(SUCCEEDED(DllRegisterServerEx(argv[1])) 
        MessageBox(0, "DllRegisterServerEx succeeded", argv[1], MB_OK);
    CoUninitialize();
}

Падает уже после MessageBox-а.

Вот я и не пойму: у меня система такая кривая или руки Но ведь regsvr32 регистрирует оба компонента за милую душу... Может, в нем SEH втихую глотается?
Успехов,
Виталий.
Re[9]: Это моникер из SCROBJ.DLL
От: Андрей Россия  
Дата: 19.09.02 07:00
Оценка:
Здравствуйте retalik, Вы писали:

skip

R>Вот я и не пойму: у меня система такая кривая или руки Но ведь regsvr32 регистрирует оба компонента за милую душу... Может, в нем SEH втихую глотается?


Вообще-то тот regsvr32, который в примерах к MSDN идет (к сожалению, сильно урезанный), работает через OleInitialize/OleUninitialize и LoadLibraryEx — попробуй их использовать. Чем черт не шутит, вдруг поможет?
Re[9]: А может CodeColorer is bad
От: Vi2 Удмуртия http://www.adem.ru
Дата: 19.09.02 07:02
Оценка:
Здравствуйте retalik, Вы писали:

R>Теперь — о симптомах. При вызове твоего кода с твоим компонентом все замечательно регистрируется. При вызове твоего кода с этим... кгхм... CodeColorer все замечательно регистрируется,.. а потом "память не может быть read".


Так, может, CodeColorer того-этого, а не DllRegisterServerEx — не STDCALL(LPCSTR). Не в "консерватории" же дело, если для TestScript всё нормально проходит.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[9]: Это моникер из SCROBJ.DLL
От: TK Лес кывт.рф
Дата: 19.09.02 07:10
Оценка: 35 (2)
Здравствуйте retalik, Вы писали:

R>Извиняюсь за продолжительное молчание — дела были, а ответить нужно было подробно


TK>>Вот упорный-то Чем тебе GetObject("script:...") то не нравится?

R>Да я инсталлятор пишу, и хотелось добавить в него возможность регистрации скриптлетов.

Выкрутился Видно эти умники что-то в scrobj.dll так намудрили, что ее нужно явно выгружать...

CoInitialize(NULL);
HMODULE hScrObj = LoadLibrary("scrobj.dll");    
DllRegisterServerEx = (HRESULT (WINAPI*)(LPCSTR pszCmdLine)) GetProcAddress(hScrObj, "DllRegisterServerEx");
DllRegisterServerEx("D:\\Test\\CodeColorer.wsc");
FreeLibrary(hScrObj);
CoUninitialize();
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[10]: Это моникер из SCROBJ.DLL
От: Алекс Россия http://wise-orm.com
Дата: 19.09.02 07:26
Оценка:
Здравствуйте TK, Вы писали:

хъ

TK>
TK>CoInitialize(NULL);
TK>HMODULE hScrObj = LoadLibrary("scrobj.dll");    
TK>DllRegisterServerEx = (HRESULT (WINAPI*)(LPCSTR pszCmdLine)) GetProcAddress(hScrObj, "DllRegisterServerEx");
TK>DllRegisterServerEx("D:\\Test\\CodeColorer.wsc");
TK>FreeLibrary(hScrObj);
TK>CoUninitialize();
TK>


Да нет, они, скорее всего, в DLL_PROCESS_DETACH юзают СОМ, а он уже к этому времени похерен CoUninitialize().
Наверняка, если ее не вызывать вообще все будет ОК.
Re[10]: Супер! Спасибо.
От: retalik www.airbandits.com/
Дата: 19.09.02 07:27
Оценка:
Здравствуйте TK, Вы писали:

TK>Выкрутился Видно эти умники что-то в scrobj.dll так намудрили, что ее нужно явно выгружать...

Все работает. Видимо, что-то накрутили в JScript.dll.

Вот за это я и люблю форумы RSDN Как-нибудь на досуге надо будет статейку написать "DllRegisterServerEx и как с ней бороться"
Успехов,
Виталий.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.