VERSIONINFO resource not being shown in EXE properties - delphi

I'm using Delphi 10.0 Seattle on a machine with Windows 10.
We have a system that has several executables. We use the version information via .rc file:
1 VERSIONINFO
FILEVERSION 18,2,0,1660
PRODUCTVERSION 18,2,0,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS (VS_FF_SPECIALBUILD|VS_FF_PRERELEASE)
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "041604E4"
BEGIN
VALUE "CompanyName", "BLA BLA BLA\0"
VALUE "FileDescription", "BLA BLABLA - DESCRICAO\0"
VALUE "FileVersion", "18.2.0.1660\0"
VALUE "InternalName", "nomexecutavel.exe\0"
VALUE "LegalCopyright", "Copyright 2018\0"
VALUE "LegalTrademarks", "BLA BLA BLA é marca registrada\0"
VALUE "OriginalFilename", "nomeexecutavel.exe\0"
VALUE "ProductName", "nomedoproduto\0"
VALUE "ProductVersion", "18.2.0\0"
VALUE "SpecialBuild", "Para Homologação\0"
VALUE "GitRevision", "790d79ee92af023d6beac953072c45b0385df17f\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0416, 1252
END
END
This .rc file is compiled through brcc32.exe.
In the project file the .RES file information generated by brcc32 is loaded.
{$R VersionInfoFactor.res}
After I do the build and install on a Windows machine in Portuguese, I can view the version information by right-clicking on the executable, selecting Properties, then Details.
So far, this is nothing new, it shows the data that is informed in the .rc file.
Now, if I install this same executable on a Windows machine in another language, I can no longer view this information.
Would anyone know the cause?

Your resource script provides version info for ONLY Portuguese and no other language. So, of course, a non-Portuguese machine won't display anything meaningful.
You need to provide multiple StringFileInfo blocks, one for each language you want to support. And you should have a block for US English, which is the fallback when a block for a specific language is not provided.
You should organize the blocks in this order, per Hierarchical Organization of Resources for Localization:
US English
Neutral cultures
Specific cultures
On a side note, you don't need to invoke brcc32.exe manually. The Delphi compiler can do that for you, if you include the .rc filename in the {$R} directive:
{$R VersionInfoFactor.res VersionInfoFactor.rc}

Related

Delphi Version number central but other info decentral

Background
Upto RS10.3 I used to use Andreas Hausladen DDevExtensions to set my version number in my project sources to be the same for all modules (bpl's/exe), but unfortunately Andreas has stopped updating his tool for RS10.4 and later.
So I am looking for more comfortable ways to set a version number in my app modules than applying multi-file changes to all dproj files with NotePad++.
But... On the other side I do want to keep specific information (like file description etc) specific to the module file.
What I also would like but isnt really a requirement is to have my (c) notice, and other shared info to be centralized in a single file (preferably .rc) as well.
It is not a problem to drop the version info from the dproj files (which are a pain to maintain anyway) and have a specific .rc file for each module instead.
Another advantage would be that having one central version number and (c) file is also a lot better in svn change management since I don't have to commit each and every .dproj file because of the version/build number change.
Investigation
(To be updated as we go along)
I Checked out
How to include Subversion revision number into Delphi project
Incrementing Delphi XE project version number from command line
But those solutions are not really what I am looking for; I am not looking for scripts but a source file/project file way to accomplish my task.
So here's the Q
How can I have one single .rc file containing my version number and use it in other .rc files containing specific version info
Ah I didn't expect it to be this simple...
I Created two .rc files, one with the shared info as #defines SharedVersionDefs.rc:
#define VER_MAJ 1
#define VER_MIN 2
#define VER_SUB 3
#define VER_BUILD 8
#define VER_FILEVERSION VER_MAJ,VER_MIN,VER_SUB,VER_BUILD
#define VER_FILEVERSION_STR ""VER_MAJ,VER_MIN,VER_SUB,VER_BUILD"\0"
// in my app file and product version are the same
#define VER_PRODUCTVERSION VER_MAJ,VER_MIN,VER_SUB,VER_BUILD
#define VER_PRODUCTVERSION_STR ""VER_MAJ,VER_MIN,VER_SUB,VER_BUILD"\0"
#define VER_COMPANYNAME_STR "MyCompany\0"
#define VER_LEGALCOPYRIGHT_STR "(c) 2020 "VER_COMPANYNAME_STR"\0"
And one specific file (which would re-appear for each module with different names and contents) SpecificVersion.rc:
/* Use the shared version info from a central file */
#include "SharedVersionDefs.rc"
#ifndef DEBUG
#define VER_DEBUG 0
#else
#define VER_DEBUG VS_FF_DEBUG
#endif
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_STR
VALUE "FileDescription", "Specific file description"
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "Specific internal name"
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "ProductName", "LCCAMQM"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
Just had to create these 2 files, set version info in the delphi dproj file to OFF, and then add the specific .rc file to the module's dproj where I want it to appear, in this case a minor delphi project:
program VersionInfoTest;
{$R 'SpecificVersion.res' 'SpecificVersion.rc'}
uses
Vcl.Forms,
uMain in 'uMain.pas' {frmMain},
uVerinfo in 'uVerinfo.pas';
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
end.
And I verified this worked.
ATTENTION: Due to RSP-13486 you are required to add the .rc file to the .dproj file as well. Just drag-and-drop in in there using the IDE.
More info regarding the .rc files and examples can be found on MSDN

Resource script with localized strings for brcc32

In a Delphi XE7 project for building an ocx I have an rc-file with Russian strings for the company name, file description etc. When I open the Properties window of the resulting ocx the Russian strings are not displayed correctly (there are strings of garbage characters due to an incorrect encoding). I have tried to convert the rc-file to Windows-1251, UTF-8 and UTF-16 encodings, then tried to specified the corresponding file encoding via the #pragma code_page directive in the rc-file, then removed #pragma and specified the encoding in the project in the section of the resource compiler. In all cases I changed the VALUE "Translation" string accordingly. Nothing of the above worked for me. What is the correct way of writing and compiling an rc-file in Delphi XE7 such that the localized strings appear correctly in the Properties window?
Note 1. I build the ocx on a build server which Delphi XE7 was simply copied to (and BDS* environment variables set manually) rather than properly installed from a distributable.
Note 2. For information my rc-file follows (the #pragma version for Windows-1251).
#pragma code_page(1251)
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
1 VERSIONINFO
FILEVERSION 2,0,0,0
PRODUCTVERSION 2,0,0,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
BLOCK "StringFileInfo"
{
BLOCK "041904E3"
{
VALUE "CompanyName", "ИмяКомпании\000"
VALUE "FileDescription", "ИмяМодуля\000"
VALUE "FileVersion", "2.0.0.0\000"
VALUE "InternalName", "Tools\000"
VALUE "LegalCopyright", "Copyright\251 2010-2014\000"
VALUE "LegalTrademarks", "\000"
VALUE "OriginalFilename", "Tools.ocx\000"
VALUE "ProductName", "ИмяПродукта\000"
VALUE "ProductVersion", "2.0.0.0\000"
VALUE "Comments", "No Comments\000"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 1049, 1251
}
}

Delphi 2010: Some of resourcestrings defined in.rc file are missing in resulting .exe

Some of resources from .RC file are not available in resulting .exe with the ID's given in .RC file.
I have and RC file with resourcestrings with id's 10000, 10100 etc. At some reason, when I load resource with id 10000 (LoadStr(10000)) it loads another string ('Invalid field type.' - which is declared in midas.rc from VCL and has the same id).
I assumed that resources with the same id should lead to "[Error] WARNING. Duplicate resource(s)" during the build. But there is no linker-related warnings.
p.s. I'm using Delphi 2010.
Update:
Workaround on that issue is to change id from 10000 to something else. 10050, e.g.
Question:
Why there's no warnings on duplicate resources?
What could be done to prevent that problem in future?
myproject.inc
const
offLanguages = 10000;
offCurrencies = 10100;
myproject.RC file
LANGUAGE LANG_LATVIAN, SUBLANG_NEUTRAL
#include "myproject.inc"
STRINGTABLE
{
offLanguages+0, "LV"
}
.. etc...
Rc file is compiled to myproject.res file. And the resulting .res files has correct string "LV" with ID 10000 (I checked that with resource editor).
In delphi coude resources are loaded in unit's initialization part, using LoadStr function.
likeThat.pas:
unit likeThat;
interface
{$I *.inc}
{$R *.res}
// skipped
initialization
Assert(LoadStr( offLanguages )= 'LV'); // <== fails here

brcc32 produces Corrupted .RES file

I am building Delphi Projects from the command line and am using brcc32.exe to build the .res files.
I have added a number of custom strings to my .RC so it looks like this. (There is a little Delphi5 app that prepares this .RC from a template)
1 VERSIONINFO
FILEVERSION 999,0,0,339
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904E4"
BEGIN
VALUE "FileDescription","Debug Build"
VALUE "FileVersion","999.0.0.339"
VALUE "LegalCopyright", "HuwCorp Finance Ltd"
VALUE "Revision","339"
VALUE "LastChangeRevision","335"
VALUE "LastChangeDate","2013-06-07"
VALUE "LastChangeTime","13:17:14"
VALUE "LastChangeAuthor","foo1234"
VALUE "BuildDate","12/06/2013"
VALUE "BuildTime","10:36:59"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 2057, 1252
END
END
All well and good so far, but the BRCC32 step produces a mangled .res file that looks like this (Viewed through a resource Builder)
VALUE "LastChangeDate", "2013-06-074\x08\x01LastChangeTime"
VALUE "LastChangeTime", "13:17:146\x07\x01LastChangeAuthor"
VALUE "LastChangeAuthor", "foo1234"
VALUE "BuildDate", "12/06/2013,\x08\x01BuildTime"
VALUE "BuildTime", "10:36:59D"
And indeed clicking properties/Version on the built .exe shows the garbage characters e.g. BuildTime is displayed as 10:36:59D
Can anyone suggest why ?
StringTable resources need to be C-style null-terminated (even when using the Borland Resource Compiler).
Try this instead:
VALUE "FileDescription","Debug Build\0"
VALUE "FileVersion","999.0.0.339\0"
VALUE "LegalCopyright", "HuwCorp Finance Ltd\0"
VALUE "Revision","339\0"
VALUE "LastChangeRevision","335\0"
VALUE "LastChangeDate","2013-06-07\0"
VALUE "LastChangeTime","13:17:14\0"
VALUE "LastChangeAuthor","foo1234\0"
VALUE "BuildDate","12/06/2013\0"
VALUE "BuildTime","10:36:59\0"

Delphi .res file changer

I'm looking for a ready-to-use piece of code that would be able to read and modify Delphi .res files. The thing is that I need to create an application that will be compiling many Delphi projects at once (using the dcc32.exe file). However, it is necessary for me to change file version and language before compilation, and as far as I know, I have to modify the .res file to do that.
Have you come across any code that would give me an interface to .res files allowing me to modify the data contained in it? The thing is that I want to change only those two pieces of information keeping the rest unchanged. This is why I can't compile my own .res file based on a script.
An application executed from a command line would also be OK if it allows to be called with parameters and does what I need it to do.
Thank you very in advance!
If all you need is to add file version resource then create appver.rc file, compile it with brcc32 and in one of your app unit (for example appver.pas) add {$R appver.res} (as Marian noticed you must turn off Delphi project option to include version info).
I created command line programs that increase build numbers in .rc file, create new branch/tag in SVN with new version in branch name, compiles .rc to .res, and build application.
My .rc files with such info (Polish language) looks like:
#define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO LOADONCALL MOVEABLE DISCARDABLE IMPURE
FILEVERSION 7,28,7,17
PRODUCTVERSION 7,28,7,17
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
{
BLOCK "StringFileInfo"
{
BLOCK "041504E2"
{
VALUE "CompanyName", "xxx\0"
VALUE "FileDescription", "yyy\0"
VALUE "ProductName", "zzz\0"
VALUE "FileVersion", "7.28.7.17\0"
VALUE "ProductVersion", "7.28.7.17\0"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0415, 1250
}
}
For all things .res, look at Colin Wilson's "XN Resource Editor", for which he provides the source code: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm
And probably all you need is his resource utility library:
http://www.wilsonc.demon.co.uk/d9resourceutils.htm
I haven't used this source, but if I needed it, that's the first place I'd look. His resource editor is very useful, btw.
There is ChangeRes which seems to match your needs.
Check out sources:
http://code.google.com/p/gedemin/source/browse/trunk#trunk/Gedemin/Utility/IncVerRC
It is our utility which reads .RC file with version information and increments build number. We use it inside our build process. Here is an excerpt:
incverrc.exe ..\gedemin\gedemin.rc
"%delphi_path%\brcc32.exe" -fogedemin.res -i..\images gedemin.rc
"%delphi_path%\dcc32.exe" -b gedemin.dpr
The utility uses TIncVerRc class written by Chris Morris.
Check Resource Tuner Console on www.heaventools.com. They position that product for tasks like yours. Also there's a free rcstamp tool on CodeProject.

Resources