This is a new site that's currently running on alpha code. There are going to be bugs. If you discover any, please report them on the site's issues page (GitHub account required). Thanks.
Warning: Many URLs are going to change. Refer to the README file to discover which library project's documentation has been completed.
† Note: [~>1.1] The first block of code in this example requires v1.1 of the Resource File Unit if compiled with Delphi 2009 or later. When compiled with an earlier compiler v1.0 will suffice.
Sometimes it’s useful for a program to “know” the date when it was last compiled. One way to do this is to include a resource in the program that contains the compile date. The program can then read the date from the resource when it needs it.
The downside of this is that before each build the resource file containing the date has to be modified. There are going to be times when this will be forgotten and the compiled program will contain the wrong date.
Using the Resource File Unit unit can automate this process by creating a command line program that can be included in an automated build process.
To begin with, here’s routine that will store the current date, as an ANSI string, in a given resource file. If the resource already contains a date resource then it is overwritten. If there is no such resource then one is created.
Here’s the code:
uses
SysUtils, Classes, Windows, PJResFile;
procedure UpdateResFile(const ResFileName: string);
var
ResFile: TPJResourceFile;
DateResource: TPJResourceEntry;
DateStr: string;
const
DateResourceName = 'COMPILEDATE';
begin
ResFile := TPJResourceFile.Create;
try
// 1: Load any existing file
if FileExists(ResFileName) then
ResFile.LoadFromFile(ResFileName);
// 2: Check if there's already a suitable resource
DateResource := ResFile.FindEntry(RT_RCDATA, DateResourceName);
if not Assigned(DateResource) then
// no such resource: create one
DateResource := ResFile.AddEntry(RT_RCDATA, DateResourceName);
// 3: Store the current date in the resource
DateStr := FormatDateTime('yyyy"-"mm"-"dd hh":"mm":"ss', Now);
{$IFDEF UNICODE}
DateResource.DataBytes := TEncoding.Default.GetBytes(DateStr);
{$ELSE}
DateResource.Data.Size := 0; // clear any existing date
DateResource.Data.WriteBuffer(Pointer(DateStr)^, Length(DateStr));
DateResource.Data.Position := 0;
{$ENDIF}
// 4: Save the modified resource file
ResFile.SaveToFile(ResFileName);
finally
ResFile.Free;
end;
end;
Here’s how it works:
Note that any existing resources in the file are preserved. If the resource file contained the “data” resource it is overwritten, but if the file had no such resource one is added. If the resource file didn’t exist a new file is created with a single “date” resource.
Any program using the resource has to simply read the date string as ANSI text, convert it to a TDateTime etc. if necessary and use it as required.
Of course you could always store a raw TDateTime value in resources instead of a format string. To do this replace the declaration of DateStr with a new local variable DateNow with type TDateTime and replace the code in the section introduced by the // 3: Store the current date in the resource
comment with the following:
...
// 3: Store the current date in the resource
DateNow := Now;
DateResource.Data.Size := 0;
DateResource.Data.WriteBuffer(DateNow, SizeOf(DateNow));
DateResource.Data.Position := 0;
// 4: Save the modified resource file
...
This routine could be included in a console application that takes the resource file name as a parameter then updates or creates the resource file containing the current date, like this:
program DateIns;
{$APPTYPE CONSOLE}
uses
SysUtils,
Classes,
Windows,
PJResFile in 'PJResFile.pas';
{$R *.res}
// Insert UpdateResFile procedure here
var
ResFileName: string;
begin
try
ResFileName := ParamStr(1);
if ResFileName = '' then
raise Exception.Create(
'Resource file name must be passed on the command line'
);
UpdateResFile(ResFileName);
ExitCode := 0;
except
on E: Exception do
begin
WriteLn('Error: ', E.Message);
ExitCode := 1;
end;
end;
end.
You can then insert this program in your build tool chain.
Links: