26

Re: WSH: Использование COM-сервера без его регистрации в системе

Страничка проекта (на английском)  http://www.codeproject.com/KB/COM/regsv … view=Quick

27

Re: WSH: Использование COM-сервера без его регистрации в системе

Но хочу заметить, что regsvr42 не всегда корректно срабатывает. Он перехватывает вызовы winapi функций работы с реестром (Reg*). И если компонент регистрируется каким-то "нестандартным" способом, результирующий файл приходится поправлять вручную на основе IDL http://msdn.microsoft.com/en-us/library … 85%29.aspx, содержащегося с файле компонента (*.dll, *.ocx). Выглядит это обычно так, пример

sqlite3.dll LiteX Automation
// Generated .IDL/C++ pseudo source equivalent of Win32 type library ..\<Unknown>
[
  uuid({10770BEB-5AFA-4851-B68E-EE891F3DEE7F}),
  version(1.0)
]
library LITEXLib
{
    // Forward references and typedefs
    dispinterface ILiteConnection;
    interface ILiteConnectionPrivate;
    dispinterface ILiteBusy;
    dispinterface ILiteProgress;
    dispinterface ILiteStatement;
    dispinterface ILiteRows;
    dispinterface ILiteColumns;
    dispinterface ILiteColumn;
    dispinterface ILiteRow;
    dispinterface ILiteParameters;
    dispinterface ILiteParameter;
    dispinterface ILargeInteger;

    [
      uuid({3E22694D-7B92-42A1-89A7-668E2F7AA107})
    ]
    coclass LiteConnection
    {
        [default] dispinterface ILiteConnection;
        interface ILiteConnectionPrivate;
        [source] dispinterface ILiteBusy;
        [default, source] dispinterface ILiteProgress;
    };

    [
      uuid({7ADFDFCF-8B4E-42A2-B458-3CA6F2DB7FE4})
    ]
    dispinterface ILiteConnection
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget] VARIANT Version([in] boolean bString);
            [id(8), propget] BSTR Path();
            [id(9), propput] void Path([in] BSTR rhs);
            [id(10)] void Open([in] BSTR bsPath);
            [id(11)] void Close();
            [id(12)] IDispatch* Prepare([in] BSTR bsCommand);
            [id(13), vararg] VARIANT Execute(
                            [in] BSTR bsCommand, 
                            [in, optional] SAFEARRAY(VARIANT)* params);
            [id(14), propget] long Changes();
            [id(15), propget] VARIANT LastInsertRowid();
            [id(16)] void OpenInMemory();
            [id(17)] void BatchExecute([in] BSTR bsSql);
            [id(18), propget] long ProgressPeriod();
            [id(19), propput] void ProgressPeriod([in] long rhs);
            [id(20)] void Interrupt();
    };

    [
      odl,
      uuid({7ADFDFCF-8B4E-42A2-B458-3CA6F2DB7FE3})
    ]
    interface ILiteConnectionPrivate : IUnknown
    {
        HRESULT _stdcall GetDB([out, retval] void** pDB);
    };

    [
      uuid({E3481F74-CB68-4D47-9F69-99D256089569}),
      helpstring("Return VARIANT_TRUE to continue or VARIANT_FALSE to abort.")
    ]
    dispinterface ILiteBusy
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7)] boolean Busy([in] long nTimes);
    };

    [
      uuid({E3481F74-CB68-4D47-9F69-99D256089570}),
      helpstring("Return VARIANT_TRUE to continue or VARIANT_FALSE to abort.")
    ]
    dispinterface ILiteProgress
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7)] boolean Progress();
    };

    [
      uuid({453A51CC-F944-4643-9540-A78253B8019C})
    ]
    coclass LiteStatement
    {
        [default] dispinterface ILiteStatement;
    };

    [
      uuid({AD13FFC0-BA5D-4B6C-ACBF-D1C44D0DA9B5})
    ]
    dispinterface ILiteStatement
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget] IDispatch* ActiveConnection();
            [id(8), propput] void ActiveConnection([in] IDispatch* rhs);
            [id(9), propget] BSTR CommandText();
            [id(10), propput] void CommandText([in] BSTR rhs);
            [id(11)] void Prepare([in] BSTR bsCommand);
            [id(12)] void BindParameter(
                            [in] VARIANT idx, 
                            [in] VARIANT vValue, 
                            [in] _LxTypeEnum eType);
            [id(13), propget] long ColumnCount();
            [id(14), propget] BSTR ColumnName([in] long nColumn);
            [id(15), propget] _LxTypeEnum ColumnType([in] VARIANT idx);
            [id(16), propget] VARIANT ColumnValue(
                            [in] VARIANT idx, 
                            [in] _LxTypeEnum eType);
            [id(17)] boolean Step([in] long nSteps);
            [id(18)] void Close();
            [id(19)] void Reset();
            [id(20), propget] _LxStateEnum State();
            [id(21), propget] boolean Done();
            [id(22), propget] long ParameterCount();
            [id(23), propget] BSTR ParameterName([in] long nIndex);
            [id(24), propget] VARIANT Row([in] _LxRowEnum eMode);
            [id(25), propget] VARIANT RowCount();
            [id(26), vararg] void BindParameters([in, optional] SAFEARRAY(VARIANT)* params);
            [id(27)] void Execute();
            [id(28), propget] IDispatch* Rows(
                            [in] boolean bStatic, 
                            [in] long nMaxRecords);
            [id(29), propget] IDispatch* Columns();
            [id(30), propget] IDispatch* Parameters();
    };

    typedef enum
    {
        lxUnknown = -1,
        lxNull = 0,
        lxInteger = 1,
        lxLongInteger = 2,
        lxFloat = 3,
        lxString = 4,
        lxBinary = 5,
        lxDate = 6
    } _LxTypeEnum;

    typedef enum
    {
        lxCreated = 0,
        lxPrepared = 1,
        lxExecuted = 2
    } _LxStateEnum;

    typedef enum
    {
        lxDefault = 0,
        lxArray = 1,
        lxCollection = 2
    } _LxRowEnum;

    [
      uuid({5AD25519-5946-420F-B068-BCCC3856363D})
    ]
    coclass LiteRows
    {
        [default] dispinterface ILiteRows;
    };

    [
      uuid({6A33FE52-8122-4494-A74A-9C7A04D637A4})
    ]
    dispinterface ILiteRows
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget, restricted] IUnknown* _NewEnum();
            [id(8), propget] VARIANT Count();
            [id(9), propget] IDispatch* Item([in] long nIndex);
    };

    [
      uuid({048DC1D9-E121-481C-8DFF-BC797993F2EC})
    ]
    coclass LiteColumns
    {
        [default] dispinterface ILiteColumns;
    };

    [
      uuid({4D4E89EB-4BCC-4647-8D0B-A6D7F627CA3D})
    ]
    dispinterface ILiteColumns
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget, restricted] IUnknown* _NewEnum();
            [id(8), propget] IDispatch* Item([in] VARIANT vIndex);
            [id(9), propget] long Count();
    };

    [
      uuid({10338227-2DC2-4A37-AF40-E5BF89FF4F10})
    ]
    coclass LiteColumn
    {
        [default] dispinterface ILiteColumn;
    };

    [
      uuid({56B3DD01-7CE3-4590-BFD4-856DEC9E3E85})
    ]
    dispinterface ILiteColumn
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget] long Index();
            [id(8), propget] BSTR Value();
    };

    [
      uuid({98FADC8F-1348-4EBD-B104-6D7CA93C8DEC})
    ]
    coclass LiteRow
    {
        [default] dispinterface ILiteRow;
    };

    [
      uuid({7A107497-5F9C-45D6-994B-FB2F8E802E84})
    ]
    dispinterface ILiteRow
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget] VARIANT Value();
            [id(8), propget, restricted] IUnknown* _NewEnum();
            [id(9), propget] VARIANT Item(
                            [in] long nIndex, 
                            [in] _LxTypeEnum eType);
            [id(10), propget] long Count();
    };

    [
      uuid({7BAB4761-C1FA-458A-8993-F9667DF51F32})
    ]
    coclass LiteParameters
    {
        [default] dispinterface ILiteParameters;
    };

    [
      uuid({08B1A162-3DE5-47D4-9992-964281640F2F})
    ]
    dispinterface ILiteParameters
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget, restricted] IUnknown* _NewEnum();
            [id(8), propget] IDispatch* Item(VARIANT vIndex);
            [id(9), propget] long Count();
            [id(10)] void Bind([in] SAFEARRAY(VARIANT)* params);
    };

    [
      uuid({0100C8E3-E467-4944-825D-7089A6EEC1B2})
    ]
    coclass LiteParameter
    {
        [default] dispinterface ILiteParameter;
    };

    [
      uuid({820D6CD0-98E2-496B-B01A-D3C4EB3F92C9})
    ]
    dispinterface ILiteParameter
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget] long Index();
            [id(8), propget] BSTR Name();
            [id(9)] void Bind(
                            [in] VARIANT vValue, 
                            [in] _LxTypeEnum eType);
    };

    [
      uuid({25EE8E01-5237-41F1-B29F-6AF441CF0924}),
      helpstring("LargeInteger Class")
    ]
    coclass LargeInteger
    {
        [default] dispinterface ILargeInteger;
    };

    [
      uuid({5E575221-737A-443A-9D64-13B79512D287})
    ]
    dispinterface ILargeInteger
    {
        properties:
        methods:
            [id(0), restricted] void QueryInterface(
                            [in] GUID* riid, 
                            [out] void** ppvObj);
            [id(1), restricted] unsigned long AddRef();
            [id(2), restricted] unsigned long Release();
            [id(3), restricted] void GetTypeInfoCount([out] unsigned int* pctinfo);
            [id(4), restricted] void GetTypeInfo(
                            [in] unsigned int itinfo, 
                            [in] unsigned long lcid, 
                            [out] void** pptinfo);
            [id(5), restricted] void GetIDsOfNames(
                            [in] GUID* riid, 
                            [in] char** rgszNames, 
                            [in] unsigned int cNames, 
                            [in] unsigned long lcid, 
                            [out] long* rgdispid);
            [id(6), restricted] void Invoke(
                            [in] long dispidMember, 
                            [in] GUID* riid, 
                            [in] unsigned long lcid, 
                            [in] unsigned short wFlags, 
                            [in] DISPPARAMS* pdispparams, 
                            [out] VARIANT* pvarResult, 
                            [out] EXCEPINFO* pexcepinfo, 
                            [out] unsigned int* puArgErr);
            [id(7), propget] long LowPart();
            [id(8), propput] void LowPart([in] long rhs);
            [id(9), propget] long HighPart();
            [id(10), propput] void HighPart([in] long rhs);
            [id(11), propget] wchar_t QuadPart();
            [id(12), propput] void QuadPart([in] wchar_t rhs);
            [id(13), propget] CURRENCY QuadPartCy();
            [id(14), propput] void QuadPartCy([in] CURRENCY rhs);
            [id(15), propget] wchar_t MAX_VALUE();
            [id(16), propget] wchar_t MIN_VALUE();
            [id(17), propget] CURRENCY MIN_VALUE_CY();
            [id(18), propget] CURRENCY MAX_VALUE_CY();
    };
};

28

Re: WSH: Использование COM-сервера без его регистрации в системе

JSman пишет:

Может быть проще огласить список вопросов? Не может же быть все непонятно? Скомпилированные ответы и будут содержанием темы для Коллекции.

Увы. У нас это уже обсуждалось: чтобы получить правильный ответ — нужно правильно задать вопрос, чтобы правильно задать вопрос — нужно знать большую часть ответа.

Нужны не просто ответы на вопросы, а описание самой технологии, как в ссылках, что я приводил выше в качестве примера.

29

Re: WSH: Использование COM-сервера без его регистрации в системе

SxS

Side-by-Side регистрация - это когда COM-сервер предоставляет доступ к своим объектам не регистрируя никакой информации о себе в реестре.

Начать, я думаю, можно с этих ссылок:

Статья про "Windows Side-by-Side" (на английском)
http://www.mazecomputer.com/sxs.htm
http://www.mazecomputer.com/sxs/help/inside1.htm
http://www.mazecomputer.com/sxs/help/inside2.htm

Эта тема на MSDN
http://msdn.microsoft.com/en-us/library … S.85).aspx и http://msdn.microsoft.com/en-us/library … S.85).aspx
Reference http://msdn.microsoft.com/en-us/library … S.85).aspx
"Описание работы" http://msdn.microsoft.com/en-us/library … S.85).aspx
"Для exe'шников" http://msdn.microsoft.com/en-us/library … S.85).aspx
"Для dll'ок" http://msdn.microsoft.com/en-us/library … S.85).aspx

Википедия
http://en.wikipedia.org/wiki/Side-by-side_assembly

Интересная заметка http://support.microsoft.com/kb/830033/ru

30

Re: WSH: Использование COM-сервера без его регистрации в системе

max7, ссылка на закачку regsvr42 не работает.

31

Re: WSH: Использование COM-сервера без его регистрации в системе

У меня всё нормально скачалось. Только зарегиться там пришлось.

32 (изменено: JSman, 2009-08-26 14:26:24)

Re: WSH: Использование COM-сервера без его регистрации в системе

Зарисовка.

SxS. Введение.

Технология DLL (англ. Dynamic-link library — динамически подключаемая библиотека) предназначалась для эффективной организации памяти и дискового пространства путем использования одного экземпляра библиотечного модуля для различных приложений. Это было особенно важно для ранних версий Microsoft Windows с жёсткими ограничениями по памяти.

Далее, предполагалось улучшить эффективность разработок и использования системных средств за счёт модульности. Замена DLL-программ с одной версии на другую должна была позволить независимо наращивать систему, не затрагивая приложений. Кроме того, библиотеки DLL могли использоваться разнотипными приложениями — например, Microsoft Office, Microsoft Visual Studio и т. п.

В дальнейшем идея модульности выросла в концепцию COM.
Фактически, полных преимуществ от внедрения DLL получить не удалось по причине явления, называемого DLL hell («ад DLL»). DLL Hell возникает, когда несколько приложений требуют одновременно различные, не полностью совместимые, версии DLL-библиотек, что приводит к сбоям в этих приложениях. Когда система выросла до определённых размеров, количество DLL стало превышать многие тысячи, не все из них обладали полной надёжностью и совместимостью, и конфликты типа DLL Hell стали возникать очень часто, резко понижая общую надёжность системы.

Для стабилизации работы операционной системы Microsoft ввели протективные меры. Системные файлы более не нуждались в замене. Операционная система использовала «встроенные» стабильные версии файлов. Одной из мер стало изменение работы функции LoadLibrary. В список адресных путей поиска библиотеки добавили директорию размещения приложения. Проблема с COM-компонентами не была решена из-за того, что система регистрации изначально предполагала единственную версию.

В Windows XP была включена новая технология Win32 Side-by-Side (SxS, «Бок-о-бок»). Файлы динамически подключаемых библиотек (DLL), буферов ассоциативной трансляции (TLB) и прочие можно группировать в сборки (assemblies), описываемые Win32-манифестом (manifest) — файлом формата xml. Регистрация COM компонента больше не требуется, как и размещение нужных файлов в системных директориях. Каждое приложение может использовать свой файл манифеста, решая таким образом проблему совместимости используемых компонентов («DLL Hell»).
Понятие «манифест» также существует в среде .Net. Сборки и манифесты Win32 (о которых идет речь) и .Net являются различными технологиями, поэтому не следует их путать.

С появлением SxS в системный загрузчик Windows XP и COM-компонентов были внесены изменения. Обращения к файлам, свойствам COM-компонентов и классам окон проводятся с учетом специального контекста подключения (activation context), который может быть задан в манифесте приложения. Кроме того, манифест приложения способен подключать другие манифесты. Таким образом, из списка директорий поиска функция LoadLibrary отдаст предпочтение той директории, которая указана контекстом подключения.

33

Re: WSH: Использование COM-сервера без его регистрации в системе

YMP пишет:

У меня всё нормально скачалось. Только зарегиться там пришлось.

Да, точно. Все получилось.

34

Re: WSH: Использование COM-сервера без его регистрации в системе

JSman
Нормально. Продолжение будет?

35

Re: WSH: Использование COM-сервера без его регистрации в системе

Да, я уже начал писать «SxS. Часть 1».

36

Re: WSH: Использование COM-сервера без его регистрации в системе

JSman, именно такого в итоге и ожидалось.

37 (изменено: JSman, 2009-08-27 11:49:12)

Re: WSH: Использование COM-сервера без его регистрации в системе

Манифест приложения [Application Manifest]. Общее описание структуры документа.

Манифест приложения представляет собой XML-файл, который описывает и идентифицирует нужные приложению общие и локальные сборки (shared and private side-by-side assemblies).

Синтаксис имени файла манифеста

Имя файла манифеста состоит из названия приложения и «.manifest». Этот файл может являться как ресурсом приложения, так и располагаться в директории программы или библиотеки.

1. example.exe.manifest
2. example.dll.manifest
3. example.exe.<resource ID>.manifest
4. example.dll.<resource ID>.manifest

Если идентификатор ресурса равен 1, то можно его не указывать в имени.

Элементы манифеста приложения

Имена элементов и их атрибутов, как и в любом XML-файле, регистрозависимы, исключая значения атрибутов.


Элемент <assembly> Является корневым элементом XML-документа. Обязательными первыми дочерними элементами должны быть <noInherit> или <assemblyIdentity>.

Атрибут xmlns задает пространство имен "urn:schemas-microsoft-com:asm.v1". Остальные элементы сборки также должны быть в указанном пространстве имен. Принадлежность пространству имен определяется путем наследования или прямым указанием в имени тега.

Атрибут manifsetVersion должен быть установлен в «1.0»


Элемент <noInherit /> Необязателен. Выступает в роли флага запрета наследования контекста подключения (activation context). Не рекомендуется к использованию.


Элемент <assemblyIdentity />.

1) Является первым по порядку дочерним элементом <assembly>. Элемент <assemblyIdentity> описывает и однозначно идентифицирует приложение, работающее с текущим манифестом.
2) Является первым по порядку дочерним элементом <dependentAssembly>. Элемент <assemblyIdentity> описывает связанные сборки (side-by-side assembly), требуемые приложением. Каждая сборка, упоминаемая в манифесте приложения, требует наличия элемента <assemblyIdentity>.

Атрибут type (определяет тип приложения или сборки) должен быть установлен в «Win32» или «win32».

Атрибут name задает имя сборки или приложения. Microsoft советует применять следующее форматирование для именования:  Organization.Division.Name. Например, Microsoft.Windows.mysampleApp.

Атрибут language указывает язык приложения или сборки. Необязателен. Значение по умолчанию «*». Если приложение или сборка являются языкозависимыми, задаёт DHTML-код языка.

Атрибут processorArchitecture определяет процессор. Значение «x86» используется для 32-битных приложений, «ia64» — для 64-битных.

Атрибут version определяет версию приложения или сборки. Обязателен. Форматирование значения подобно написанию IP  (делится на четыре части  тремя точками). Каждая часть — это число в диапазоне 0-65535.

Атрибут publicKeyToken требуется только для описания общих (shared) сборок. Представляет собой 16-символьное значение-идентификатор, зарегистрированных сборок в системе.


Элемент <dependency> содержит как минимум один элемент <dependentAssembly>. Не имеет атрибутов. Необязателен.


Элемент <dependentAssembly>. Не имеет атрибутов. Первым дочерним элементом <dependentAssembly> является элемент <assemblyIdentity>, который описывает связанные (Side-by-Side) сборки. Содержится в одном экземпляре в элементе <dependency>. Не имеет атрибутов.


Элемент <file>. Определяет подключаемый файл. Необязателен.

Атрибут name задает имя файла.

Атрибут hashlang задает название алгоритма хеша файла. Значение равно «SHA1».

Атрибут hash представляет собой хеш файла.

В качестве примера манифеста приложения приведу код файла «Manifest XP» — средство стилизации элементов окна.

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

<assemblyIdentity
    name="CiaoSoftware.Ciao.Shell.Contacts"
    processorArchitecture="x86"
    version="5.1.0.0"
    type="win32"/>

<description>Windows Shell</description>

<dependency>
    <dependentAssembly>

        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="x86"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />

    </dependentAssembly>
</dependency>

</assembly>

В примере указана указана ссылка на общую сборку (shared assambly). Речь о манифестах сборок пойдет в следующей части.

38

Re: WSH: Использование COM-сервера без его регистрации в системе

JSman пишет:

Атрибут language указывает язык приложения или сборки. Необязателен. Значение по умолчанию «*». Он применяется в случае использования приложений и сборок, написанных на специфичных языках, например DHTML.

Это место мне что-то подозрительно. Думаю, там речь идёт о человеческих языках, а не программирования. А DHTML упоминается в связи с кодами языков — ru, en, en-us и т.п. Можно ссылку на оригинал, чтобы точно убедиться?

И почему assemblyIdentity — пустой элемент??

39

Re: WSH: Использование COM-сервера без его регистрации в системе

Оригинал:

Identifies the language of the application or assembly. Optional. If the application or assembly is language-specific, specify the DHTML language code.

Перевод:

указывает язык приложения или сборки. Необязателен. Он применяется в случае использования приложений и сборок, написанных на специфичных языках, например DHTML.

И почему assemblyIdentity — пустой элемент??

<assemblyIdentity>
As the first subelement of an <assembly> element, <assemblyIdentity> describes and uniquely identifies the application owning this application manifest. As the first subelement of a <dependentAssembly> element, <assemblyIdentity> describes a side-by-side assembly required by the application. Note that every assembly referenced in the application manifest requires an <assemblyIdentity> that exactly matches the <assemblyIdentity> in the referenced assembly's own assembly manifest.

The <assemblyIdentity> element has the following attributes. It has no subelements.

Сейчас дополню статью примерами. Начну писать следующую часть о манифесте сборки.

40

Re: WSH: Использование COM-сервера без его регистрации в системе

Я бы перевёл

If the application or assembly is language-specific, specify the DHTML language code.

как

Если приложение или сборка является языко-зывисимыми, задаёт dhtml-код языка.

(т.е., мне кажется, имеются в виду всё-таки человеческие языки).

41

Re: WSH: Использование COM-сервера без его регистрации в системе

Исправил.

42

Re: WSH: Использование COM-сервера без его регистрации в системе

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

43

Re: WSH: Использование COM-сервера без его регистрации в системе

«Языкозависимый» написал слитно.

44 (изменено: JSman, 2009-09-08 14:54:59)

Re: WSH: Использование COM-сервера без его регистрации в системе

Манифест сборки [Assembly Manifest]. Общее описание структуры документа.

Манифест сборки представляет собой XML файл, который описывает подключаемые SxS сборки. В нем указываются имена и версии сборок, файлы, ресурсы сборок, а также связи с другими сборками. Корректная установка, подключение и запуск SxS сборок обеспечивается наличием данного манифеста, который распространяется вместе с ними.


Размещение файла

Манифест сборки размещается тремя способами:
1. Размещение в качестве отдельного файла в папке общих сборок (shared assemblies) (в так называемом кэше SxS сборок) (по умолчанию в «%Windir%\WinSxS»).
2. Размещение в качестве отдельного файла в папке частных сборок (private assemblies) (обычно там же, где и само приложение).
3. Размещение в качестве ресурса Dll. Манифест сборки не может быть ресурсом Exe, так как Exe-файл может включать (касаемо манифестов) в качестве ресурса только манифест приложения.


Синтаксис имени файла манифеста

Имя файла манифеста оканчивается на «.manifest». Например, манифест сборки, который ссылается на сборку myassembly использует следующее правило именования myassembly.<resourceID>.manifest. ResourceID можно не указывать в том случае, когда resourceID равен 1 или манифест размещается в качестве отдельного файла.

Примечание.
Существуют ограничения именования манифестов, если сборка представляет собой Dll. В этом случае разместите манифест сборки в качестве ресурса Dll. Идентификатор ресурса должен быть равен 1 и название ресурса соответствует имени Dll. Например, если имя dll будет «Microsoft.Windows.mysample.dll», то значение атрибута элемента <assemblyIdentity> должно быть «Microsoft.Windows.mysample».
Другим способом является представление манифеста сборки в качестве отдельного файла. В этом случае имена сборки и ее манифеста должны отличаться. Например, Microsoft.Windows.mysampleAsm, Microsoft.Windows.mysampleAsm.manifest и Microsoft.Windows.Mysample.dll.


Элементы манифеста сборки

Имена элементов и их атрибутов, как и в любом XML-файле, регистрозависимы, исключая значения атрибутов.

Элемент <assembly> Является корневым элементом XML-документа. Обязательными первыми дочерними элементами должны быть <noInherit> или <assemblyIdentity>.

Атрибут xmlns задает пространство имен "urn:schemas-microsoft-com:asm.v1". Остальные элементы сборки также должны быть в указанном пространстве имен. Принадлежность пространству имен определяется путем наследования или прямым указанием в имени тега.

Атрибут manifsetVersion должен быть установлен в «1.0»


Элемент <noInherit /> Необязателен. Выступает в роли флага запрета наследования контекста подключения (activation context). Наличие noInherit в манифесте приложения не влияет на текущий манифест.


Элемент <assemblyIdentity />. Описывает и идентифицирует SxS сборки.

1) Является первым по порядку дочерним элементом <assembly>. Элемент <assemblyIdentity> описывает и однозначно идентифицирует сборку, работающую с текущим манифестом. Это так называемый DEF-контекст манифеста сборки.
2) Является первым по порядку дочерним элементом <dependentAssembly>. Элемент <assemblyIdentity> описывает связанные сборки (side-by-side assembly), используемые в DEF-контексте элемента <assemblyIdentity>, — это REF-контекст элемента <assemblyIdentity> манифеста сборки. Для корректной работы манифеста должны быть указаны и DEF, и REF -контексты.

Атрибут type (определяет тип сборки) должен быть установлен в «win32».

Атрибут name задает имя сборки. Microsoft советует применять следующее форматирование для именования: Organization.Division.Name. Например, Microsoft.Windows.mysampleApp. Примечание: в случае размещения манифеста сборки в отдельном файле и сборке Dll. следует помнить, что имена фалов сборки и манифеста должны отличаться.

Атрибут language указывает язык сборки. Необязателен. Если сборка являются языкозависимой, задаёт DHTML-код языка. В DEF-контексте для установки языка по умолчанию, Вы можете пропустить этот атрибут. Что касается REF-контекста, то укажите «*».

Атрибут processorArchitecture определяет процессор. Значение «x86» используется для 32-битных приложений, «ia64» — для 64-битных.

Атрибут version определяет версию сборки. Обязателен. Форматирование значения подобно написанию IP (делится на четыре части тремя точками). Каждая часть — это число в диапазоне 0-65535.

Атрибут publicKeyToken требуется только для описания общих (shared) сборок. Представляет собой 16-символьное значение-идентификатор, зарегистрированной сборки в системе.


Элемент <dependency> содержит как минимум один элемент <dependentAssembly>. Не имеет атрибутов. Необязателен.


Элемент <dependentAssembly>. Не имеет атрибутов. Первым дочерним элементом <dependentAssembly> является элемент <assemblyIdentity>, который описывает связанные (Side-by-Side) сборки. Содержится в одном экземпляре в элементе <dependency>. Не имеет атрибутов.
<file>


Элемент <file>. Определяет подключаемый файл. Необязателен. Включает элементы <comClass>, <typelib>, <windowClass>, <comInterfaceProxyStub>.

Атрибут Name. Имя файла, например Conctl32.dll.

Атрибут hashlang задает название алгоритма хеша файла. Значение равно «SHA1».

Атрибут hash представляет собой хеш файла.


Элемент <comClass>. Дочерний элемент <file>. Необязателен.

Атрибут description задает имя класса.

Атрибут clsid описывает GUID, который однозначно идентифицирует класс.

Атрибут threadingModel задает тип потоковой модели в COM. Необязателен. Доступные значения "Apartment", "Free", "Both", and "Neutral".

Атрибут tlbid представляет собой GUID библиотеки типов описываемого COM компонента. Необязателен.

Атрибут progid.

Также доступны атрибуты miscStatus, miscStatusIcon, miscStatusContent, miscStatusDocprint, miscStatusThumbnail. Их подробное описание доступно в справке.


Возможно наличие элементов <progid> внутри <comClass>. Таким образом можно организовать список зависимых progid от версии.


Пример использования элемента <file>:

<file name="sampleu.dll">
  <comClass description="Font Property Page"
    clsid="{0BE35200-8F91-11CE-9DE3-00AA004BB851}"
    threadingModel = "Both" 
    tlbid = "{44EC0535-400F-11D0-9DCD-00A0C90391D3}"/>
  <comClass description="Color Property Page"
    clsid="{0BE35201-8F91-11CE-9DE3-00AA004BB851}" 
    progid="ABC.Registrar"/>
 </file>

Элемент <typelib>. Дочерний элемент <file>. Необязателен.

Атрибут tlbid указывает идентификатор типизированной библиотеки. Обязателен.

Сегодня постараюсь завершить перевод этой статьи, а также добавить пример манифеста сборки.

45

Re: WSH: Использование COM-сервера без его регистрации в системе

Что-то эта тема маленько запылилась . Нужно бы слить в Коллекцию из неё всё, что можно, и открепить.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

46

Re: WSH: Использование COM-сервера без его регистрации в системе

Подождём, коллега JSman, думаю, рано или поздно закончит. А когда тема висит на первой странице, это очень настойчиво напоминает — сужу по собственному опыту .

47

Re: WSH: Использование COM-сервера без его регистрации в системе

Еще немного терпения и все будет готово ;-)

48

Re: WSH: Использование COM-сервера без его регистрации в системе

Открепляю, т.к. тема не развивается.
Вообще, в этой теме и сейчас есть, что перенести в Коллекцию. Работающий пример в посте #6, даже без подробных пояснений — гораздо лучше, чем ничего, и частичный перевод документации тоже очень полезен.

Предложения в русском языке начинаются с большой буквы и заканчиваются точкой.
В названии ветки всегда должен быть указан язык программирования или среда исполнения скрипта, если это возможно.

49

Re: WSH: Использование COM-сервера без его регистрации в системе

Надо бы постучать коллеге JSman'у в личку, дабы он свёл в Коллекцию уже то, что есть.

50 (изменено: Flasher, 2012-02-14 06:13:39)

Re: WSH: Использование COM-сервера без его регистрации в системе

Приветствую всех!
Вопрос портабельности стоит остро, использовать разные костыли (вызов консольных утилит через Run/Exec) в скриптах уже поднадоело, компоненты предпочтительней.
Я старался внимательно изучить вопрос по информации отсюда и ещё пары сайтов (1, 2), но пока как следует отфильтровать имеющееся получается не очень. Попытки запустить скрипт после написания манифеста заканчиваются сообщениями "Невозможно создание объекта контейнером ActiveX".
Просьба отозваться тех, кто разобрался в теме как следует и на практике умеет создавать рабочий манифест для любого ActiveX-компонента.

Что именно требуется (при наличии некой dll/ocx):
1. Алгоритм получения информации по атрибутам в связке с необходимыми для этого утилитами (regsvr42, RegDllView, oleview, TLViewer и т.п.), определения их необходимости в конкретном случае. (В описаниях выше статус (не)обязательности некоторых атрибутов несколько сомнителен).
2. Алгоритм правки/редактирования манифеста, полученного с пом. regsvr42.

Предложение: было бы здорово собрать коллекцию манифестов для представленных на сайте (и не только) компонентов. Если сам научусь, то готов посодействовать.