Целостность multi-DLL проекта
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
-
- ✯ Ветеран ✯
- Сообщения: 4994
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 7 раз
- Поблагодарили: 21 раз
Целостность multi-DLL проекта
Дата изменения - это дата последней записи в файл. Она не меняется при копировании и т.д. В GetFileDate это значение вытаскивается по умолчанию (при отсутствии второго параметра). Думаю и в Directory она же.
We are hard at work… for you.
- Дед Пахом
- Старичок
- Сообщения: 3136
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 11 раз
- Поблагодарили: 31 раз
- Контактная информация:
Целостность multi-DLL проекта
Если загружать dll с FTP, то дата изменения (вроде бы) меняется на текущую.
С уважением, ДП
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
Есть много нюансов с архиваторами, программами резервного копирования и т.д.
И вообще это совсем не правильно определять версию DLL по внешней дате файла.
За теми кто отстал - не возвращаться. (С) Кодекс
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
Достаточно трудно в использовании.
1. Нужно после сборки проекта записывать хеш всех DLL файлов проекта в какой-то лог.
Не очень большая - но всё-таки дополнительная операция.
2. А вот загружать в память все DLL считать их хеш при каждом запуске программы - уже медленно.
Правильный путь через WinAPI - надо разбираться с GetFileVersionInfoA().
1. Нужно после сборки проекта записывать хеш всех DLL файлов проекта в какой-то лог.
Не очень большая - но всё-таки дополнительная операция.
2. А вот загружать в память все DLL считать их хеш при каждом запуске программы - уже медленно.
Правильный путь через WinAPI - надо разбираться с GetFileVersionInfoA().
За теми кто отстал - не возвращаться. (С) Кодекс
-
- ✯ Ветеран ✯
- Сообщения: 4994
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 7 раз
- Поблагодарили: 21 раз
Целостность multi-DLL проекта
Передавайте архивом.
Вообще загнаться можно. И Api будет врать.
We are hard at work… for you.
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
Ещё раз спасибо, всё сделал по науке. И это была интересная охота !
Когда уже разобрался в вопросе, то понял что элементарную базовую проверку
можно сделать и штатными средствами Clarion (и это решило бы мой вопрос):
Код: Выделить всё
If System{Prop:ExeVersion,3} <> System{Prop:LibVersion,3} then Message('Houston, we have a problem !').
За теми кто отстал - не возвращаться. (С) Кодекс
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
Пример контроля версий DLL Clarion (и не только).
1. Добавляем где-нибудь в Global Map и линкуем к проекту Version.lib (прикреплён, см. ниже):
2. Пример проверки версии DLL используемой в Вашем проекте (где-нибудь при запуске EXE):
3. И собственно сама процедура проверки (кто найдёт ошибку - тому спасибо !):
1. Добавляем где-нибудь в Global Map и линкуем к проекту Version.lib (прикреплён, см. ниже):
Код: Выделить всё
Module('Windows')
Glo:memcpy(Long lpDest,Long lpSource,Long nCount),Long,Proc,Name('_memcpy')
end
Module('Version.dll')
WinGetFileVersionInfoSizeA(*CSTRING lptstrFilename, *ULong lpdwHandle),ULONG,PASCAL,RAW,Name('GetFileVersionInfoSizeA')
WinGetFileVersionInfoA( *CSTRING lptstrFilename, Long dwHandle, Long dwLen, *String lpData),BOOL,PASCAL,RAW,Name('GetFileVersionInfoA')
WinVerQueryValueA(*String pBlock, *CSTRING lpSubBlock, *ULong lplpBuffer, *ULong puLen),BOOL,PASCAL,RAW,Name('VerQueryValueA')
end
Код: Выделить всё
ExeVersion# = System{Prop:ExeVersion,3} ! Версия сборки EXE модуля
If CheckVerDll(ExeVersion#, 'CLAASC.DLL') Or |
CheckVerDll(ExeVersion#, 'CLATPS.DLL') Or |
CheckVerDll(ExeVersion#, 'CLADOS.DLL') then Return.
Код: Выделить всё
CheckVerDll PROCEDURE (Long xVersion_, String xDllName_, Byte xMess_ = 0)
Loc:RetValue BYTE(False)
Loc:SubBlock CSTRING('\')
Loc:puLen ULONG(0)
Loc:Buffer ULONG
Loc:verHandle ULONG(0)
Loc:verSize ULONG
Loc:verData &STRING
Loc:verFile CSTRING(256)
Loc:verInfo Group
dwSignature Long
dwStrucVersion Long
dwFileVersionMS Long
dwFileVersionLS Long
dwProductVersionMS Long
dwProductVersionLS Long
dwFileFlagsMask Long
dwFileFlags Long
dwFileOS Long
dwFileType Long
dwFileSubtype Long
dwFileDateMS Long
dwFileDateLS Long
end
Code
Loc:verFile = Command('0') ! Получить папку EXE модуля (может отличаться от текущей папки работы)
Loc:verFile = LongPath(xExtractFileName(Loc:verFile,1) & xExtractFileName(Loc:verFile,2) & xDllName_)
Loc:verSize = WinGetFileVersionInfoSizeA(Loc:verFile, Loc:verHandle)
If Loc:verSize > 0
Loc:verData &= New(String(Loc:verSize)) ! Создаем буфер для загрузки
If ~(Loc:verData &= NULL) ! Если буфер удачно создан
If WinGetFileVersionInfoA(Loc:verFile,0,Loc:verSize,Loc:verData) <> 0 ! Получить данные о версии
If WinVerQueryValueA(Loc:verData,Loc:SubBlock,Loc:Buffer,Loc:puLen) <> 0 ! Получить адрес структуры версии
If Loc:puLen = 52
Glo:memcpy(address(Loc:verInfo), Loc:Buffer, Loc:puLen) ! Копируем кусок памяти в Loc:verInfo
If (Loc:verInfo.dwSignature = 0FEEF04BDh) and | ! Проверка сигнатуры структуры версии
(Sub(LongToHex(Loc:verInfo.dwFileVersionLS,False),5,4) <> Sub(LongToHex(xVersion_,False),5,4))
Message('Нарушена целостность библиотек программы !|' & |
'Различные версии сборки EXE и DLL файлов программы.||' & |
LongPath(Command('0')) & '|Версия: 0x' & Sub(LongToHex(xVersion_,False),5,4) & ' ( ' & |
Clip(Left(xVersion_)) & ' )||' & |
Loc:verFile & '|Версия: 0x' & Sub(LongToHex(Loc:verInfo.dwFileVersionLS,False),5,4) & ' ( ' & |
Evaluate('0' & Sub(LongToHex(Loc:verInfo.dwFileVersionLS,False),5,4) & 'h') & ' )||' & |
'Выполните пожалуйста переустановку программы.', 'У нас проблема',Icon:Exclamation,'&1. Закрыть')
Loc:RetValue = True ! Не совпадение версий DLL и EXE
end
! Просмотр содержимого Loc:verInfo при отладке
!Message(Loc:verFile & '||' & |
! 'Signature = ' & LongToHex(Loc:verInfo.dwSignature , False) & '|' & |
! 'StrucVersion = ' & LongToHex(Loc:verInfo.dwStrucVersion , False) & '|' & |
! 'FileVersionMS = ' & LongToHex(Loc:verInfo.dwFileVersionMS , False) & '|' & |
! 'FileVersionLS = ' & LongToHex(Loc:verInfo.dwFileVersionLS , False) & '|' & |
! 'ProductVersionMS = ' & LongToHex(Loc:verInfo.dwProductVersionMS, False) & '|' & |
! 'ProductVersionLS = ' & LongToHex(Loc:verInfo.dwProductVersionLS, False) & '|' & |
! 'FileFlagsMask = ' & LongToHex(Loc:verInfo.dwFileFlagsMask , False) & '|' & |
! 'FileFlags = ' & LongToHex(Loc:verInfo.dwFileFlags , False) & '|' & |
! 'FileOS = ' & LongToHex(Loc:verInfo.dwFileOS , False) & '|' & |
! 'FileType = ' & LongToHex(Loc:verInfo.dwFileType , False) & '|' & |
! 'FileSubtype = ' & LongToHex(Loc:verInfo.dwFileSubtype , False) & '|' & |
! 'FileDateMS = ' & LongToHex(Loc:verInfo.dwFileDateMS , False) & '|' & |
! 'FileDateLS = ' & LongToHex(Loc:verInfo.dwFileDateLS , False))
end ! If Loc:puLen = 52
end ! If WinVerQueryValueA(
elsIf xMess_ then Message('Ошибка WinGetFileVersionInfo !','У нас проблема',Icon:Exclamation,'&1. Закрыть')
end ! If WinGetFileVersionInfoA(
Dispose(Loc:verData)
end ! If ~(Loc:verData &= NULL)
elsIf xMess_ then Message('Ошибка GetFileVersionInfoSize !','У нас проблема',Icon:Exclamation,'&1. Закрыть')
end ! If Loc:verSize > 0
Return Loc:RetValue
- Вложения
-
- vers_lib.zip
- Файл Version.Lib
- (234 байт) 114 скачиваний
За теми кто отстал - не возвращаться. (С) Кодекс
-
- ✯ Ветеран ✯
- Сообщения: 1703
- Зарегистрирован: 25 Март 2009, 21:55
- Благодарил (а): 9 раз
- Поблагодарили: 4 раза
Целостность multi-DLL проекта
Огромное спасибо за Ваш код.
Надеюсь у админа найдется возможность докинуть в FAQ
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
В разделе FAQ - ответы на базовые вопросы, а это что-то вроде игры в напёрстки с WinAPI ...
Хотя, конечно, вызывает недоумение, почему SV считает, что работа приложения с разными версиями DLL - это нормально.
На мой субъективный взгляд, Run-Time должен проверять прилинковые DLL при запуске приложения и рубить запуск при
обнаружении "солянки сборной мясной" ... Что в общем-то и делает обсуждаемый пример ...
За теми кто отстал - не возвращаться. (С) Кодекс
-
- ✯ Ветеран ✯
- Сообщения: 4994
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 7 раз
- Поблагодарили: 21 раз
Целостность multi-DLL проекта
Я помню времена, когда как раз dll разных сборок работали, а одной нет. Если у SV было бы всё чётко, то да. А так косячат не по-детски. Другое дело свои dll. А есть ещё сторонние dll. Совершенно не базовый вопрос, ИМХО.
We are hard at work… for you.
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
Я часто читаю на ClarionHUB советы вернуть какую-то DLL из прошлого релиза или наоборот, подсунуть из нового.
Есть просто знатные купажисты, работающие методом тыка ... но проблема в том, что Clarion - это не OpenSource.
Фиг его знает, что изменено в версиях на самом деле и где это вылезет. Я против таких слепых замесов.
Возможные результаты - см. в первом сообщении этой темы.
За теми кто отстал - не возвращаться. (С) Кодекс
- Игорь Столяров
- Ветеран движения
- Сообщения: 7390
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 15 раз
- Поблагодарили: 49 раз
Целостность multi-DLL проекта
Если эта тема кому-нибудь интересна, то здесь можно усугубить.
Вот такая функция позволяет построить список используемых компонентов проекта, как в серьёзный программах.
P/S: По прежнему готов выпить пива за здоровье того, кто видит в этом коде ошибку.
Вот такая функция позволяет построить список используемых компонентов проекта, как в серьёзный программах.
Код: Выделить всё
GetVerDll PROCEDURE (String xDllName_,Byte xMess_ = 0) ! ,Byte
Loc:RetValue BYTE(False)
Loc:SubBlock CSTRING(256)
Loc:puLen ULONG(0)
Loc:Buffer ULONG
Loc:verHandle ULONG(0)
Loc:verSize ULONG
Loc:verData &STRING
Loc:verFile CSTRING(256)
Loc:LTmp ULONG
Loc:LangCharset STRING(8)
Loc:verInfo CSTRING(256),DIM(2,8)
Loc:Count BYTE
Code
Loc:verFile = Command('0')
Loc:verFile = LongPath(xExtractFileName(Loc:verFile,1) & xExtractFileName(Loc:verFile,2) & xDllName_)
Loc:verSize = WinGetFileVersionInfoSizeA(Loc:verFile, Loc:verHandle)
If Loc:verSize > 0
Loc:verData &= New(String(Loc:verSize)) ! Создаем буфер для загрузки
If ~(Loc:verData &= NULL) ! Если буфер удачно создан
If WinGetFileVersionInfoA(Loc:verFile,0,Loc:verSize,Loc:verData) <> 0 ! Получить данные о версии
Loc:SubBlock = '\VarFileInfo\Translation'
If WinVerQueryValueA(Loc:verData,Loc:SubBlock,Loc:Buffer,Loc:puLen) <> 0 ! Получить структуру версии
If Loc:puLen = 4 ! Размер буфера 4 byte
Glo:memcpy(address(Loc:LTmp), Loc:Buffer, Loc:puLen)
Loc:LangCharset = LongToHex(Loc:LTmp,False)
Loc:LangCharset = Loc:LangCharset[5:8] & Loc:LangCharset[1:4]
Loop Loc:Count = 1 to 8 by 1
Loc:verInfo[1,(Loc:Count)] = Choose(Loc:Count,'CompanyName', |
'FileDescription', |
'FileVersion', |
'InternalName', |
'LegalCopyright', |
'OriginalFileName', |
'ProductName', |
'ProductVersion')
Loc:SubBlock = '\StringFileInfo\' & Loc:LangCharset & '\' & Loc:verInfo[1,(Loc:Count)]
If WinVerQueryValueA(Loc:verData,Loc:SubBlock,Loc:Buffer,Loc:puLen) <> 0
If Loc:puLen <= Size(Loc:verInfo[2,(Loc:Count)])
Glo:memcpy(address(Loc:verInfo[2,(Loc:Count)]), Loc:Buffer, Loc:puLen)
else
Loc:verInfo[2,(Loc:Count)] = 'Превышение размера: ' & Clip(Left(Loc:puLen))
end
end ! If WinVerQueryValueA(
end ! Loop Loc:Count = 1 to 8 by 1
Message(Loc:verFile & '||' & |
Loc:verInfo[1,1] & ' = ' & Loc:verInfo[2,1] & '|' & |
Loc:verInfo[1,2] & ' = ' & Loc:verInfo[2,2] & '|' & |
Loc:verInfo[1,3] & ' = ' & Loc:verInfo[2,3] & '|' & |
Loc:verInfo[1,4] & ' = ' & Loc:verInfo[2,4] & '|' & |
Loc:verInfo[1,5] & ' = ' & Loc:verInfo[2,5] & '|' & |
Loc:verInfo[1,6] & ' = ' & Loc:verInfo[2,6] & '|' & |
Loc:verInfo[1,7] & ' = ' & Loc:verInfo[2,7] & '|' & |
Loc:verInfo[1,8] & ' = ' & Loc:verInfo[2,8])
end ! If Loc:puLen = 4
end ! If WinVerQueryValueA(
elsIf xMess_ then Message('Ошибка WinGetFileVersionInfo !','У нас проблема',Icon:Exclamation,'&1. Закрыть')
end ! If WinGetFileVersionInfoA(
Dispose(Loc:verData)
end ! If ~(Loc:verData &= NULL)
elsIf xMess_ then Message('Ошибка GetFileVersionInfoSize !','У нас проблема',Icon:Exclamation,'&1. Закрыть')
end ! If Loc:verSize > 0
Return Loc:RetValue ! Потом вернём успешность выполнения
P/S: По прежнему готов выпить пива за здоровье того, кто видит в этом коде ошибку.
За теми кто отстал - не возвращаться. (С) Кодекс