@@ -58,13 +58,16 @@ TPythonVersion = record
5858
5959
6060 { $IFDEF MSWINDOWS}
61+ (* Checks whether a DLL was compiled for X64 *)
62+ function Isx64 (const FileName: string): Boolean;
6163 (* Checks whether a Python version is registered and returns the related info *)
6264 function GetRegisteredPythonVersion (SysVersion: string;
6365 out PythonVersion: TPythonVersion): Boolean;
6466 (* Returns all registered Python versions *)
6567 function GetRegisteredPythonVersions : TPythonVersions;
6668 (* Returns the highest numbered registered Python version *)
6769 function GetLatestRegisteredPythonVersion (out PythonVersion: TPythonVersion): Boolean;
70+ function PythonVersionFromPath (const Path: string; out PythonVersion: TPythonVersion): Boolean;
6871 { $ENDIF}
6972
7073implementation
@@ -217,6 +220,27 @@ function CompareVersions(A, B : String) : Integer;
217220end ;
218221
219222{ $IFDEF MSWINDOWS}
223+ function Isx64 (const FileName: string): Boolean;
224+ var
225+ Strm : TFileStream;
226+ Header: TImageDosHeader;
227+ ImageNtHeaders: TImageNtHeaders;
228+ begin
229+ Strm := TFileStream.Create(FileName, fmOpenRead);
230+ try
231+ Strm.ReadBuffer(Header, SizeOf(Header));
232+ if (Header.e_magic <> IMAGE_DOS_SIGNATURE) or (Header._lfanew = 0 ) then
233+ Exit(False);
234+ Strm.Position := Header._lfanew;
235+ Strm.ReadBuffer(ImageNtHeaders, SizeOf(ImageNtHeaders));
236+ if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
237+ Exit(False);
238+ Result := ImageNtHeaders.FileHeader.Machine <> IMAGE_FILE_MACHINE_I386;
239+ finally
240+ Strm.Free;
241+ end ;
242+ end ;
243+
220244function GetRegisteredPythonVersion (SysVersion: string;
221245 out PythonVersion: TPythonVersion): Boolean;
222246 // Python provides for All user and Current user installations
@@ -275,6 +299,7 @@ function GetRegisteredPythonVersion(SysVersion: string;
275299var
276300 key: string;
277301 VersionSuffix: string;
302+ APythonVersion: TPythonVersion;
278303begin
279304 // Initialize PythohVersion
280305 Finalize(PythonVersion);
@@ -303,6 +328,13 @@ function GetRegisteredPythonVersion(SysVersion: string;
303328 PythonVersion.fSysArchitecture := PythonVersion.ExpectedArchitecture;
304329 end ;
305330
331+ if Result and (PythonVersion.fSysArchitecture = ' ' ) then begin
332+ // We need to check it is the proper platform
333+ Result := PythonVersionFromPath(PythonVersion.InstallPath, APythonVersion);
334+ if Result then
335+ PythonVersion.fSysArchitecture := PythonVersion.ExpectedArchitecture;
336+ end ;
337+
306338 PythonVersion.IsRegistered := Result;
307339end ;
308340
@@ -334,7 +366,67 @@ function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion): Bo
334366 end ;
335367end ;
336368
337- { $ENDIF}
369+ function PythonVersionFromPath (const Path: string; out PythonVersion: TPythonVersion): Boolean;
370+ function FindPythonDLL (APath : string): string;
371+ Var
372+ FindFileData: TWIN32FindData;
373+ Handle : THandle;
374+ DLLFileName: string;
375+ begin
376+ Result := ' ' ;
377+ Handle := FindFirstFile(PWideChar(Path+' \python??.dll' ), FindFileData);
378+ if Handle = INVALID_HANDLE_VALUE then Exit; // not python dll
379+ DLLFileName:= FindFileData.cFileName;
380+ // skip if python3.dll was found
381+ if Length(DLLFileName) <> 12 then FindNextFile(Handle, FindFileData);
382+ if Handle = INVALID_HANDLE_VALUE then Exit;
383+ Windows.FindClose(Handle);
384+ DLLFileName:= FindFileData.cFileName;
385+ if Length(DLLFileName) = 12 then
386+ Result := DLLFileName;
387+ end ;
388+
389+ Var
390+ DLLFileName: string;
391+ DLLPath: string;
392+ SysVersion: string;
393+ I: integer;
394+ begin
395+ Result := False;
396+ Finalize(PythonVersion);
397+ FillChar(PythonVersion, SizeOf(TPythonVersion), 0 );
398+ DLLPath := ExcludeTrailingPathDelimiter(Path);
399+
400+ PythonVersion.InstallPath := DLLPath;
401+
402+ DLLFileName := FindPythonDLL(DLLPath);
403+ if DLLFileName = ' ' then begin
404+ DLLPath := DLLPath + ' \Scripts' ;
405+ DLLFileName := FindPythonDLL(DLLPath);
406+ end ;
407+ if DLLFileName = ' ' then Exit;
408+
409+ // check if same platform
410+ try
411+ if { $IFDEF CPUX64} not { $ENDIF} Isx64(DLLPath+' \' +DLLFileName) then Exit;
412+ except
413+ Exit;
414+ end ;
415+ PythonVersion.DLLPath := DLLPath;
338416
417+ SysVersion := Copy(DLLFileName, 7 , 2 );
418+ Insert(' .' , SysVersion, 2 );
419+
420+ PythonVersion.SysVersion := SysVersion;
421+ PythonVersion.fSysArchitecture := PythonVersion.ExpectedArchitecture;
422+
423+ for I := High(PYTHON_KNOWN_VERSIONS) downto COMPILED_FOR_PYTHON_VERSION_INDEX do
424+ if PYTHON_KNOWN_VERSIONS[I].RegVersion = SysVersion then begin
425+ Result := True;
426+ break;
427+ end ;
428+ end ;
429+
430+ { $ENDIF}
339431
340432end .
0 commit comments