![]() |
32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Hallo Delphifreunde!
Zur Zeit beschäftige ich mich gerade damit, wie ein 32-Bit-Programm unter 32- und 64-Bit-Windows natürlich lauffähig sein soll und zusätzlich die Bitanzahl des OS selbständig erkennen kann. Bisherige Recherchen waren erfolglos. Also, sizeof(Pointer) fällt als Erkennungsmerkmal aus, weil das auch unter 64 Bit nur 4 liefert, wohl wegen des 32-Bit-Subsystems. Nun könnte man natürlich die IsWow64Process-Funktion benutzen, doch die ist in der 32-Bit-Version der kernel32.dll nicht enthalten, so daß das Programm an dieser Stelle mit einer Fehlermeldung abbricht ("Prozedureinsprungpunkt wurde .... nicht gefunden"). Fände man diese Funktion in besagter DLL, dann ist es ein 64-Bit-Windows, anderenfalls ein 32-Bit-Windows. Um den Programmabbruch abzufangen, versuchte ich es mit try...except...end, bekam es aber nicht - kann try solche Mißerfolge wie fehlende DLLs oder fehlende Funktionen in den DLLs nicht abfangen? Oder wie erreicht man das? Was ich nicht möchte: Mit OSVersionInfo "rumzumachen", um 32 von 64 Bit zu unterscheiden, weil das verdammt umständlich ist und künftige OS-Versionen logischerweise noch nicht berücksichtigen kann. Gibt es einen einfachen Weg? Natürlich kann man immer für beide Bitanzahlen zwei getrennte Programme erstellen, doch ist das vergleichsweise unelegant. Vielen Dank & viele Grüße Delphi-Laie |
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
IsWow64Process dynamisch einginden?
Wenn es dieses nicht gibt oder es False liefert, dann ist das Windows 32 Bit :zwinker: Zitat:
Darum auch WOW64 ... das ist ein 32-Bit-Subsystem (Windows on Windows aka Windows32 on Windows64), worin dein Win32-Programm ausgeführt wird. PS: In Win7 64 wurde das 16-Bit Subsystem entfernt, daum laufen dort auch keine 16 Bit Programme mehr ... soviel zu den Subsystemen, welche quasi "eigenständig" arbeiten ... dein Programm kommt also nicht direkt mit dem 64-Bit-System in Berührung. Und zu deinem Try-Except: Statische Bindungen werden zum Programmstart aufgelöst/hergestellt. Es kommt also niemals bis zum Try-Except, da es gleich zu Anfang knallt. (Es sei denn du hast es schon dynamisch eingebunden, aber "vergessen" die Rückgabewerte zu prüfen :stupid: ) Wozu mußt du das überhaupt wissen? |
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
Prüfe ob die Environment Variable %ProgramW6432% existiert (gibt es nur bei 64) bit. Und nein, es ist nicht unelegant 32- und 64-bit Programme zu trennen.
|
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
Kann ich denn mit einem 32Bit-Programm eine 64Bit-DLL laden, um die Existenz eben dieser Funktion zu ermitteln?
|
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
Oder vielleicht eine WMI Abfrage?
Unter Win32_ComputerSystem gibt es auch den Schlüssel SystemType... Gruß, Steku |
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
Zitat:
32 Bit kann nicht in 64 Bit und 64 Bit nicht in 32 Bit geladen werden. (die Unterschiedliche Speicherverwaltung macht das quasi Unmöglich) Genauso wie man nicht einfach eine .Net-DLL in einem Win32-Programm laden kann. Eine Ausnahme stellen OutOfProcess-Server (DLLs) und sogenannte "Brücken" dar. (im Code-Center von Emba liegt soeine Brücke rum, um eine 64-Bit-DLL indirekt in ein 32 Bit-Programm einzubinden) PS: Nein, wenn ich lustig bin, dann erstell ich mir ein meinem 32 Bit-Windows einfach eine Umgebungsvariable namens "ProgramW6432" und was ist dann? @DeddyH: Diese Funktion existiert in den 32-Bit-SystemDLLs und in den 64-Bit-SystemDLLs, seit WinXP SP2. Man kann sie also von überall aus aufrufen, auch von Win32-Programmen. |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
No offense meant, but himitsu hat mMn bereits die optimale Lösung genannt.
Das Environment ist "beliebig" (spätestens wenn das Programm von einem anderen ferngestartet wird, kann der ein beliebiges Environment übergeben oder auch mal aus Versehen ein leeres). Und WMI ist eine viel zu hohe Ebene, das kann aus diversen Gründen auch mal scheitern, während die Möglichkeit, DLLs dynamisch zu laden, so grundlegend ist, daß das System, wenn das nicht mehr ginge, eh nicht mehr laufen würde ;) |
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
Dank Euch, das sollte als erstes für weitere "Forschungen" reichen!
Zitat:
Definiert ist die Funktion im interface:
Delphi-Quellcode:
, und sie wird dann im Programm aufgerufen.
function IsWow64Process(hProcess:THandle;var Wow64Process:pbool):bool;stdcall;external kernel32 name 'IsWow64Process';
Zitat:
Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Gelöscht, war Quatsch.
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Das mit der Environment-Variable erschien mir schon optimal, aber dann wurde die Idee hier eingeworfen, sie selbst zu defnieren....
Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
VAR + BOOL (delphilike) oder PBOOL (WinAPI-vorgabe) Und das ist natürlich eine statiscjhe Bindung, welche vor WinXP SP2 überall knallen wird. Mit ![]() Und dann mit ![]() Statt LoadLibrary (hier FreeLibrary am Ende nicht vergessen) kann man auch ![]() Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Also diese:
Delphi-Quellcode:
Genau das haben wir ja schon gesagt: Dynamisch einbinden.
function 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; Aber ich würde sie umbenennen: Is32BitProcess bei IsWow64Process bekomme ich immer einen Knoten im Hirn. Ich muss dann immer überlegen was es eigentlich heißt. |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Und die Funktion muss ja im Gegensatz zur ersten Behauptung in beiden DLL-Versionen vorhanden sein:
- 32Bit-Exe: kann keine 64Bit-DLL laden und somit die Funktion gar nicht ermitteln -> sie wäre somit nutzlos - 64Bit-Exe: sobald sie läuft, ist das ja wohl automatisch ein 64Bit-OS :D |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Die 32 bit .exe lädt automatisch die 32 bit kernel32.dll, eine 64 bit .exe lädt automatisch die 64 bit kernel32.dll :)
Somit sähe das korrekt so aus: - 32Bit-Exe unter 32Bit-Win: lädt kernel32.dll(32Bit), findet dort kein IsWow64Process - also false. - 32Bit-Exe unter 64Bit-Win: lädt kernel32.dll(32Bit), findet dort IsWow64Process - also true. - 64Bit-Exe: lädt kernel32.dll(64bit), findet dort IsWow64Process, welches false zurückgeben dürfte. Ein Umbenennen in Is32BitProcess wäre etwas anderes (bzw. das kommt halt drauf an, wie man obige Situationen auswertet) - Is32BitProcess wäre für mich aber vermutlich sinnlos, weil ich das bereits zur Compile Time per Direktive regeln könnte. |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Ja eben, von daher stimmt die anfangs getroffene Behauptung, die Funktion gäbe es nur in der 64Bit-Version der DLL, nicht bzw. kann ja gar nicht stimmen.
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Das darf auch nicht knallen, weil die Funktion dort existieren sollte. (Bei mir jedenfalls ist die da.)
// EDIT: Nebenbei steht bei Microsoft explizit, dass man diese Funktion nicht statisch einbinden sollte. ;-) // EDIT2: Ok, ist bei mir auch SP3, das wurde im virtuellen PC doch schon automatisch aktualisiert. Aber grad nochmal zurückgesetzt, die Funktion ist auch mit SP1 dabei. |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
Zitat:
![]() (Es scheint keine Möglichkeit zu geben die Quelle direkt im Quote-Tag anzugeben... :shock:) |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
Für reine 64-Bit-Compilate halte ich das nicht für verkehrt, denn die müssen diese Funktion ja (vor)finden. Günstig ist die dynamische Einbindung natürlich, wenn man - einen (1) Quelltext für 32- und 64-Bit-Compilate ohne Compilerschalter (die die Lesbarkeit immer erschweren) - 32-Bit-Compilate haben möchte, die weder zum Programmabbruch führen noch diese Funktion ignorieren, wenn es sie denn gibt. haben möchte. Es gelang mir, an mein Ziel (Diskussionseröffnung) zu gelangen, besten Dank noch einmal an alle! Da auch Windows XP die IsWow64Process-Funktion bereitstellt, ist mir allerdings nicht ganz klar, inwieweit die verlinkte und hier veröffentlichte Funktion sicher zwischen 32- und 64-Bit-Windows unterscheiden kann. Ich werde mich noch damit beschäftigen. Dank und Gruß Delphi-Laie |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Hallo Delphi-Laie,
in diesem ![]() ![]() |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Für ein 32-Bit-Programm ist die hier verlinkte und auch hier veröffentlichte Funktion erschöpfend. Für einen allgemeingültigen Quelltext, nämlich einen, der 32- und 64-Bit-Compilate - möglichst ohne Compilerschalter - übersetzt, taugt sie jedoch nicht(s), denn ein 64-Bit-Programm wird sich nie in einer Wow64-Umgebung wiederfinden und mithin fälschlicherweise 32 Bit zurückmelden (bzw. genaugenommen die 64 Bit verneinen).
Wird von dem Programm vorher auf 64 Bit geprüft, so z.B. mit der Größe eines Pointers, müßte dieser Quelltext "bitanzahlübergreifend" funktionieren, denn ein 64-Bit-Programm wird dann die 64 Bit zurückliefern, anderenfalls geht es wie gewohnt weiter. Diese Prüfung kann vorangestellt werden und mithin vor dem Funktionsaufruf oder am Anfang derselben geschehen (Quellcode etwas vereinfacht und an das originale PBool angepaßt):
Delphi-Quellcode:
Die Exceptionmeldung ist n.m.B. nicht nötig und stört nur. Auch wenn der Funktionsaufruf "IsWow64Process" fehlschlägt, sind die Ergebnisse korrekt.
function Is64BitWin:Boolean;
var IsWow64Result:BOOL; IsWow64Process:function(Handle:THandle;var Res:PBOOL):BOOL;stdcall; begin if SizeOf(Pointer)>4 {=8?!} then begin result:=true; exit end else begin IsWow64Process:=GetProcAddress(GetModuleHandle('kernel32'),'IsWow64Process'); if Assigned(IsWow64Process) then begin if not IsWow64Process(GetCurrentProcess, IsWow64Result) then raise Exception.Create('Bad process handle'); Result:=Boolean(IsWow64Result) end else Result:=false end end; |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Irgendwie verstehe ich Dein Vorgehen nicht. Wenn ich ein Programm für 64Bit kompiliere, wozu brauche ich dann noch eine Abfrage ob mein Betriebssystem 32 oder 64 Bit ist. Ein 64Bit Programm greift auf die richtige Struktur zurück. Nur bei einem 32Bit Programm, welches auf einem 64Bit OS ausgeführt wird ist es wichtig auf die WOW6432Node - Registry Schlüssel zuzugreifen. Deshalb muss hier im Vordergrund eine Prüfung auf 32 oder 64 Bit stattfinden.
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
|
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
Delphi-Quellcode:
Wenn ich hier die IFDEF-Deklaration entferne, kann ich das Programm mit der USES-Klausel nur noch für MAC OSX kompilieren. Steht die IFDEF-Deklaration drin, kann ich es für 32/64Bit Windows und für Mac OSX kompilieren. Es ist eine Firemonkey-Anwendung.
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, {$IFDEF POSIX} Posix.SysTypes, Posix.Time, {$ENDIF} FMX.Layouts, FMX.Memo; Deshalb nochmal meine Frage, wozu brauche ich die IF-Abfrage auf den Pointer in der Procedure Is64BitWin ? Wenn ich das ganze über die Kompilerschalter regel habe ich es doch viel sauberer. |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Man kann diesen Code unabhängig für die Bitanzahl verwenden - er ist sozusagen bitanzahlneutral. Es ist ein gemeinsamer Code für beide Bitanzahlen. Mehr kann ich dazu wirklich nicht mehr sagen, zumal ich mich inzwischen wiederhole. Man muß es ja so nicht lösen, sondern es ist auch so möglich:
Zitat:
Insofern sollte mein Beispiel das eine/andere Ende der Fahnenstange aufzeigen - nicht mehr und nicht weniger. |
AW: 32-Bit-Programm soll 32- und 64-OS erkennen
Zitat:
![]() ![]() Warum schreibe ich das, weil die Information daß es nicht ginge nur die halbe Wahrheit (bis Unwahrheit) ist. Ich kann sogar ermitteln ob eine Funktion exportiert wird, aber mit dem Handle in dem Falle eventuell nicht mehr über ![]() Die Funktion existiert allerdings in der 32bit-Variante von kernel32.dll wenn ich mich recht entsinne. Und kernel32.dll ist in jedem Win32-Prozeß schon geladen bevor dein Haupthread startet. |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Moin Oliver,
schön, mal wieder etwas von Dir zu lesen. :-) Die Variante mit "Load_As_DataFile" ist mir bekannt, doch wie gehst Du denn mit den unterschiedlichen Calling-Conventions um, wenn Du eine DLL und die in ihr enthaltenen Funktionen tatsächlich nutzen willst? Ich hielt dies bisher für ein "No-Go" und hatte daher ebenfalls die Ansicht propagiert, dass eine normale 32bit-DLL mit Funktionen nicht im Rahmen einer 64bit-Anwendung zu nutzen sei (Ressourcen-DLLs ausdrücklich ausgenommen). |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
32 Bit-DLL in 64 Bit Programm zu nutztn, das soll gehn?
Der Code müßte doch in einer 32 Bit-Umgebung ausgeführt werden, oder täusche ich mich da? Gut, vieleicht könnte man da soeinen DLLHost als Zwischenschicht nutzen, aber eine Funktion direkt in der Anwendung auszuführen dürfte etwas schwer werden. :gruebel: |
AW: 32-Bit-Programm soll 32- und 64-Bit-OS erkennen
Zitat:
Es ging mir darum zu zeigen daß man auch bei einer 64bit-DLL ohne weiteres herausfinden kann ob eine Funktion existiert, siehe: Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz