Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 126632f

Browse files
committed
Isx64 added (checking the platform of a dll)
PythonVersionFromPath added
1 parent c73cb71 commit 126632f

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

PythonForDelphi/Components/Sources/Core/PythonVersions.pas

+93-1
Original file line numberDiff line numberDiff line change
@@ -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

7073
implementation
@@ -217,6 +220,27 @@ function CompareVersions(A, B : String) : Integer;
217220
end;
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+
220244
function 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;
275299
var
276300
key: string;
277301
VersionSuffix: string;
302+
APythonVersion: TPythonVersion;
278303
begin
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;
307339
end;
308340

@@ -334,7 +366,67 @@ function GetLatestRegisteredPythonVersion(out PythonVersion: TPythonVersion): Bo
334366
end;
335367
end;
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

340432
end.

0 commit comments

Comments
 (0)