Strona 1 z 1

Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 15:47
przez simekone
Szukałem w internecie informacji na temat pobierania wersji napisanego programu (major, minor, release i build). Niestety znalazłem tylko informacje jak pobrać te informacje korzystając z VS. może ktoś z was kiedyś poradził sobie z tym problemem?

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 16:02
przez Cyfrowy Baron
Słabo szukasz. odpowiedź w serwisie Cyfrowy Baron w dziel: porady -> API -> Pobieranie informacji o wersji pliku.

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 16:12
przez simekone
Strasznie skomplikowana metoda i nie do końca o to mi chodziło, ponieważ zależy mi na pobieraniu numeru wersji napisanego przeze mnie programu, a nie dowolnego pliku EXE - liczyłem, że tak jak w VS jest do tego odpowiednia funkcja, która załatwia sprawę, a wersja pobierana jest np. podczas procesu uruchamiania mojej aplikacji i zapisywana do zmiennej, czy a nie ze skompilowanego pliku EXE.

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 16:15
przez Cyfrowy Baron
Chyba nie przeczytałeś tej porady, przecież tam jest to podane:

Kod: Zaznacz cały
#include <stdio.h>
//--------------------------------
String GetFileVersionInfo(char *ModulePath, String KeyName)
{
LPVOID lpStr1 = NULL, lpStr2 = NULL;
WORD* wTmp;
DWORD dwHandlev = NULL;
UINT dwLength;
char sFileName[1024] = {0};
char sTmp[1024] = {0};
String sInfo;
LPVOID* pVersionInfo;

if(ModulePath == NULL) GetModuleFileName(NULL, sFileName, 1024);
else strcpy(sFileName, ModulePath);

DWORD dwInfoSize = GetFileVersionInfoSize((char*)(LPCTSTR)sFileName, &dwHandlev);
if(dwInfoSize)
{
  pVersionInfo = new LPVOID[dwInfoSize];
  if(GetFileVersionInfo((char*)(LPCTSTR)sFileName, dwHandlev, dwInfoSize, pVersionInfo))
  {
   if(VerQueryValue(pVersionInfo, "\\VarFileInfo\\Translation", &lpStr1, &dwLength))
   {
    wTmp = (WORD*)lpStr1;
    sprintf(sTmp, ("\\StringFileInfo\\%04x%04x\\" + KeyName).c_str(), *wTmp, *(wTmp + 1));
    if(VerQueryValue(pVersionInfo, sTmp, &lpStr2, &dwLength)) sInfo = (LPSTR)lpStr2;
   }
  }
  delete[] pVersionInfo;
}
return sInfo;
}
//--------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Label2->Caption = "Wersja pliku: " + GetFileVersionInfo(NULL, "FileVersion"); // pobranie wersji programu z którego funkcja jest uruchamiana
}
//--------------------------------


Co w tym skomplikowanego, przecież masz gotowy kod, na co właściwie liczysz?

Podana funkcja odczytuje wersję pliku aplikacji.

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 16:21
przez simekone
Spraw przedstawia się następująco - jest to program na zaliczenie laborek, będę musiał dopowiedzieć na pytania zawiązane z użytymi funkcjami, operacjami, klasami itd., a kod podany przez Ciebie w tej poradzie nie jest do końca dla mnie zrozumiały, także wolałbym z niego nie korzystać, aby uniknąć problemów przy obronie programu.

Chciałem zrobić to jako mały feature, ale nie mam ochoty spędzać czasu na szukaniu w internecie wyjaśnień i opisów części kodu, którego nie do końca rozumiem. Tak jak pisałem wcześniej liczyłem na to, że jest prosta, gotowa funkcja do tego typu operacji.

Tak czy inaczej, dziękuję za szybka odpowiedź.

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 16:31
przez Cyfrowy Baron
Tak jak pisałem wcześniej liczyłem na to, że jest prosta, gotowa funkcja do tego typu operacji.


Nawet gdyby istniała gotowa funkcja, to przecież byłaby zbudowana podobnie jak ta, którą ja podałem, czyli z innych funkcji i metod, zawarta byłaby tylko w odrębnym pliku (bibliotece), który musiałbyś dodać do projektu w sekcji include.

Tak wiec możesz tą funkcję podaną przeze mnie umieścić w odrębnym pliku *.h, umieścić ten plik w katalogu środowiska C++Builder, np. w katalogu:

C:\Program Files\CodeGear\RAD Studio\5.0\include

potem tylko w swojej aplikacji w sekcji include włączysz ten plik i wywołasz tylko funkcję: GetFileVersionInfo

Wszystkie gotowe funkcje są gromadzone w jakichś plikach (bibliotekach), by z nich skorzystać musisz dołączyć odpowiednia bibliotekę, więc zawsze moze pojawić sie pytanie: Jak działa ta funkcja?

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 16:39
przez simekone
Zrobiłem tak jak poradziłeś, ale niestety pojawia sie jakaś niegodność zmiennych:
Kod: Zaznacz cały
[BCC32 Error] GetVersion.h(26): E2034 Cannot convert 'wchar_t *' to 'const char *'
[BCC32 Error] GetVersion.h(26): E2342 Type mismatch in parameter '__format' (wanted 'const char *', got 'wchar_t *')

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 21:26
przez Cyfrowy Baron
Dzieje się tak dlatego, że środowisko C++ Builder 2009 operuje na zmiennych typu UnicodeString tutaj wchar_t, dlatego ten zapis:

Kod: Zaznacz cały
("\\StringFileInfo\\%04x%04x\\" + KeyName)


we wcześniejszych wersjach środowiska jest domyślnie traktowany jako typ AnsiString funkcja c_str() konwertuje typ AnsiString na char, podczas gdy w wersji 2009 i nowszych powyższy zapis jest traktowany jako typ UnicodeString. Funkcja sprintf oczekuje argumentów typu char*, nie można jednak dokonać konwerski z typu UnicodeString na char za pomocą funkcji c_str(), trzeba użyć funkcji t_str().

Kolejna sprawa to, że wersja 2009 operuje na UnicodeString wiec deklaracja zmiennej typu String jest traktowana jako UnicodeString, inaczej niż we wcześniejszych wersjach gdy była traktowana jako AnsiString. Można tutaj używać typu AnsiString, gdyż środowisko dokona niejawnej konwersji do UnicodeString, nie jestem jednak pewien czy stanie sie tak w wersji 2009, ale w wersji 2010 na pewno zostanie wykonana niejawna konwersja na typ UniceString. Dla pewności lepiej jest jednak deklarować typ UniceString. Należałoby też zmienić typ LPSTR na LPCTSTR by uczynić go w pełni zgodnym z nowym standardem.

Popełniłem bład nadajac swojej funkcji nazwę GetFileVersionInfo, gdyż funkcja o tej nazwie występuje już w bibliotekach środowiska C++Builder, dlatego w poniższym przykładzie zmieniłem nazwę funkcji na myGetFileVersionInfo

Kod: Zaznacz cały
//---------------------------------------------------------------------------
UnicodeString myGetFileVersionInfo(char *ModulePath, UnicodeString KeyName)
{
LPVOID lpStr1 = NULL, lpStr2 = NULL;
WORD* wTmp;
DWORD dwHandlev = NULL;
UINT dwLength;
char sFileName[1024] = {0};
char sTmp[1024] = {0};
UnicodeString sInfo;
LPVOID* pVersionInfo;

if(ModulePath == NULL) GetModuleFileName(NULL, sFileName, 1024);
else strcpy(sFileName, ModulePath);

DWORD dwInfoSize = GetFileVersionInfoSize((char*)(LPSTR)sFileName, &dwHandlev);

if(dwInfoSize)
{
  pVersionInfo = new LPVOID[dwInfoSize];
  if(GetFileVersionInfo((char*)(LPCTSTR)sFileName, dwHandlev, dwInfoSize, pVersionInfo))
  {
   if(VerQueryValue(pVersionInfo, "\\VarFileInfo\\Translation", &lpStr1, &dwLength))
   {
   wTmp = (WORD*)lpStr1;
   sprintf(sTmp, ("\\StringFileInfo\\%04x%04x\\" + KeyName).t_str(), *wTmp, *(wTmp + 1));
   if(VerQueryValue(pVersionInfo, sTmp, &lpStr2, &dwLength)) sInfo = (LPCTSTR)lpStr2;
   }
  }
  delete[] pVersionInfo;
}
return sInfo;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Label1->Caption =  "Wersja pliku: " + myGetFileVersionInfo(NULL, "FileVersion");
}
//---------------------------------------------------------------------------

Re: Pobieranie wersji programu (major, minor, release i build)

Nowy postNapisane: poniedziałek, 16 listopada 2009, 21:51
przez simekone
Wielkie dzięki ; )

W ramach ścisłości od kilku dni używam trial'a 2010 i powyższy kod działa w nim także poprawnie.