Позднее связывание с DLL файлом

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Позднее связывание с DLL файлом

Сообщение SSecurity » 09.07.2007 (Пн) 1:05

Всем привет,

Суть вопроса такова.
Есть софтвара, установленная в определенный каталог, например D:\Software\Test в этом каталоге есть подкаталог D:\Software\Test\DLLs, в который требуется положить DLL-ки.

Задача:
Подгружать список DLLок загруженных в этом каталоге, и в зависимости от содержания самих DLL менять функциональные возможности ПО.

Собственно изменение функционала у меня уже реализовано, для упрощения я просто называл DLL в формате [ИмяСервера].dll
В каждой DLL был класс Info в который я помещал необходимую мне информацию (автор, версия, список классов длл, версия и т.д.) после чего методом позднего связывания подключал точто нужно к проекту.

Но меня теребит вопрос, - можно ли обратившись по имени файла, определить версию, набор классов в длл-ке? (как без предварительной регистрирации компонента в системе, так и после оной).

Буду благодарен ссылке, коду и просто совету:)

Заранее спасибо за ответ.

С Уважением,
Сергей
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Позднее связывание с DLL файлом

Сообщение Хакер » 09.07.2007 (Пн) 4:40

SSecurity писал(а):Но меня теребит вопрос, - можно ли обратившись по имени файла, определить версию, набор классов в длл-ке? (как без предварительной регистрирации компонента в системе, так и после оной).


Для этого, а также для того, чтобы узнать "список методов" классов, необходима TLB. Если нет TLB - узнать при всём желании не получится, не смотря на то, что вызвать какой-то метод будет можно. При компиляции библиотеки TLB помещается в ресурсы оной. Если нет, то получить её можно у автора библы. В противном случае, ничего сделать нельзя.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 09.07.2007 (Пн) 8:46

На всякий случай: TLB открывается функцией LoadTypeLibEx, а пример для её дампа я выкладывал в топике от ANDLL.
Изображение

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 09.07.2007 (Пн) 10:24

Порочная архитектура. Для небольших проектов она громоздка, для больших вредна. Если ошибешься в какой-нибудь библиотеке в классе Info, рискуешь получить ошибку типа или объект не поддерживает свойство или метод. Если уж делаешь "кирпичное" приложение, то не поленись сделать еще одну dll с интерфейсом для Info. А вообще для любого "кирпичного" приложения достаточно двух-трех интерфейсов, которыми можно описать любой тип взаимодействий между любыми его частями.
Лучший способ понять что-то самому — объяснить это другому.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Сообщение SSecurity » 09.07.2007 (Пн) 10:42

Antonariy писал(а):Порочная архитектура. Для небольших проектов она громоздка, для больших вредна. Если ошибешься в какой-нибудь библиотеке в классе Info, рискуешь получить ошибку типа или объект не поддерживает свойство или метод. Если уж делаешь "кирпичное" приложение, то не поленись сделать еще одну dll с интерфейсом для Info. А вообще для любого "кирпичного" приложения достаточно двух-трех интерфейсов, которыми можно описать любой тип взаимодействий между любыми его частями.


INFO итак как интерфейс описан. До юзера доходит голый DLL файл.

"Кирпичность" здесь нужна для того, чтобы данном случае хранить бланки отчетов (точнее код вызова и форматирования до нужного вида Листов-Excel).

Может в этом случае лучше замутить свой редактор отчетов, как и подобает со своим синтаксисом, а отчеты хранить в отдельных файлах

С Уважением,
Сергей
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 09.07.2007 (Пн) 22:38

Может в этом случае лучше замутить свой редактор отчетов, как и подобает со своим синтаксисом, а отчеты хранить в отдельных файлах
Я пробовал. Замучался с расчетом координат элементов отчета и суботчетов при выводе на принтер. Перешел на HTML. Рекомендую заценить мой контрол HTML Form из проектов - он как раз использует html-шаблоны с расширенным синтаксисом для вывода рекордсетов в html. А точнее не синтаксисом, а дополнительными атрибутами. И не только вывода.
Лучший способ понять что-то самому — объяснить это другому.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Сообщение SSecurity » 10.07.2007 (Вт) 11:31

Antonariy писал(а):Я пробовал. Замучался с расчетом координат элементов отчета и суботчетов при выводе на принтер. Перешел на HTML. Рекомендую заценить мой контрол HTML Form из проектов - он как раз использует html-шаблоны с расширенным синтаксисом для вывода рекордсетов в html. А точнее не синтаксисом, а дополнительными атрибутами. И не только вывода.


Спасибо большое за предложение, но мне бы тут другой контрол - который данные в Excel и Word экспортирует.

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

Шаблонный метод он хороший - в том смысле, что взял в экселе например открыл, инфу внес и сохранил куда нить. Это удобно, но прийдется за собой файлики шаблонные таскать.

По поводу самого вопроса. Насколько я понимаю без ТЛБ это не возможно. Тогда перефразируем вопрос.

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

Щас все решается "
Код: Выделить всё
regsvr32 [имя длл файла] /s
вроде так, т.е. сначала регистрируем все что есть в текущей папке потом вызываем.

С Уважением,
Сергей
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 10.07.2007 (Вт) 13:15

Лучший способ понять что-то самому — объяснить это другому.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Сообщение SSecurity » 10.07.2007 (Вт) 14:00

Antonariy писал(а):Таки да.

бААААльшое спасибо скачал модулья для запуска незарегистрированных объектов.

БАльшущее спасибо:)


С Уважением,
Сергей
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 10.07.2007 (Вт) 14:02

Но меня теребит вопрос, - можно ли обратившись по имени файла, определить версию, набор классов в длл-ке? (как без предварительной регистрирации компонента в системе, так и после оной).


Да можно, через Reference подключи TLBINF32.dll, на форму положи кнопку и такой код. Путь измени к своей DLL

Код: Выделить всё
Option Explicit
Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
    (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
    ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32" (ByVal hKey As Long) As Long
Private Declare Function RegQueryValueExStr Lib "advapi32" Alias "RegQueryValueExA" _
    (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
    ByRef lpType As Long, ByVal szData As String, ByRef lpcbData As Long) As Long
Private Declare Function RegQueryValueExLong Lib "advapi32" Alias "RegQueryValueExA" _
    (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, _
    ByRef lpType As Long, szData As Long, ByRef lpcbData As Long) As Long
       

Public Function astcGetObject(ByVal Path As String, Optional ByVal ClassName As String) As Object
    'On Error Resume Next
    Dim c As TypeLibInfo
    Dim sGuid As String
    Dim fName As String
    'TLBINF32.dll
        Set c = TLI.TypeLibInfoFromFile(Path)

        If c.CoClasses.Count <= 0 Then
            Exit Function
        End If

        If ClassName = "" Then
            sGuid = c.CoClasses.Item(1).Guid
        Else
            sGuid = c.CoClasses.NamedItem(ClassName).Guid
        End If
        fName = GetClassString(sGuid)
         
        MsgBox GetClassString(c.CoClasses.Item(1).Guid)
        MsgBox GetClassString(c.CoClasses.Item(2).Guid)
        MsgBox GetClassString(c.CoClasses.Item(3).Guid)

    End Function


Private Function GetClassString(ByVal sGuid As String) As String
    Const HKEY_CLASSES_ROOT = &H80000000
    Dim lpSubKey As String
    Dim cData As Long, sData As String, ordType As Long, e As Long
    Dim hKey As Long
    lpSubKey = "CLSID\" & sGuid
    e = RegOpenKeyEx(HKEY_CLASSES_ROOT, lpSubKey, 0, 1, hKey)
    e = RegQueryValueExLong(hKey, "", 0&, ordType, 0&, cData)
    sData = String$(cData - 1, 0)
    e = RegQueryValueExStr(hKey, "", 0&, ordType, sData, cData)
    RegCloseKey (hKey)
    GetClassString = sData
End Function


Private Sub Command1_Click()
astcGetObject "C:\Documents and Settings\pashkov\Рабочий стол\VB6_TreeView_Full_Source\Release\vbalTreeView6.ocx"
End Sub

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Re: Позднее связывание с DLL файлом

Сообщение SSecurity » 05.03.2009 (Чт) 18:45

Спасибо, версию я всетаки определил ... методом от обратного:)
Взял желаемый класс ... нашел его в реестре (если он существует), определил его CLSID, по CLSID нашел DLL которая его содержит и уже по пути определил её версию:)

Путь конечно не из простых ... но вроде работает. Интересно а если я создам свой контрол в котором имя класса совпадет с существующим в реестре что сделает виндовс ... какой объект она определит как основной:)) :!: :?:
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Позднее связывание с DLL файлом

Сообщение Хакер » 05.03.2009 (Чт) 18:47

Что такое "имя класса"? progid что-ли?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Re: Позднее связывание с DLL файлом

Сообщение SSecurity » 07.03.2009 (Сб) 13:31

ProjectName.ClassName
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Позднее связывание с DLL файлом

Сообщение Хакер » 07.03.2009 (Сб) 13:49

Ага, progid.

Насколько я знаю, новые progid-ы затирают старые.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Re: Позднее связывание с DLL файлом

Сообщение SSecurity » 07.03.2009 (Сб) 15:10

Т.е. если создам ДЛЛ-ку или компонент с юзеровским интерфейсом или без оного ... ProgID которого соответсвует ранее имеющемуся (ADODB.Connection, например), то может получится так что при вызове будет стартовать мой компнент ... GUID и CLSID у них точно разные будут это понятно ...

но тогда, если мы в референсах ничего не пишем, а просто проверяем создастся ли ADODB.Connection
через CreateObject (в данном случае) или Controls.Add - в случае компонента, то как система определит что нужно создать компонент/дллку и какой будет выбор между ними .... мне почему-то кажется что с большей вероятностью АДОДБ объект останется:)
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Позднее связывание с DLL файлом

Сообщение Хакер » 07.03.2009 (Сб) 15:17

Ну вот я сейчас создал проект ADODB, в него добавил класс Connection. В классе создал метод:
Код: Выделить всё
Public Sub ShameOnAdo()
    MsgBox "ADO в пролёте"
End Sub


Скомпилировал dll-шку, зарегистрировал.

В другом проекте:
Код: Выделить всё
Private Sub Form_Load()
    Call CreateObject("ADODB.Connection").ShameOnAdo
End Sub


Вижу своё же сообщение "ADO в пролёте".
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Re: Позднее связывание с DLL файлом

Сообщение SSecurity » 07.03.2009 (Сб) 21:19

получаетсся что динамически можно совсем не к тому что нужно привязаться...
а как этого избежать?
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Позднее связывание с DLL файлом

Сообщение Хакер » 07.03.2009 (Сб) 21:40

(Ерунда какая-то) Что значит "динамически"? Знаешь способ создавать COM-компоненты статически?

а как этого избежать?

Ну никто же не заставляет тебя пользоваться для индентификации класса progid-ом. Пользуйся CLSID-ом, никогда не ошибёшься.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SSecurity
Служба безопасности
Аватара пользователя
 
Сообщения: 1283
Зарегистрирован: 19.08.2003 (Вт) 1:11
Откуда: Россия, Мурманск

Re: Позднее связывание с DLL файлом

Сообщение SSecurity » 07.03.2009 (Сб) 21:59

Хакер писал(а):(Ерунда какая-то) Что значит "динамически"? Знаешь способ создавать COM-компоненты статически?

а как этого избежать?

Ну никто же не заставляет тебя пользоваться для индентификации класса progid-ом. Пользуйся CLSID-ом, никогда не ошибёшься.

слово ДИНАМИЧЕСКИ относится к процессу создания объекта внутри самой программы а не всеобщего межпрограммного взаимодействия - т.е. позднее связывание с компонентами для которых известны только ProgID

Просто я постепенно прихожу к очень нехорошему выводу: - При обновлении ПО, например, я предлагаю юзеру установку версии 1.5 своего компонента, притом если у него версия 1.4.1 и выше, то программа будет оставаться работоспособной ... установка будет опциональной. Между тем,можно конечно составить список совместимых CLSID, которые ещё будут работать в случае отказа от обновления, но ведь может получится так, что у пользователя окажутся контролы либо новее либо старее, CLSID которого я не смогу по каким-то причинам внести в список установки.

Поэтому приходится тестить по Progid, а как тут быть?
Программист - это маленький Бог, а все его ошибки - это самостоятельные творения:)
Так задумано:)

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Позднее связывание с DLL файлом

Сообщение Хакер » 07.03.2009 (Сб) 22:20

слово ДИНАМИЧЕСКИ относится к процессу создания объекта внутри самой программы

Это в твоём посте так? В моём тоже так, вообще-то...
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот, Yandex-бот и гости: 25

    TopList