|
Компонент для модификации ресурса Version (информация о версии DLL или EXE)
Введение
|
      
При распространении дистрибутивов ваших проектов может возникнуть необходимость обновлять
информацию о версии dll и exe-модулей. Однако, ручное изменение информации о версии возможно
только посредством среды разработки (например, Visual Studio) или специализированных программ
изменения ресурсов (например, exeScope), если вы меняете информацию о версии библиотек, не имея
возможности скомпилировать модуль. Для автоматизированного выпуска сборок вашего продукта
может потребоваться программный способ изменения информации о версии.
     
Реализация данной задачи стала мне более интересной после того, как я не обнаружил функций
противоположных по смыслу GetFileVersionInfo (например, SetFileVersionInfo) и
VerQueryValue в Win32 API. Модификация ресурса с версией (VS_VERSION_INFO) оказалась невозможной
средствами Win32 API. Для устранения этого пробела мной был разработан класс-обертка,
который эмулирует структуру ресурса с информацией о версии и позволяет модифицировать поля
этой структуры. Далее приводится пример использования класса-обертки class VersionInfo:
#include "vinfo.h"
using namespace vi;
class YourOwnErrorHandler
{
public:
void error(LPCTSTR lpszErrorText) {
throw lpszErrorText;
}
};
void main(int argc, char* argv[])
{
VersionInfo<VIParserSimple, YourOwnErrorHandler> vi;
try {
if(!vi.load(argv[1])) return -1;
// change file version info
vi[VIH_FILEVERSION] = _L("1, 2, 3, 4");
// change product name
vi[VI_PRODUCTNAME] = _L("Your cool program name");
VIItem &item = vi[_L("OriginalFilename")];
if(item == VIItem::dummy);
// the item was not found
vi.update();
}
catch(LPCTSTR lpszError)
{
printf("error: %s", lpszError);
}
}
     Целью разработки этого класса-обертки являлась максимальная
простота использования с точки зрения программиста C++, вы работает с информацией о версии
как с ассоциативным массивом, некоторые значения которого целочисленные, некоторые строковые (unicode).
Однако, информация о версии настолько насыщена различными тонкими моментами, что в дальнейшем
последуют обновления данного класса.
     С академической точки зрения, в данном классе успешно реализована
идиома стратегий (Alexandrescu, 2002), а также примеры определения оператора =, оператора преобразования
типов, примеры использования STL.
|
Специальный случай
|
     
Однако, с изменением информации о версии в некоторых случаях возникают забавные ситуации, которые
не позволяют использовать также и стандартного механизма изменения ресурсов в приложении. Так, например,
разработчики PowerBuilder (видимо PowerSoft, купленная в последствии Sybase) приняли решение хранить
в ресурсе о версии, какую-то дополнительную информацию. Если попытаться применить по назначению
вышеописанный класс для исполняемого .exe-модуля, сформированного самой средой или при помощи PBORCA (API для
регенрации и компоновки библиотек), то размер этого модуля уменьшится почти в двое.
     
Для разрешения этой проблемы был разработан класс-наследник VersionInfoBinary<...>, интерфейс
которого унаследован от VersionInfo<...>, а реализация отличается тем, что не используютcя
механизмы Win32 API для обновления ресурсов, а модифицируется ресурс непосредственно в .exe-модуле
(непосредственная модификация файла). Данный подход отлично работает в описанном случае, однако,
имеет некоторое ограничение - размер файла зачастую нельзя увеличить (за счет информации о версии).
Разработчики PowerBuilder как-будто специально подготовили почву для изменения информации о
версии - все дело в том, что поле Copyright содержит довольно длинную и никчемную строку, местом
из-под которой вы и можете воспользоваться (Copyright сделать поменьше, а остальные поля - побольше).
|
Класс-обертка доступен для скачивания на странице Download
|
Компонент модификации инфомрации о версии
|
     
Для использования в инфраструктурных бизнес-процессах (например, выпуск сборок, использования
инсталляторов) я разработал COM-обертку для модификации информации о версии как посредством
Win32 API, так и при помощи непосредственной модификации исполняемого файла (см. предыдущий раздел).
Пользоваться компонентом очень просто: вы загружаете информацию о версии (load), а затем
модифицируете поля этой структуры, после чего изменения автоматически применяются.
|
Описание интерфейса
|
| load([in] BSTR name) - загружает информацию о версии. |
| getProperty([in] BSTR name, [out, retval] BSTR *pVal) - возвращает значение поля структуры ресурса версии по имени поля. |
| setProperty([in] BSTR name, [in] BSTR val) - установка значения поля структуры ресурса версии по имени поля. |
| Mode - свойство, переключающее режим обновления информации о версии: 0 (умолч.) - посредством Win32 API (VersionInfo), 1 - посредством непосредственной модификации файла (VersionInfoBinary). |
| FileVersion - свойство, соответствующее полю структуры. |
| ProductVersion - свойство, соответствующее полю структуры. |
| Description - свойство, соответствующее полю структуры. |
| Copyright - свойство, соответствующее полю структуры. |
| CompanyName - свойство, соответствующее полю структуры. |
| InternalName - свойство, соответствующее полю структуры. |
| ProductName - свойство, соответствующее полю структуры. |
| Comments - свойство, соответствующее полю структуры. |
| LegalTrademarks - свойство, соответствующее полю структуры. |
| OriginalFilename - свойство, соответствующее полю структуры. |
| SpecialBuild - свойство, соответствующее полю структуры. |
|
Идентификация
|
ProgID | IPM.VersionInfo |
Потоковая модель | Apartment |
CLSID | {6869846A-588B-40BB-97CB-0048DB57BED7} |
Версия | 1 |
|
|
Компонент доступен для скачивания на странице Download
|
|
|
|