Jump to content
direktor05

x32->x64

Recommended Posts

I'm getting a ton of issues converting from x32 to x64. First one:

 

var
  Size: Cardinal;
  Handle: Cardinal;
  FileName: String;
begin
  if ModuleName = '' then
    FileName := OAExeName
  else
    FileName := ModuleName;
  Size := GetFileVersionInfoSize(PWideChar(FileName), Handle);

 

Size returned is 0 and the error is:

 

VerQueryValue (Language in Project Settings/Version Info has to be set to English (United Kingdom))

 

var
  SubBlock: String;
  ValuePointer: Pointer;
  ValueLen: Cardinal;
begin
  SubBlock := '\StringFileInfo\080904E4\' + ValueName;
  TestGetLastError(VerQueryValue(@FBuffer[0], PWideChar(SubBlock), ValuePointer, ValueLen), 'VerQueryValue (Language in Project Settings/Version Info has to be set to English (United Kingdom))');
  Result := PChar(ValuePointer);

 

So what is wrong? I assume it's the variable (un)signed-ness again. GetFileVersionInfoSize(PWideChar(FileName), Handle) - Handle must be Cardinal according to API definition.

How can I fix this?

 

Another one is  array of Byte variable is causing AV error.

 

Share this post


Link to post

Make sure you have version info enabled for the x64 platform. There may be different settings for each platform.

Share this post


Link to post
3 minutes ago, FPiette said:

Try using THandle data type for all handles.

 

Except Windows documentation defines this lpdwHandle as LPDWORD, So THandle would be wrong.

Share this post


Link to post

Is this working? I have something like this in my code and is working for both x32 and x64.

var
  Size: DWORD;
  Handle: DWORD;
  FileName: String;
begin
  if ModuleName = '' then
    FileName := OAExeName
  else
    FileName := ModuleName;
  UniqueString(FileName);
  Size := GetFileVersionInfoSize(PChar(FileName), Handle); 

 

Share this post


Link to post

Actually this is what I have and is working x32 and x64.

procedure GetFileVersion(const AFileName: string; var V1, V2, V3, V4: Integer);
var
  FileName: string;
  InfoSize, Wnd: DWORD;
  VerBuf: Pointer;
  FI: PVSFixedFileInfo;
  VerSize: DWORD;
begin
  V1 := 0;
  V2 := 0;
  V3 := 0;
  V4 := 0;
  // GetFileVersionInfo modifies the filename parameter data while parsing.
  // Copy the string const into a local variable to create a writeable copy.
  FileName := AFileName;
  UniqueString(FileName);
  InfoSize := GetFileVersionInfoSize(PChar(FileName), Wnd);
  if InfoSize <> 0 then
  begin
    GetMem(VerBuf, InfoSize);
    try
      if GetFileVersionInfo(PChar(FileName), Wnd, InfoSize, VerBuf) then
        if VerQueryValue(VerBuf, PathDelim, Pointer(FI), VerSize) then begin
          V1 := FI.dwFileVersionMS shr 16;
          V2 := FI.dwFileVersionMS and $FFFF;
          V3 := FI.dwFileVersionLS shr 16;
          V4 := FI.dwFileVersionLS and $FFFF;
        end;
    finally
      FreeMem(VerBuf);
    end;
  end;
end;

 

Share this post


Link to post

Try this function GetVersionInformation():

{$WARNINGS OFF}

function LinkerTimeStamp(const AFileName: string): TDateTime;
var
  LI: TLoadedImage;
  m: TMarshaller;
  timeStamp: Int64;
  utcTime: TDateTime;
begin
  Win32Check(MapAndLoad(PAnsiChar(m.AsAnsi(ParamStr(0)).ToPointer), nil, @LI,
    False, True));
  timeStamp := LI.FileHeader.FileHeader.TimeDateStamp;
  UnMapAndLoad(@LI);
  utcTime := System.DateUtils.UnixToDateTime(timeStamp);
  Result := TTimeZone.local.ToLocalTime(utcTime);
end;
{$WARNINGS ON}

function GetVersionInformation(): string;
const
  lastCompileStr: string = 'Last Compile';
  cnPackLastCompileStr: string = 'LastCompiledTime';
  bitStr: string = '; %d bit';
  verInfoStr: string = '%d.%d.%d.%d';
var
  VerInfo: TVerInfo; //class from unit UVerInfoClass.pas
  myFileName: string;
  myResultStr: string;
  verBitStr: string;
  FFI: WinApi.Windows.TVSFixedFileInfo;
  myCompiledTime: TDateTime;
  Fmt: TFormatSettings;
begin
  Result := '';
  myFileName := Application.ExeName;
  VerInfo := TVerInfo.Create(myFileName);
  try
    if VerInfo.HasVerInfo then
    begin
      myResultStr := ' ver.';
      {get version info}
      FFI := VerInfo.FixedFileInfo;
      myResultStr := myResultStr + Format(verInfoStr,
        [HiWord(FFI.dwFileVersionMS), LoWord(FFI.dwFileVersionMS),
        HiWord(FFI.dwFileVersionLS), LoWord(FFI.dwFileVersionLS)]);
      //add bit version
      {$IFDEF WIN32}
      verBitStr := Format(bitStr, [32]);
      {$ENDIF}
      {$IFDEF WIN64}
      verBitStr := Format(bitStr, [64]);
      {$ENDIF}
      myResultStr := myResultStr + verBitStr;
      //get date of last compilation
      if (VerInfo.TranslationCount > 0) then
      begin
        myCompiledTime := LinkerTimeStamp(myFileName);
        if (myCompiledTime <= Now) then
        begin
          Fmt.ShortDateFormat := 'dd.mm.yyyy';
          Fmt.DateSeparator := '.';
          Fmt.LongTimeFormat := 'hh:nn';
          Fmt.TimeSeparator := ':';
          myResultStr := myResultStr + compiledStr +
            DateTimeToStr(myCompiledTime, Fmt);

        end;
        Result := myResultStr;
      end;
    end;
  finally
    VerInfo.Free;
  end; {try}
end;

 

Share this post


Link to post
11 minutes ago, Jirka52 said:

VerInfo: TVerInfo; //class from unit UVerInfoClass.pas

From where is this unit UVerInfoClass?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×