@@ -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' 
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} ' \' then  Exit;
412+   except 
413+     Exit;
414+   end ;
415+   PythonVersion.DLLPath := DLLPath;
338416
417+   SysVersion := Copy(DLLFileName, 7 , 2 );
418+   Insert(' .' 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