我们有它由众多应用的系统。 所有的应用程序有自己的版本在同一时间发生变化。 目前,当我们发布一个新版本,我们必须手动打开每个应用程序的项目选择和更改版本一个接一个。 有什么办法来编译同一版本的所有应用程序,例如,它保存在一个全局文件,并在编译时,读取该文件与该版本分配给项目? 我只是试图消除步骤太多,因为我们计划更频繁地更改版本号。 我想改变它在只有一个地方。 可以这样做? 如何?
Answer 1:
您可以创建一个VERSIONINFO
资源,在一个纯文本文件(例如, 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
}
}
注:C风格空终结符( \0
),在每个项目结束时需要如为了使资源编译器正确终止字符串。 否则,当您使用浏览器来显示可执行文件的版本信息,你可能会出现乱码或部分连接值。
一个行添加到您的项目源文件:
{$R VersionInfo.res VersionInfo.rc}
我建议把常见的版本信息资源到您的版本控制系统中的外部引用,然后你可以检查出来到每个项目的文件夹,轻松地更新它。
做一个项目 - >构建和你的版本信息嵌入.exe文件。 您可以通过使用Windows资源管理器和查看应用程序的性能验证。
有一对夫妇在CodeNewsFast档案Embarcadero的德尔福论坛帖子(一个由我和一个由吉姆·弗莱明有响应)。 我的是[这里],其中,我描述一步一步如何使用预生成事件在您的项目更新资源脚本我上面贴的版本号。
吉姆张贴一些答复,但大约有十几个帖子或这样下来有来源,可以从他的作品的预生成事件被称为可执行文件。 (有些事我会做出不同的,就像让IDE通过项目名称和位置在命令行上;如何这样做是一步一步的文章中描述我还处理版本解析和增加不同,但基本的应用程序是一个很好的起点位置。)
英巴卡迪诺的小组正在下降,但我能够检索吉姆的代码CodeNewsFast为好,并能在这里重现:
肯,
谢谢你,我得到它的工作。
万一别人要实现这个解决方案,下面你会发现必要的步骤和辅助程序。
吉姆·弗莱明
A)在项目目录或其它地方创建您的版本信息资源文件,用下面的
内容和文件扩展名.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)创建一些文件夹,一个新的项目,只有模块的代码应该类似于:
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)在其版本号应该增加该项目的项目选项:
去掉勾选“包括版本信息”。
添加预生成事件用以下文本,作为写入,包括两对双引号的,内<>代的部分:
“<完整的文件名,并自动递增程序exe文件的路径>”,“<完整文件名和.RC资源文件的路径>”
d)添加到项目源,正下方的“程序”的文章:
{$R '<whatever you called it>.res' '<whatever you called it>.rc'} // I think both names must
在这里一样:IIRC,有错误时,他们是不同的。
E)编译,运行和享受自动递增的回报版本号,尽管英巴卡迪诺已经删除的设施。
吉姆的内容结束
你可以使用预生成事件,例如,更新ProductName
或FileDescription
值,或必须从基础的脚本不同任何人。
Answer 2:
UPDATE:这不是RADStudio本身的一部分,而是来自安德烈亚斯Hausladen的DDevExtensions (我已经习惯有...!)。
用ProjectGroup只要你安装了优良您可以在IDE中做DDevExtensions由安德烈亚斯Hausladen。
- 有一个项目组来包含所有项目
- 确保每个项目已经“包含在项目的版本信息”的检查
Options|Version Info page
。 - 使用菜单
Project|Set Versioninfo...
打开设置项目VERSIONINFO对话框(只有一次,当前项目并不重要)。 - 在那里,你可以指定所有的版本信息,然后选择要“应用到所有”或只是所选择的项目,如果选中“应用到选定的”。
例如,看我怎么设置的版本,以这两个项目的一次:
然后, Build All
的ProjectGroup与生产,并设置在1.1.1.9版本的所有其他细节都EXE文件...
Answer 3:
这是对用例dzPrepBuild之一: http://www.dummzeuch.de/delphi/dzprepbuild/englisch.html
(注:该项目已被转移到sourceforge上,因为感谢BerliOS打算去年被关闭。 http://sourceforge.net/projects/dzprepbuild/ )