Search code examples
delphiversiondelphi-7

Modify version information in EXE at compile time


My Delphi 7 application has Include version information in project selected in the Delphi IDE project properties. I would like to modify one of the version information fields (eg. InternalName) at compile time based on a define.

In the project properties, I've manually set InternalName to the string "Test". I then call this code:

function GetSpecificFileVersionInfo(szFile: PChar; strInfo: String) : String;
var
    pstrBuffer: PChar;
    dwSize, dwLength: DWORD;
    pVersion: pointer;
    strKey: String;
begin
    // Return the specified file version information
    // Adapted from: http://www.swissdelphicenter.com/en/showcode.php?id=1047
    Result := '';
    dwSize := GetFileVersionInfoSize(szFile, dwSize);
    if (dwSize > 0) then
        begin
        pstrBuffer := AllocMem(dwSize);
        try
            if (    (GetFileVersionInfo(szFile, 0, dwSize, pstrBuffer)) and
                    (VerQueryValue(pstrBuffer, '\VarFileInfo\Translation', pVersion, dwLength))) then
                begin
                strKey := Format('\StringFileInfo\%.4x%.4x\%s', [
                    LoWord(Integer(pVersion^)),
                    HiWord(Integer(pVersion^)), strInfo]);
                if (VerQueryValue(pstrBuffer, PChar(strKey), pVersion, dwLength)) then
                    Result := StrPas(pVersion);
                end;
        finally
            FreeMem(pstrBuffer, dwSize);
        end;
        end;
end;

with a call like strVersion := GetSpecificFileVersionInfo('MyEXE.exe', 'InternalName');

This returns "Test" as expected. All good so far. Now I create the following Version.rc file (in an attempt to change the value of InternalName):

// Version information resource file
VS_VERSION_INFO VERSIONINFO
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        // Note: Block "080904b0" was also tried with the same results
        BEGIN
            VALUE "InternalName", "Donkey"
        END
    END 
END

which is compiled (using the Microsoft Resource Compiler, rc.exe) into Version.res. This is then linked into the application at compile (based on my compile-flag), placed in the project .dpr file:

{$IFDEF ALT_LANG}
        {$R 'source\Version.res'}
{$ENDIF}

This all appears to compile correctly...but when I check the value of InternalName, it is still "Test" and not "Donkey" as expected.

What am I doing wrong? How do you change the version information using a compile-switch?


Solution

  • As stated by Remy Lebeau (and in the answer linked to by Ken White) version information should be included from only one source. This can either be manually entered in the project properties or by linking in a VERSIONINFO resource, but not both. If you try to do both you'll either get a conflict or the linked VERSIONINFO resource will delete the manually entered details.

    You cannot:

    • include manually entered version information in your project properties
    • and update part of the version information later (using a .rc file)

    Manually entered version information has limitations. The solution is to take full control of the version information to solve your problem. This answer and the one Ken linked to should provide enough information to get you started.