Jak zdefiniować wersję aplikacji w jednym miejscu dla wielu aplikacji?
Mamy system, który składa się z wielu aplikacji. Wszystkie aplikacje mają zmienioną wersję w tym samym czasie. Obecnie, kiedy wydajemy nową wersję, musimy ręcznie otworzyć Opcje projektu każdej aplikacji i zmienić wersję jeden po drugim. Czy jest jakiś sposób kompilacji wszystkich aplikacji na tej samej wersji, na przykład, zapisać go w pliku globalnym i po kompilacji, przeczytać ten plik i przypisać tę wersję do projektu? Staram się tylko wyeliminować zbyt wiele kroków, ponieważ planujemy częściej zmieniać numery wersji. Chciałbym to zmienić tylko w jednym miejscu. Czy można to zrobić? i jak?
3 answers
Możesz utworzyć VERSIONINFO
zasób, w zwykłym pliku tekstowym (np., Versioninfo.rc
)
1 VERSIONINFO
FILEVERSION 2,0,0,0
PRODUCTVERSION 2,0,0,0
FILEOS 0x4
FILETYPE 0x1
{
BLOCK "StringFileInfo"
{
BLOCK "040904E4"
{
VALUE "CompanyName", "Your Company Name Here\0"
VALUE "FileDescription", "Your File Description Here\0"
VALUE "FileVersion", "2.0.0.0\0"
VALUE "InternalName", "Your Internal Name\0"
VALUE "LegalCopyright", "© Your Copyright Notice\0"
VALUE "LegalTrademarks", "Your Trademark Notice\0"
VALUE "OriginalFilename", "YourExeName\0"
VALUE "ProductName", "Your Product Name\0"
VALUE "ProductVersion", "2.0.0.0\0"
VALUE "Comments", "No Comments\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409 0x04E4
}
}
Uwaga: terminatory null w stylu C (\0
) są potrzebne na końcu każdego elementu, jak pokazano, aby kompilator zasobów mógł poprawnie zakończyć ciągi znaków. W przeciwnym razie, gdy używasz Eksploratora do wyświetlania informacji o wersji pliku wykonywalnego, możesz uzyskać zniekształcone lub częściowo skonkatenowane wartości.
Dodaj wiersz do pliku źródłowego projektu:
{$R VersionInfo.res VersionInfo.rc}
Proponuję umieścić wspólny źródło informacji o wersji do odniesienia zewnętrznego w systemie kontroli wersji, a następnie możesz po prostu sprawdzić go w folderze każdego projektu i łatwo go zaktualizować.
Wykonaj projekt - > Build, A informacja o wersji zostanie osadzona w .exe. Możesz sprawdzić, używając Eksploratora Windows i przeglądając właściwości aplikacji.
Jest kilka postów (jeden przeze mnie i jeden w odpowiedzi Jima Fleminga) na forach Embarcadero Delphi w archiwum CodeNewsFast. Mój jest [tutaj], gdzie, Opisuję krok po kroku, jak użyć zdarzenia pre-build w projekcie, aby zaktualizować numer wersji w skrypcie zasobów, który napisałem powyżej.
Jim napisał kilka odpowiedzi, ale około kilkunastu postów znajduje się źródło pliku wykonywalnego, który można wywołać ze zdarzenia pre-build, które działa dla niego. (Są pewne rzeczy, które zrobiłbym inaczej, jak pozwolenie IDE przekazać nazwę projektu i lokalizację w wierszu poleceń; jak to zrobić jest opisane w artykule krok po kroku. Też bym sobie poradził wersja parsuje i inkrementuje inaczej, ale podstawowa aplikacja jest dobrą lokalizacją początkową.)
Grupa Embarcadero jest obecnie nieaktywna, ale udało mi się pobrać kod Jima z CodeNewsFast i odtworzyć go tutaj:Ken,
Dzięki tobie udało mi się.Na wszelki wypadek, gdyby ktoś jeszcze chciał wdrożyć to rozwiązanie, Poniżej znajdziesz niezbędne kroki i program pomocniczy.
Jim Fleming
A) Utwórz plik informacji o wersji w katalogu projektu lub gdziekolwiek indziej, za pomocą następującego
Zawartość i rozszerzenie pliku .rc:
// Note the \000 !!!! Here and elsewhere below !!!!
// C string terminator !!!
#define CONST_VERSION "4.1.1.1003\000"
1 VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEOS 0x4
FILETYPE 0x1
{
BLOCK "StringFileInfo"
{
BLOCK "040904E4" // Will need changing if your language is not English and char-set not
1252 (multilingual).
{
VALUE "CompanyName", "Whatever\000"
VALUE "FileDescription", "Whatever\000"
VALUE "FileVersion", CONST_VERSION
VALUE "InternalName", "My Internal Name\000"
VALUE "LegalCopyright", "Copyright © whoever\000"
VALUE "LegalTrademarks", "\000"
VALUE "OriginalFileName", "If you wish\000"
VALUE "ProductName", "What pleases you\000"
VALUE "ProductVersion", CONST_VERSION
VALUE "Comments", "Anything you wish to add\000"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409 0x04E4
}
}
B) Utwórz nowy projekt w jakimś folderze, Kod tylko modułu powinien być podobny do:
unit FormIncrementBuildNumber;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
Vcl.StdCtrls, System.IOUtils, System.StrUtils;
type
TIncrementBuildNumber = class(TForm)
IncrementingBuildNumberLabel: TLabel;
procedure FormShow (Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
IncrementBuildNumber: TIncrementBuildNumber;
implementation
{$R *.dfm}
procedure TIncrementBuildNumber.FormShow (Sender: TObject);
var
Resource_File_Contents: TStringList;
Full_File_Name_And_Path: string;
First_Line_Of_File: string;
Position_First_Dot: Integer;
Position_Second_Dot: Integer;
Position_Third_Dot: Integer;
Position_Trailing_Backslash: Integer;
Start_of_Build_Number: Integer;
Length_of_Build_Number: Integer;
Build_Number_In_ASCII: string;
Build_Number_Numeric: Integer;
Old_Resource_File_Name: string;
Success: Boolean;
begin
if (System.ParamCount <> 1) then
begin
ShowMessage ('Resource File name not in first command-line parameter.');
Exit;
end;
Full_File_Name_And_Path := System.ParamStr(1);
if (not TFile.Exists(Full_File_Name_And_Path, False)) then
begin
ShowMessage ('Resource file ' + Full_File_Name_And_Path +
' not found.');
Exit;
end;
Resource_File_Contents := TStringList.Create;
try
Resource_File_Contents.LoadFromFile(Full_File_Name_And_Path);
First_Line_Of_File := Resource_File_Contents.Strings[0];
if (Copy(First_Line_Of_File, 1, 21) <> '#define CONST_VERSION') then
begin
ShowMessage ('First line of Version Info must start with "#define CONST_VERSION".' +
#13 + 'Version not incremented.');
Exit;
end;
Position_First_Dot := Pos('.', First_Line_Of_File);
if (Position_First_Dot = 0) then
begin
ShowMessage ('Version must have format "a.b.c.d".' + #13 +
'Build Number not incremented.');
Exit;
end;
Position_Second_Dot := PosEx('.', First_Line_Of_File,
Position_First_Dot+1);
if (Position_Second_Dot = 0) then
begin
ShowMessage ('Version must have format "a.b.c.d".' + #13 +
'Build Number not incremented.');
Exit;
end;
Position_Third_Dot := PosEx('.', First_Line_Of_File,
Position_Second_Dot+1);
if (Position_Third_Dot = 0) then
begin
ShowMessage ('Version must have format "a.b.c.d".' + #13 +
'Build Number not incremented.');
Exit;
end;
Position_Trailing_Backslash := PosEx('\', First_Line_Of_File,
Position_Third_Dot+1);
if (Position_Trailing_Backslash = 0) then
begin
ShowMessage ('Version must have format "a.b.c.d\000".' + #13 +
'Build Number not incremented.');
Exit;
end;
Start_of_Build_Number := Position_Third_Dot + 1;
Length_of_Build_Number := Position_Trailing_Backslash -
Start_of_Build_Number;
if (Length_of_Build_Number < 1) then
begin
ShowMessage ('Build Number must be present.' + #13 +
'Build Number not incremented.');
Exit;
end;
Build_Number_In_ASCII := Copy (First_Line_Of_File,
Start_of_Build_Number,
Length_of_Build_Number);
Success := TryStrToInt (Build_Number_In_ASCII, Build_Number_Numeric);
if (not Success) then
begin
ShowMessage ('Build Number must be numeric integer.' + #13 +
'Build Number not incremented.');
Exit;
end;
Build_Number_Numeric := Build_Number_Numeric + 1;
Build_Number_In_ASCII := IntToStr(Build_Number_Numeric);
Resource_File_Contents.Strings[0] := Copy(First_Line_Of_File, 1,
Position_Third_Dot) +
Build_Number_In_ASCII +
'\000"';
Old_Resource_File_Name := Full_File_Name_And_Path;
Old_Resource_File_Name := TPath.ChangeExtension(Old_Resource_File_Name, '~rc');
if TFile.Exists(Old_Resource_File_Name, False) then
TFile.Delete(Old_Resource_File_Name);
Success := RenameFile(Full_File_Name_And_Path, Old_Resource_File_Name);
if (not Success) then
begin
ShowMessage ('Error renaming old resource file to have extension "~rc".' + #13 +
'Build Number not incremented.');
Exit;
end;
Resource_File_Contents.SaveToFile(Full_File_Name_And_Path);
finally
Resource_File_Contents.Free;
end;
end;
procedure TIncrementBuildNumber.FormActivate (Sender: TObject);
begin
Close;
end;
end.
C) w opcjach projektu, którego numer budowy powinien być zwiększany:
Usuń zaznaczenie "Dołącz informacje o wersji".
Dodaj zdarzenie pre-build z po tekście, jak napisano, w tym dwie pary podwójnych cudzysłowów, zastępując części wewnątrz :
" " "
D) dodać do źródła projektu, tuż pod słowem kluczowym "program":
{$R '<whatever you called it>.res' '<whatever you called it>.rc'} // I think both names must
Być tym samym tutaj: IIRC, dostał błędy, gdy były różne.
E) kompilować, uruchamiać i cieszyć się powrotem Auto-Increment budować numery, pomimo Embarcadero usunął obiekt.
Koniec treści Jima
Można użyć zdarzenia pre-build, aby na przykład zaktualizować wartości ProductName
lub FileDescription
, lub inne, które muszą być inne niż skrypt podstawowy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-21 04:50:58
UPDATE: nie jest częścią samego RADStudio, ale pochodzi z Ddevextensions Andreasa Hausladena (które już kiedyś miałem...!).
Możesz to zrobić z poziomu IDE {[5] } z ProjectGroup pod warunkiem zainstalowania doskonałego DDevExtensions od Andreasa Hausladena.
- mieć grupę projektową, która zawiera wszystkie twoje projekty
- upewnij się, że każdy z twoich projektów ma " Include version information in project" sprawdzone w
Options|Version Info page
. - użyj menu
Project|Set Versioninfo...
, aby otworzyć okno dialogowe Set Project Versioninfo (tylko raz, bieżący projekt nie ma znaczenia). - tam możesz określić wszystkie informacje o wersji i wybrać, który "Zastosuj do wszystkich" lub tylko do wybranych projektów, jeśli zaznaczyłeś "Zastosuj do wybranych".
Na przykład, zobacz jak ustawić wersję do obu projektów naraz:
Następnie Build All
Na ProjectGroup wyprodukował oba EXY z wersją ustawioną na 1.1.1.9 i wszystkie inne szczegóły...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-02 23:28:50
Jest to jeden z przypadków użycia dzPrepBuild: http://www.dummzeuch.de/delphi/dzprepbuild/englisch.html
(uwaga: projekt został przeniesiony do sourceforge, ponieważ berlios miał zostać zamknięty w zeszłym roku. http://sourceforge.net/projects/dzprepbuild/)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-03 12:48:35