20

多数のアプリケーションで構成されるシステムがあります。すべてのアプリケーションのバージョンが同時に変更されます。現在、新しいバージョンをリリースするときは、各アプリケーションのプロジェクトオプションを手動で開き、バージョンを1つずつ変更する必要があります。すべてのアプリケーションを同じバージョンでコンパイルする方法はありますか?たとえば、グローバルファイルに保存し、コンパイル時にこのファイルを読み取って、そのバージョンをプロジェクトに割り当てますか?バージョン番号をより頻繁に変更する予定なので、あまりにも多くの手順を削除しようとしています。一箇所だけ変更したいのですが。これはできますか?そしてどうやって?

4

3 に答える 3

29

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
}
}

注:\0リソース コンパイラが文字列を適切に終了するためには、示されているように、各項目の末尾に C スタイルの null ターミネータ ( ) が必要です。そうしないと、エクスプローラーを使用して実行可能ファイルのバージョン情報を表示すると、値が文字化けしたり、部分的に連結されたりする場合があります。

プロジェクトのソース ファイルに次の行を追加します。

{$R VersionInfo.res VersionInfo.rc}

共通のバージョン情報リソースをバージョン管理システムの外部参照に配置することをお勧めします。そうすれば、それを各プロジェクトのフォルダーにチェックアウトして簡単に更新できます。

Project->Build を実行すると、バージョン情報が .exe に埋め込まれます。Windows エクスプローラーを使用して、アプリのプロパティを表示することで確認できます。

CodeNewsFast アーカイブの Embarcadero Delphi フォーラムには、いくつかの投稿があります (1 つは私によるもので、もう 1 つは Jim Fleming による回答です)。私のものは [こちら] です。ここでは、プロジェクトでビルド前イベントを使用して、上で投稿したリソース スクリプトのバージョン番号を更新する方法を段階的に説明します。

Jim はいくつかの返信を投稿しますが、約 12 件程度の投稿の下に、彼のために機能するビルド前イベントから呼び出すことができる実行可能ファイルのソースがあります。(IDE にコマンド ラインでプロジェクト名と場所を渡すようにするなど、別の方法で行うこともいくつかあります。その方法については、ステップバイステップの記事で説明しています。また、バージョンの解析とインクリメントは異なりますが、基本的なアプリは出発点として適しています)。

Embarcadero のグループは現在ダウンしていますが、CodeNewsFastから Jim のコードを取得することもできました。ここで再現できます。

ケン、

おかげさまで出来上がりました。

他の誰かがこのソリューションを実装したい場合に備えて、以下に必要な手順と補助プログラムを示します。

ジム・フレミング

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) ビルド番号をインクリメントする必要があるプロジェクトの [プロジェクト オプション] で:

  • 「バージョン情報を含める」のチェックを外します。

  • < > 内の部分を置き換えて、二重引用符の 2 つのペアを含む、書かれているとおりに、次のテキストを使用してビルド前イベントを追加します。

"<自動インクリメント プログラム exe の完全なファイル名とパス>" "<.rc リソース ファイルの完全なファイル名とパス>"

D) プロジェクト ソースの「program」キーワードのすぐ下に追加します。

{$R '<whatever you called it>.res' '<whatever you called it>.rc'} // I think both names must

ここで同じである: IIRC、異なる場合にエラーが発生しました。

E) Embarcadero がこの機能を削除したにもかかわらず、コンパイル、実行、および自動インクリメント ビルド番号のリターンをお楽しみください。

ジムのコンテンツの終わり

ビルド前のイベントを使用して、たとえば、ProductNameまたはFileDescription値、またはベース スクリプトとは異なる必要があるその他の値を更新できます。

于 2012-08-02T17:18:32.827 に答える
16

更新: RADStudio 自体の一部ではありませんが、Andreas Hausladen の DDevExtensions (私はこれに慣れています...!) から来ています。

Andreas Hausladenの優れた DDevExtensions がインストールされていれば、ProjectGroup を使用しIDE 内から実行できます。

  • すべてのプロジェクトを含むプロジェクト グループを用意する
  • 各プロジェクトで、[プロジェクトにバージョン情報を含める] がオンになっていることを確認してくださいOptions|Version Info page
  • メニューProject|Set Versioninfo...を使用して Set Project Versioninfo ダイアログを開きます (一度だけ、現在のプロジェクトは関係ありません)。
  • そこでは、すべてのバージョン情報を指定し、「すべてに適用」するか、「選択したものに適用」をチェックした場合は選択したプロジェクトにのみ適用するかを選択できます。

たとえば、バージョンを両方のプロジェクトに同時に設定する方法をご覧ください。 一度に両方のプロジェクトにバージョンを設定する例

次に、Build AllProjectGroup で、バージョンが 1.1.1.9 に設定された両方の exe とその他すべての詳細が生成されました...

于 2012-08-02T18:30:47.470 に答える
2

これは dzPrepBuild の使用例の 1 つです: http://www.dummzeuch.de/delphi/dzprepbuild/englisch.html

(注: 昨年 berlios が閉鎖される予定だったため、プロジェクトは sourceforge に移動されました。http://sourceforge.net/projects/dzprepbuild/ )

于 2012-08-03T12:48:35.363 に答える