Wersja aplikacji do zmiennej

0

Witam. Tworząc program chciałbym, aby w menu Pomoc->O programie wyświetlała mi się aktualna wersja programu w formacie np. 0.1.2.3. Wersję taką ustawiam w oknie Version Info w Opcjach projektu. Czy jest jakiś sposób na zapisanie wersji programu do zmiennej, którą mogę później wykorzystać?

1

mozesz ja pozniej odczytac z pliku exe - czyli z samego siebie.
google-> delphi get version exe

0

Znalazłem taką funkcję:

{
Usage:
VersionInformation(ListBox1)
}

{Pads or truncates a String and
Justifies Left if StrJustify=True}
Function StringPad(
   InputStr,
   FillChar: String;
   StrLen: Integer;
   StrJustify: Boolean): String;
Var
   TempFill: String;
   Counter : Integer;
Begin
   If Not (Length(InputStr) = StrLen) Then
   Begin
     If Length(InputStr) > StrLen Then
     Begin
       InputStr := Copy(InputStr,1,StrLen) ;
     End
     Else
     Begin
       TempFill := '';
       For Counter := 1 To StrLen-Length(InputStr) Do
       Begin
         TempFill := TempFill + FillChar;
       End;
       If StrJustify Then
       Begin
         {Left Justified}
         InputStr := InputStr + TempFill;
       End
       Else
       Begin
         {Right Justified}
         InputStr := TempFill + InputStr ;
       End;
     End;
   End;
   Result := InputStr;
End;


Function VersionInformation(
   ListBox : TListBox): Boolean;
const
   InfoNum = 11;
   InfoStr : array [1..InfoNum] of String =
     ('CompanyName', 'FileDescription', 'FileVersion',
'InternalName', 'LegalCopyright', 'LegalTradeMarks',
'OriginalFilename', 'ProductName', 'ProductVersion',
'Comments', 'Author') ;
   LabelStr : array [1..InfoNum] of String =
     ('Company Name', 'Description', 'File Version',
'Internal Name', 'Copyright', 'TradeMarks',
'Original File Name', 'Product Name',
'Product Version', 'Comments', 'Author') ;
var
  S : String;
    j : Integer;
   Len, n: Cardinal;
   Buf : PChar;
   Value : PChar;
begin
   Try
     S := Application.ExeName;
     ListBox.Items.Clear;  <-----------------------  Tu wywala błąd
     ListBox.Sorted := True;
     ListBox.Font.Name := 'Courier New';
     n := GetFileVersionInfoSize(PChar(S),n) ;
     If n > 0 Then Begin
       Buf := AllocMem(n) ;
       ListBox.Items.Add
(StringPad('Size',' ',20,True)+' = '+IntToStr(n)) ;
       GetFileVersionInfo(PChar(S),0,n,Buf) ;
       For j:=1 To InfoNum Do Begin
         If VerQueryValue(Buf,PChar('StringFileInfo\040904E4\'+
                           InfoStr[j]),Pointer(Value),Len) Then
         Begin
           Value := PChar(Trim(Value)) ;
           If Length(Value) > 0 Then
           Begin
             ListBox.Items.Add
(StringPad(labelStr,' ',20,True)+' = '+Value) ;
           End;
         End;
       End;
       FreeMem(Buf,n) ;
     End
     Else Begin
       ListBox.Items.Add
('No FileVersionInfo found') ;
     End;
     Result := True;
   Except
     Result := False;
   End;
End;

Nie znam dobrze elementów typu TListBox, więc proszę o pomoc co może powodować błąd.

0

Nie utworzyłeś TListBox.
Poza tym łatwiej byłoby użyć po prostu TStringList...

0

TListBox był przekazywany jako parametr... Zresztą znalazłem o wiele mniejszy kod kilka stron dalej ;] oto on:

procedure GetBuildInfo(var V1, V2, V3, V4: word);
var
  VerInfoSize, VerValueSize, Dummy: DWORD;
  VerInfo: Pointer;
  VerValue: PVSFixedFileInfo;
begin
  VerInfoSize := GetFileVersionInfoSize(PChar(ParamStr(0)), Dummy);
  if VerInfoSize > 0 then
  begin
      GetMem(VerInfo, VerInfoSize);
      try
        if GetFileVersionInfo(PChar(sFileName), 0, VerInfoSize, VerInfo) then
        begin
          VerQueryValue(VerInfo, '\', Pointer(VerValue), VerValueSize);
          with VerValue^ do
          begin
            V1 := dwFileVersionMS shr 16;
            V2 := dwFileVersionMS and $FFFF;
            V3 := dwFileVersionLS shr 16;
            V4 := dwFileVersionLS and $FFFF;
          end;
        end;
      finally
        FreeMem(VerInfo, VerInfoSize);
      end;
  end;
end;

Dzięki niemu można uzyskać każdą cyferkę oddzielnie co jest pomocne przy formatowaniu, np. v2.1.3 build 5 :D

0
marcin412 napisał(a)

Dzięki niemu można uzyskać każdą cyferkę oddzielnie co jest pomocne przy formatowaniu

Przecież podzielić łańcuch na kawałki według jakichś znaków nie jest problem; Kilka funkcji do tego istnieje, także łatwo samemu taką napisac;

const
  IV_CompanyName      = 0;
  IV_FileDescription  = 1;
  IV_FileVersion      = 2;
  IV_InternalName     = 3;
  IV_LegalCopyRight   = 4;
  IV_LegalTradeMark   = 5;
  IV_OriginalFileName = 6;
  IV_ProductName      = 7;
  IV_ProductVersion   = 8;
  IV_Comments         = 9;

function GetAppVersionInfo(const FileName: String; InfoValue: Byte): String;
var
  VerSize: Integer;
  VerBuf: PChar;
  VerBufValue: Pointer;
  VerHandle: Cardinal;
  VerBufLen: Cardinal;
  VerKey: String;

  function GetInfo(ThisKey: String): String;
  begin
    Result := '';
    VerKey := '\StringFileInfo\' + IntToHex(LoWord(Integer(VerBufValue^)), 4) +
               IntToHex(HiWord(Integer(VerBufValue^)), 4) + '\' + ThisKey;

    if VerQueryValue(VerBuf, PChar(VerKey), VerBufValue, VerBufLen) then
      Result := StrPas(VerBufValue);
  end;

  function QueryValue(ThisValue: string): string;
  begin
    Result := '';

    if GetFileVersionInfo(PChar(FileName), VerHandle, VerSize, VerBuf) and
       VerQueryValue(VerBuf, '\VarFileInfo\Translation', VerBufValue, VerBufLen) then
         Result := GetInfo(ThisValue);
  end;

begin
  VerSize := GetFileVersionInfoSize(PChar(FileName), VerHandle);
  VerBuf := AllocMem(VerSize);
  
  try
    case InfoValue of
      IV_CompanyName:      Result := QueryValue('CompanyName');
      IV_FileDescription:  Result := QueryValue('FileDescription');
      IV_FileVersion:      Result := QueryValue('FileVersion');
      IV_InternalName:     Result := QueryValue('InternalName');
      IV_LegalCopyRight:   Result := QueryValue('LegalCopyRight');
      IV_LegalTradeMark:   Result := QueryValue('LegalTradeMark');
      IV_OriginalFileName: Result := QueryValue('OriginalFileName');
      IV_ProductName:      Result := QueryValue('ProductName');
      IV_ProductVersion:   Result := QueryValue('ProductVersion');
      IV_Comments:         Result := QueryValue('Comments');
    end;
  finally
    FreeMem(VerBuf, VerSize);
  end;
end;

Dzięki temu kodowi możesz pobrać wiele informacji z pliku wykonywalnego; Podobny do tego kod napisał dla mnie kiedyś @Opi, ten jest przerobiony na własne potrzeby; Myślę, że @Opi nie będzie miał nic przeciwko, jak udostępnię go :)

0

Mam jeszcze jeden problem tyle, że w C++. Otóż funkcja (której kod przedstawiam poniżej) zamiast ustawionego przeze mnie numeru wersji zawraca (zawsze) wartości odpowiednio:
V1 = 65535
V2 = 65534
V3 = 0
V4 = 0

W opcjach projektu miałem ustawione 3.3.3.3

Oto kod funkcji:

void GetAppVersion(DWORD &V1, DWORD &V2, DWORD &V3, DWORD &V4)
{
   //give your application full path
   LPTSTR lpszFilePath = g_CmdLine;

   DWORD dwDummy;
   DWORD dwFVISize = GetFileVersionInfoSize( lpszFilePath , &dwDummy );

   LPBYTE lpVersionInfo = new BYTE[dwFVISize];

   GetFileVersionInfo( lpszFilePath , 0 , dwFVISize , lpVersionInfo );

   UINT uLen;
   VS_FIXEDFILEINFO *lpFfi;

   VerQueryValue( lpVersionInfo , _T("\\") , (LPVOID *)&lpFfi , &uLen );

   DWORD dwFileVersionMS = lpFfi->dwFileVersionMS;
   DWORD dwFileVersionLS = lpFfi->dwFileVersionLS;

   delete [] lpVersionInfo;

   V1 = HIWORD(dwFileVersionMS);
   V2 = LOWORD(dwFileVersionMS);
   V3 = HIWORD(dwFileVersionLS);
   V4 = LOWORD(dwFileVersionLS);
}
0

Wrzuć ten kod do działu 4programmers.net » Forum » C/C++ to może Ci ktoś pomoże; W tym dziale rozwiązuje się problemy w języku Object Pascal & Pascal;

Jeśli nie wiesz co się dzieje - uruchom debuger;

0

Witam wszystkich
Mam takie pytanko każdy zamieszcza jak można odczytać wersję, COmpanyName itp
A jak zmienić w pliku np dll CompanyName?

0

Pewnie są do tego rózne metody. Ale najprościej chyba przez edycje zasóbów.

0
oksik napisał(a):

Witam wszystkich
Mam takie pytanko każdy zamieszcza jak można odczytać wersję, COmpanyName itp
A jak zmienić w pliku np dll CompanyName?

http://www.wilsonc.demon.co.uk/files/d10/ResourceUtils100.zip

0

Dzięki za linka ale nie nadmieniłem że potrzebowałbym tego do delphi 5 - 7, trochę leciwe:)

0

A nie możesz sobie zrobić stałej z wersją programu? Jak i tak wpisujesz to w środowisku to zamiast w środowisku wpisz do stałej.

program qwer;
const
  version = '1.2.3.4';
begin
end.
0

Widzicie budowa w resourcach wersji i innych właściwości wygląda mniej więcej tak:

1 VERSIONINFO
FILEVERSION 1,9,0,29
PRODUCTVERSION 1,9,0,29
FILEOS 0x4
FILETYPE 0x1
FILESUBTYPE 0x0L
{
  BLOCK "StringFileInfo"
  {
        BLOCK "040904E4"
        {
            VALUE "CompanyName", ""
            VALUE "FileDescription", ""
            VALUE "FileVersion", ""
            VALUE "InternalName", ""
            VALUE "LegalCopyright", ""
            VALUE "LegalTrademarks", ""
            VALUE "OriginalFilename", ""
            VALUE "ProductName", ""
            VALUE "ProductVersion", "1.9.0\0"
            VALUE "Comments",""
        }
  }
  BLOCK "VarFileInfo"
  {
        VALUE "Translation", 0x0409, 1252
  }
}

chodzi mi o to żeby się dobrać do tego blocku BLOCK "040904E4" a konkretnie do której kolwiek wartości. To co mówicie jest jak najbardziej ok ale potrzebuje zmieniać wersję DLL z kodu programu.

dodanie znacznika <code> - fp

1 użytkowników online, w tym zalogowanych: 0, gości: 1