Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Pfad prüfen - 32/64bit DLL (https://www.delphipraxis.net/196287-pfad-pruefen-32-64bit-dll.html)

Alex_ITA01 7. Mai 2018 15:47

Pfad prüfen - 32/64bit DLL
 
Hallo zusammen,
ich möchte dynamisch eine DLL laden und kenne nur deren Name.
Es gibt für diese DLL eine 32bit Variante und die liegt im PfadA und es gibt eine 64bit Variante die liegt im PfadB.
PfadA und PfadB sind in der Umgebungsvariable "Path" beide eingetragen.
Die Umgebungsvariable Path auslesen geht wie folgt:

Delphi-Quellcode:
GetEnvironmentVariable('Path')
Jetzt möchte ich mit FileExists prüfen, ob die passende DLL überhaupt vorhanden ist, je nach Compilat (32bit/64bit).
Gibt es eine einfache Möglichkeit das Ergebnis von GetEnvironmentVariable abzugrasen und jeden Ordner mit dem DLL Namen auf FileExists abzufragen oder muss ich mir den langen String zerlegen und dann jeden Ordner separat prüfen?

Ich hoffe ihr könnt mir da weiterhelfen.

TiGü 7. Mai 2018 16:07

AW: Pfad prüfen - 32/64bit DLL
 
Zitat:

Zitat von Alex_ITA01 (Beitrag 1401554)
...muss ich mir den langen String zerlegen und dann jeden Ordner separat prüfen?

Ja, aber das ist ja nun mit einer TStringList ein Vierzeiler. Du weißt wie?

Uwe Raabe 7. Mai 2018 17:27

AW: Pfad prüfen - 32/64bit DLL
 
Das geht auch recht einfach mit der Split-Funktion:
Delphi-Quellcode:
function FindFileInPathList(const PathList, DllName: string): string;
var
  S: string;
begin
  for S in PathList.Split(';') do begin
    Result := TPath.Combine(S, dllName);
    if TFile.Exists(Result) then Exit;
  end;
  Result := '';
end;

KodeZwerg 7. Mai 2018 17:46

AW: Pfad prüfen - 32/64bit DLL
 
Alternativ:
I.d.R. hat man zwei verschiedene Environment Variablen zur Verfügung, Beispiel %ProgramFiles% und %ProgramFiles(x86)%, öffne ein Kommandprompt und tippe "SET" ein + Return drücken, da werden dir alle aufgelistet, nun such Dir eine Variable aus die es auch mit (x86) gibt und kopiere dort deine dll rein, also in (x86) die 32bit usw. Dann kannst Du in Deinem Programm wie gewünscht darauf zugreifen.

Achja, generell kann man auch System32 und SysWOW64 verzeichnisse benutzen, in letzteres kommt die 32bit dll rein.
Wenn Du LoadLibrary() aufrufst wählt Windows automatisch die Richtige, ohne Pfadangabe.
Diese Funktion hier kannst Du benutzen um aus ExpandFileName('Library.dll') = 'X:\PFAD\Library.dll' zu machen (sofern Library.dll irgendwo findbar ist)
Delphi-Quellcode:
//function GetFullPathName(lpFileName: PChar; nBufferLength: DWORD; lpBuffer: PChar; var lpFilePart: PChar): DWORD; stdcall;
//function GetFullPathName; external kernel32 name 'GetFullPathNameA';
function ExpandFileName(const FileName: string): string;
var
  FName: PChar;
  Buffer: array[0..MAX_PATH - 1] of Char;
begin
  SetString(Result, Buffer, GetFullPathName(PChar(FileName), SizeOf(Buffer), Buffer, FName));
end;
ACHTUNG!!!!
Unbedingt vorher in Deiner Windows.pas Datei gucken ob der
Delphi-Quellcode:
function GetFullPathName(lpFileName: PChar; nBufferLength: DWORD; lpBuffer: PChar; var lpFilePart: PChar): DWORD; stdcall;
Aufruf so definiert ist, ansonsten meinen Source anpassen!!!

PS: Diese Funktion liefert so wie sie da steht nur den ersten Treffer wieder, mehr zeigt sie nicht.
Du kannst sie einfach umprogrammieren um eine TStringList o.ä. als Result zu erhalten wo alle Treffer auf den Suchbegriff drinnen stehen, falls Du da Hilfe brauchst sag Bescheid.

KodeZwerg 7. Mai 2018 18:36

AW: Pfad prüfen - 32/64bit DLL
 
Hats geklappt?

edit
Vielleicht wäre es Sinnvoller seine Dlls umzubenennen um es dann vom OSVersion 32/64 abhängig zu machen?
Also xyz32.dll und xyz64.dll, beide in ein Verzeichnis, und per OS Abfrage die entsprechende laden lassen und später auch wieder freigeben, die Eigentlichen dll calls sollten ja gleich sein.
Ps: Bei dieser Methode, so glaube ich, sollte auch so etwas möglich sein - pseudo code
Delphi-Quellcode:
//da wo code initialisiert wird so etwas einfügen
if osversion = 64bit then {$define x64} else {$define x32}

//überall wo benötigt über ifdefs gehen, so in etwa
{$ifdef x32}
// 32bit code hier einfügen
{$endif}
{$ifdef x64}
// 64bit code hier einfügen
{$endif}
edit
nicht osversion, sowas hier meinte ich
Delphi-Quellcode:
class function TOSInfo.IsWOW64: Boolean;
type
  TIsWow64Process = function( // Type of IsWow64Process API fn
    Handle: THandle;
    var Res: BOOL
  ): BOOL; stdcall;
var
  IsWow64Result: BOOL;             // result from IsWow64Process
  IsWow64Process: TIsWow64Process; // IsWow64Process fn reference
begin
  // Try to load required function from kernel32
  IsWow64Process := GetProcAddress(
    GetModuleHandle('kernel32'), 'IsWow64Process'
  );
  if Assigned(IsWow64Process) then
  begin
    // Function is implemented: call it
    if not IsWow64Process(GetCurrentProcess, IsWow64Result) then
      raise Exception.Create('Bad process handle');
    // Return result of function
    Result := IsWow64Result;
  end
  else
    // Function not implemented: can't be running on Wow64
    Result := False;
end;
damit ermitteln ob man im 64bit modus ist und dementsprechend die {$Define} parameter setzen.

Alex_ITA01 7. Mai 2018 20:01

AW: Pfad prüfen - 32/64bit DLL
 
Danke, das hilft. Teste ich morgen früh gleich mal.

Ich hätte es mit der StringList so gelöst:

Delphi-Quellcode:
  sl := TStringlist.Create;
  try
    sl.Delimiter := ';';
    sl.StrictDelimiter := True;
    sl.DelimitedText := GetEnvironmentVariable('Path');

    for I := 0 to sl.Count -1 do
    begin
      //Pfad prüfen
    end;
  finally
    sl.clear;
    FreeAndNIL(SL);
  end;

Dalai 7. Mai 2018 22:52

AW: Pfad prüfen - 32/64bit DLL
 
Ähm, es gibt auch MSDN-Library durchsuchenPathFindOnPath, das die ganze Arbeit erledigt, die Verzeichnisse des %PATH% zu durchsuchen. Name der DLL übergeben und Rückgabe (bzw. den ersten Parameter) auswerten. Meine Wrapper-Funktion dafür:
Delphi-Quellcode:
function _PathFindOnPath(const AFile: string): string;
var LFile: array[0..MAX_PATH] of Char;
begin
    Result:= AFile;
    FillChar(LFile, SizeOf(LFile), #0);
    StrLCopy(LFile, PChar(AFile), MAX_PATH);
    if PathFindOnPath(LFile, nil) then
        Result:= StrPas(LFile);
end;
Grüße
Dalai

Alex_ITA01 8. Mai 2018 06:39

AW: Pfad prüfen - 32/64bit DLL
 
Danke Dalai, kannte ich auch noch nicht ;-)

CCRDude 8. Mai 2018 07:04

AW: Pfad prüfen - 32/64bit DLL
 
DLLs im System32-Verzeichnis halte ich für eine ganz schlechte Idee, spätestens wenn verschiedene Programmversionen verschiedene DLL-Versionen benötigen, fliegt einem das um die Ohren.

DLLs irgendwo im Pfad abzulegen sollte man eigentlich auch nicht mehr machen, bietet das doch einen guten Angriffsvektor für DLL injection, denn der Pfad aus dem Environment liegt an allerletzter Stelle, an der Windows schaut. Da würde ich das Konzept überdenken :)

Siehe auch SafeDllSearchMode. Wenn man die DLLs nicht im Programmverzeichnis ablegen kann, weil 32- und 64-bit Executables dort liegen, kann man auf SetDllDirectory zurückgreifen.

Alex_ITA01 8. Mai 2018 07:36

AW: Pfad prüfen - 32/64bit DLL
 
Den Pfad der DLLs kann ich nicht ändern, diese werden durch eine Fremdanbieter-Software installiert und liegen da wo sie liegen.
Es wird nur entsprechend die %PATH% Variable durch die Fremdanbieter-Software angepasst, sodass ich bei 32 und 64bit jeweils die richtige DLL finde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:46 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz