Gal |
Отправлено: 04.06.2004, 10:22 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 124
|
Как узнать программно версию exe -файла |
|
olegenty |
Отправлено: 04.06.2004, 10:31 |
|
Ветеран
Группа: Модератор
Сообщений: 2412
|
если пользуешься RxLib, то так:
CODE |
#include "RxVerInf.hpp"
...
TVersionInfo *p = NULL;
try
{
try
{
TVersionInfo *p = new TVersionInfo(Application->ExeName);
if (p->Valid)
{
laFileVersion->Caption = p->FileVersion;
} else
{
laFileVersion->Visible = false;
laFileVersionCaption->Visible = false;
}
}
catch(const Exception &E)
{
ShowMessage(E.Message.Trim());
}
} __finally
{
if (p) delete p;
}
|
|
|
Gedeon |
Отправлено: 04.06.2004, 10:41 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Вот готовая функция
CODE |
bool GetAppVersion(char* FileName, int* VerInfo){ // получение версии файла
if(!IsFile(FileName)){ // Проверяем наличие файла
return false; // Если нет ф-ция неуспешна
}
DWORD FSize = GetFileVersionInfoSize(FileName,NULL); // размер инфы о версии файла
if(FSize==0){ // Если 0 функция неуспешна
return false;
}
LPVOID pBlock = (char*)malloc(FSize); // адрес буфера для ресурсов версии
GetFileVersionInfo(FileName,NULL,FSize,pBlock); // получаем ресурс информации о версии
LPVOID MS;
UINT LS;
try{
VerQueryValue(pBlock,"\\",&MS,&LS); // извлекаем информацию из ресурса
}
catch(...){
return false; // в случае ошибки функция неуспешна
}
VS_FIXEDFILEINFO FixedFileInfo; // структура с информацией о версии файла
memmove(&FixedFileInfo, MS, LS); // приводим информацию к структуре
DWORD FileVersionMS = FixedFileInfo.dwFileVersionMS;
DWORD FileVersionLS = FixedFileInfo.dwFileVersionLS;
VerInfo[0] = HIWORD(FileVersionMS); // получаем значения
VerInfo[1] = LOWORD(FileVersionMS); // и присваиваеи их входному указателю
VerInfo[2] = HIWORD(FileVersionLS);
VerInfo[3] = LOWORD(FileVersionLS);
return true; // функция успешна
}
|
Заставили меня его прокоментировать для идиотов, а вот пригодилось.
Вот так пользоваться
CODE |
int ApplicationVersion[4] = {0,0,0,0}; // массив с информацией о версии
if(GetAppVersion(Application->ExeName.c_str(), ApplicationVersion)){ // занести в него информацию
AppMajor = ApplicationVersion[0]; // версия обновляемого приложения
AppMinor = ApplicationVersion[1];
AppRelease = ApplicationVersion[2];
AppBuild = ApplicationVersion[3];
}
|
И уже вопрос в догонку от меня: если в эту функцию имя приложения засунуть в таком виде, как я привел в примере, то че то происходит со значением указателя и он после выполнения функции(успешного и правильного) с последней буквой F в конце и без трех своих. Лечил созданием нового указателя и копированием в него значения Application->ExeName.c_str(), но не понятно че за ботва?
Отредактировано Gedeon — 04/06/2004, 11:45
|
|
xTrim |
Отправлено: 04.06.2004, 10:56 |
|
Машинист паровоза
Группа: Участник
Сообщений: 208
|
у меня похожая есть
CODE |
//---------------------------------------------------------------------------
template <class T>
class GlobalMem
{
public:
GlobalMem(DWORD s):size(s){buf = (T) GlobalAlloc(GMEM_FIXED, size);}
~GlobalMem(){GlobalFree(buf);}
T operator()(){return buf;}
private:
T buf;
DWORD size;
};
//---------------------------------------------------------------------------
AnsiString GetAnyAppParam(AnsiString appname,AnsiString pname)
{
//pname = ProductName,FileVersion,LegalCopyright,CompanyName и т.д.
AnsiString ret("<Invalid parametr>");
DWORD h;
DWORD Size = GetFileVersionInfoSize(appname.c_str(), &h);
if (Size == 0) return ret;
GlobalMem<char*> buf(Size);
if (GetFileVersionInfo(appname.c_str(), h, Size, buf()) == 0) return ret;
char* ValueBuf;
UINT Len;
VerQueryValue(buf(), "\\VarFileInfo\\Translation", &(void *) ValueBuf, &Len);
if (Len < 4) return ret;
AnsiString CharSet = IntToHex((int)MAKELONG(*(int*) (ValueBuf + 2), *(int*) ValueBuf),8);
AnsiString fn = "\\StringFileInfo\\" + CharSet + "\\"+pname;
if (VerQueryValue(buf(),fn.c_str(),&(void *) ValueBuf, &Len) != 0)
ret = ValueBuf;
return ret;
}
//---------------------------------------------------------------------------
|
использовать
CODE |
Label1->Caption = GetAnyAppParam(Application->ExeName,"ProductName")+" "+GetAnyAppParam(Application->ExeName,"FileVersion");
Label2->Caption = GetAnyAppParam("C:\\Program Files\\Opera75\\opera.exe","ProductName")+" "+GetAnyAppParam("C:\\Program Files\\Opera75\\opera.exe","FileVersion");
|
вроде не глючит
|
|
Gedeon |
Отправлено: 04.06.2004, 11:43 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Да нет, сама функция у меня не глючит, вот с указателем что-то происходит, char* иногда преподносит сюрпризы. Вот подумалось надо было не мудрствуя лукаво обьявить его как const.
|
|
Treumer |
Отправлено: 22.06.2005, 09:31 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 92
|
QUOTE (olegenty @ 04/06/2004, 10:31) | если пользуешься RxLib, то так:
CODE |
#include "RxVerInf.hpp"
...
TVersionInfo *p = NULL;
try
{
try
{
TVersionInfo *p = new TVersionInfo(Application->ExeName);
if (p->Valid)
{
laFileVersion->Caption = p->FileVersion;
} else
{
laFileVersion->Visible = false;
laFileVersionCaption->Visible = false;
}
}
catch(const Exception &E)
{
ShowMessage(E.Message.Trim());
}
} __finally
{
if (p) delete p;
}
|
|
Странная получается ерунда: делаю как описано, а она все время на TVersionInfo как на "unresolved external" ругается! |
|
|