direktor05 2 Posted Wednesday at 11:41 AM 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
FPiette 379 Posted Wednesday at 12:25 PM Try using THandle data type for all handles. Share this post Link to post
direktor05 2 Posted Wednesday at 12:26 PM The error I get is 1813 - resource not found Share this post Link to post
Uwe Raabe 2029 Posted Wednesday at 12:31 PM 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
Virgo 18 Posted Wednesday at 12:32 PM 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
Cristian Peța 103 Posted Wednesday at 12:59 PM 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
Cristian Peța 103 Posted Wednesday at 01:05 PM 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
Davide Angeli 44 Posted Wednesday at 02:34 PM To get that kind of info from a file I use the JCL class TJvVersionInfo (https://github.com/project-jedi/jvcl/blob/master/jvcl/run/JvVersionInfo.pas) that is a wrapper of that kind API. For me it works both 32 and 64 bit. Share this post Link to post
Jirka52 2 Posted 18 hours ago 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
Cristian Peța 103 Posted 18 hours ago 11 minutes ago, Jirka52 said: VerInfo: TVerInfo; //class from unit UVerInfoClass.pas From where is this unit UVerInfoClass? Share this post Link to post