Entwickler-Ecke

Windows API - Wie ermitteln ob 32bit oder 64bit System?


del1312 - Mi 26.05.10 18:46
Titel: Wie ermitteln ob 32bit oder 64bit System?
Nabend Leute,

kann mir bitte einer helfen und sagen, wie ich per Abfrage rausbekomme ob der aktuelle Rechner nen 64 bzw 32 bit System ist? Schreib grad nen kleines Prog, was unter WinXP32, WinXP64 und Win764 laufen soll und dafür muss mein kl. Prog wissen, auf was für ne Kiste es läuft damit z. B. der richtige Programm-Order gefunden wird. Wie kann ich das das schnell abfragen? DANKE!

Moderiert von user profile iconGausi: Topic aus Off Topic verschoben am Mi 26.05.2010 um 19:19
Moderiert von user profile iconNarses: Überflüssige Zeilenumbrüche/Leerzeilen entfernt.


elundril - Mi 26.05.10 18:50

ich denke das hier [http://www.delphidabbler.com/articles?article=23&part=5] kann dir weiterhelfen.

lg elundril


Ralf Jansen - Mi 26.05.10 18:52

In managed Code über die 'Environment.Is64BitOperatingSystem' Funktion. In unmanaged Code über die 'IsWow64Process' Windows API Methode.


jaenicke - Mi 26.05.10 20:29

user profile icondel1312 hat folgendes geschrieben Zum zitierten Posting springen:
dafür muss mein kl. Prog wissen, auf was für ne Kiste es läuft damit z. B. der richtige Programm-Order
gefunden wird.
Wie man diese Pfade bekommt habe ich hier geschrieben:
http://www.delphi-forum.de/viewtopic.php?p=605453#605453


fuba - So 01.08.10 15:50

ich nutze immer diese function:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function IsWow64: Boolean;
type
  TIsWow64Process = function// Type of IsWow64Process API fn
    Handle: Windows.THandle; var Res: Windows.BOOL
  ): Windows.BOOL; stdcall;
var
  IsWow64Result: Windows.BOOL;      // Result from IsWow64Process
  IsWow64Process: TIsWow64Process;  // IsWow64Process fn reference
begin
  // Try to load required function from kernel32
  IsWow64Process := Windows.GetProcAddress(
    Windows.GetModuleHandle('kernel32'), 'IsWow64Process'
  );
  if Assigned(IsWow64Process) then
  begin
    // Function is implemented: call it
    if not IsWow64Process(
      Windows.GetCurrentProcess, IsWow64Result
    ) then
      raise SysUtils.Exception.Create('IsWow64: bad process handle');
    // Return result of function
    Result := IsWow64Result;
  end
  else
    // Function not implemented: can't be running on Wow64
    Result := False;
end;


elundril - So 01.08.10 21:39

user profile iconfuba hat folgendes geschrieben Zum zitierten Posting springen:
ich nutze immer diese function:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function IsWow64: Boolean;
type
  TIsWow64Process = function// Type of IsWow64Process API fn
    Handle: Windows.THandle; var Res: Windows.BOOL
  ): Windows.BOOL; stdcall;
var
  IsWow64Result: Windows.BOOL;      // Result from IsWow64Process
  IsWow64Process: TIsWow64Process;  // IsWow64Process fn reference
begin
  // Try to load required function from kernel32
  IsWow64Process := Windows.GetProcAddress(
    Windows.GetModuleHandle('kernel32'), 'IsWow64Process'
  );
  if Assigned(IsWow64Process) then
  begin
    // Function is implemented: call it
    if not IsWow64Process(
      Windows.GetCurrentProcess, IsWow64Result
    ) then
      raise SysUtils.Exception.Create('IsWow64: bad process handle');
    // Return result of function
    Result := IsWow64Result;
  end
  else
    // Function not implemented: can't be running on Wow64
    Result := False;
end;


dürften wir die gleiche Quelle zitieren, dein Code ist exakt der gleiche wie der im Listing 31 aus meinem Link. ;)

lg elundril


Hendi48 - Do 05.08.10 20:19

Ehm, wie soll diese Funktion denn bitte funktionieren? Die prüft ob der aktuelle Prozess ein 64-Bit Prozess ist, was nie so sein wird, da Delphi (noch) keine 64-Bit Programme kompilieren kann. Wird also IMMER False ergeben, auch auf 64-Bit Systemen.

Kennt jemand eine andere Methode um das herauszufinden?


Hidden - Do 05.08.10 20:22

Tja, der vorhersehende Programmierer baut halt jetzt schonmal seinen Code so, dass er auch noch funtioniert, wenn Delphi auf x64 umstellt :mrgreen:

Imho sollte der Code oben aber zusätzlich eine Exception werfen, wenn die Funktion nicht implementiert ist. :)

lg,


Hendi48 - Do 05.08.10 20:28

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Die Funktion kann man Afaik auch mit einem 32-bit-Programm aufrufen. ;) Eventuell sogar auf nem 32-Bit-Rechner, nur ob was sinnvolles dabei rauskommt bleibt offen.

Nein. Sie ergibt in dieser Form immer False, egal auf welchem Betriebssystem, da GetCurrentProcess ein 32-Bit Programm ist.


jaenicke - Do 05.08.10 20:40

user profile iconHendi48 hat folgendes geschrieben Zum zitierten Posting springen:
Ehm, wie soll diese Funktion denn bitte funktionieren? Die prüft ob der aktuelle Prozess ein 64-Bit Prozess ist
Falsch... :roll:

user profile iconHendi48 hat folgendes geschrieben Zum zitierten Posting springen:
da GetCurrentProcess ein 32-Bit Programm ist.
Darum geht es ja auch.

Die Funktion heißt IsWow64Process, nicht Is64BitProcess oder sowas...
Wow64 ist die Emulation für 32-Bit Programme unter 64-Bit Windows Systemen. Wenn also das Programm als Wow64 Prozess läuft, dann wird es gerade unter einem 64-Bit System emuliert ausgeführt.

Die Funktion macht also genau das was hier gefragt ist.


Delete - Fr 06.08.10 15:12

Alternative:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
function GetNativeSystemInfo(var SystemInfo: TSystemInfo): Boolean;
type
  TGetNativeSystemInfo = procedure (var SystemInfo: TSystemInfo) stdcall;
var
  LibraryHandle: HMODULE;
  _GetNativeSystemInfo: TGetNativeSystemInfo;
begin
  Result := False;
  LibraryHandle := GetModuleHandle(kernel32);

  if LibraryHandle <> 0 then
  begin
    _GetNativeSystemInfo := GetProcAddress(LibraryHandle,'GetNativeSystemInfo');
    if Assigned(_GetNativeSystemInfo) then
    begin
      _GetNativeSystemInfo(SystemInfo);
      Result := True;
    end
    else
      GetSystemInfo(SystemInfo);
  end
  else
    GetSystemInfo(SystemInfo);
end;

function IsWindows64: Boolean;
var
  ASystemInfo: TSystemInfo;
const
  PROCESSOR_ARCHITECTURE_INTEL = 0;
  PROCESSOR_ARCHITECTURE_IA64 = 6;
  PROCESSOR_ARCHITECTURE_AMD64 = 9;
begin
  GetNativeSystemInfo(ASystemInfo);
  Result := ASystemInfo.wProcessorArchitecture in [PROCESSOR_ARCHITECTURE_IA64,PROCESSOR_ARCHITECTURE_AMD64];
end;


Roy - Sa 13.09.14 16:25

Wie Frage ich denn nun diese Funktion ab?
Mit einer Procedur?

Bsp. Timer und Editfeld ??

Gruß Roy


jaenicke - Sa 13.09.14 21:46

Du rufst die Funktion auf. Von wo aus hängt doch davon ab wo du diese Information brauchst und nicht von der Funktion. :gruebel:

Ein Timer macht keinen Sinn, da sich diese Information ja während der Laufzeit des Programms nicht ändert. Wenn du diese Information in einem Timerevent benötigst, kannst du sie ja beim Programmstart abfragen und speichern.


Roy - Sa 13.09.14 23:04

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Ein Timer macht keinen Sinn, da sich diese Information ja während der Laufzeit des Programms nicht ändert. Wenn du diese Information in einem Timerevent benötigst, kannst du sie ja beim Programmstart abfragen und speichern.

Ja eben, es änderet sich ja nichts. Möchte nur in einem Edit oder Textfeld die aktuelle Version x86 oder x64 anzeigen lassen.
Speichern will ich garnichts!

Genau so wie abfrage: GetProzessorname


jaenicke - So 14.09.14 07:45

Dann rufst du die Funktion am besten in FormCreate, also im OnCreate des Formulars, auf, aber wenn du GetProzessorname bereits benutzt, scheint das ja gar nicht das Problem zu sein. Aber wo ist denn dann dein Problem?
Funktioniert der Aufruf nicht? Stört dich, dass der Rückgabewert Boolean ist? ...

Wenn du nicht damit herausrückst wo eigentlich dein Problem ist, weiß ich auch nicht wie wir dir helfen können...


Delphi-Laie - So 14.09.14 13:10

Einfach die Größe eines Pointers ermitteln (SizeOf(Pointer)). Dieser ist unter 32 Bit 4, unter 64 Bit 8 Byte groß.


Stundenplan - So 14.09.14 13:56

Das mit SizeOf(Pointer) funktioniert (zumindest bei meinem D7) nicht, da AFAIR die Pointergröße beim Kompilieren hardkodiert wird. (Ein auf einem 32bit-System kompiliertes Testprogrämmchen liefert auf einem 64bit-System immer noch 4. ;-))


jaenicke - So 14.09.14 14:11

Richtig, die Größe des Pointers hat nichts mit dem System zu tun, sondern mit dem kompilierten Code des Programms. Der wiederum ändert sich logischerweise nicht je nachdem auf welchem System er läuft.


Delphi-Laie - So 14.09.14 14:44

Ja natürlich, ich bitte um Entschuldigung!

Allerdings frage ich mich, wie man überhaupt ermitteln kann, ob ein 64-Bit-Computer existiert, wenn nur ein 32-Bit-Betriebsprogramm darauf installiert ist. Es wurde in der Eingangsfrage ja das Wort "Rechner" benutzt, nicht etwa "Betriebssystem". Vermutlich können das Hardwarediagnoseprogramme.


WasWeißDennIch - So 14.09.14 18:02

Der Typ der CPU ist zwar für das im Ausgangspost geschilderte Problem irrelevant, aber man könnte ihn z.B. mittels WMI ermitteln. Das folgende Programm wurde mit dem WMI Delphi Code Creator erstellt und nur leicht erweitert (Angabe des Prozessortyps):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
//-----------------------------------------------------------------------------------------------------
//     This code was generated by the Wmi Delphi Code Creator (WDCC) Version 1.8.5.0
//     http://code.google.com/p/wmi-delphi-code-creator/
//     Blog http://theroadtodelphi.wordpress.com/wmi-delphi-code-creator/
//     Author Rodrigo Ruz V. (RRUZ) Copyright (C) 2011-2014 
//----------------------------------------------------------------------------------------------------- 
//
//     LIABILITY DISCLAIMER
//     THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.
//     YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS,
//     DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE.
//
//----------------------------------------------------------------------------------------------------
program GetWMI_Info;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;
  
function ProcessorTypeAsString(ProcessorType: integer): string;
begin
  case ProcessorType of
    0:
      Result := 'x86';
    1:
      Result := 'MIPS';
    2:
      Result := 'Alpha';
    3:
      Result := 'PowerPC';
    5:
      Result := 'ARM';
    6:
      Result := 'Itanium-based systems';
    9:
      Result := 'x64';
    else
      Result := 'unknown';
  end;
end;
    
// Die Klasse "Win32_Processor" stellt eine Gerät zum Übersetzen von sequentiellen 
// Computeranweisungen in einem Win32-Computersystem dar. Für jeden Prozessor ist 
// eine Instanz dieser Klasse vorhanden.

procedure  GetWin32_ProcessorInfo;
const
  WbemUser            ='';
  WbemPassword        ='';
  WbemComputer        ='localhost';
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer(WbemComputer, 'root\CIMV2', WbemUser, WbemPassword);
  FWbemObjectSet:= FWMIService.ExecQuery('SELECT * FROM Win32_Processor','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
    Writeln(Format('AddressWidth    %d bit',[Integer(FWbemObject.AddressWidth)]));// Uint16
    Writeln(Format('Architecture    %s',[ProcessorTypeAsString(Integer(FWbemObject.Architecture))]));// Uint16
    Writeln('');
    FWbemObject:=Unassigned;
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetWin32_ProcessorInfo;
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode])); 
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;      
end.


Roy - So 14.09.14 20:34

Dieser Code sagt es sind ungenügend Parameter vorhanden?!?



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
function GetNativeSystemInfo(var SystemInfo: TSystemInfo): Boolean;
type
  TGetNativeSystemInfo = procedure (var SystemInfo: TSystemInfo) stdcall;
var
  LibraryHandle: HMODULE;
  _GetNativeSystemInfo: TGetNativeSystemInfo;
begin
  Result := False;
  LibraryHandle := GetModuleHandle(kernel32);

  if LibraryHandle <> 0 then
  begin
    _GetNativeSystemInfo := GetProcAddress(LibraryHandle,'GetNativeSystemInfo');
    if Assigned(_GetNativeSystemInfo) then
    begin
      _GetNativeSystemInfo(SystemInfo);
      Result := True;
    end
    else
      GetSystemInfo(SystemInfo);
  end
  else
    GetSystemInfo(SystemInfo);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Label13.Caption := GetNativeSystemInfo;
end;

end.


Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt


WasWeißDennIch - So 14.09.14 21:07

Stimmt ja auch, der Var-Parameter muss übergeben werden.


Roy - So 14.09.14 21:19

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Stimmt ja auch, der Var-Parameter muss übergeben werden.


Und wie und wo


WasWeißDennIch - So 14.09.14 21:23

Na, beim Aufruf.

Delphi-Quelltext
1:
2:
3:
4:
var 
  SystemInfo: TSystemInfo;
begin
  GetNativeSystemInfo(SystemInfo);


jaenicke - So 14.09.14 21:27

Was im Übrigen auch in dem Beitrag so drin steht...
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
...

function IsWindows64: Boolean;
var
  ASystemInfo: TSystemInfo;
const
  PROCESSOR_ARCHITECTURE_INTEL = 0;
  PROCESSOR_ARCHITECTURE_IA64 = 6;
  PROCESSOR_ARCHITECTURE_AMD64 = 9;
begin
  GetNativeSystemInfo(ASystemInfo);
  Result := ASystemInfo.wProcessorArchitecture in [PROCESSOR_ARCHITECTURE_IA64,PROCESSOR_ARCHITECTURE_AMD64];
end;


Roy - Di 16.09.14 22:41

Parameter sind übergeben, jedoch streikt er bei aufruf der übergabe an ein Label


jaenicke - Di 16.09.14 22:50

Wie sieht denn der Quelltext aus?


Roy - Di 16.09.14 22:56


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
function GetNativeSystemInfo(var SystemInfo: TSystemInfo): Boolean;
type
  TGetNativeSystemInfo = procedure (var SystemInfo: TSystemInfo) stdcall;
var
  LibraryHandle: HMODULE;
  _GetNativeSystemInfo: TGetNativeSystemInfo;
begin
  Result := False;
  LibraryHandle := GetModuleHandle(kernel32);

  if LibraryHandle <> 0 then
  begin
    _GetNativeSystemInfo := GetProcAddress(LibraryHandle,'GetNativeSystemInfo');
    if Assigned(_GetNativeSystemInfo) then
    begin
      _GetNativeSystemInfo(SystemInfo);
      Result := True;
    end
    else
      GetSystemInfo(SystemInfo);
  end
  else
    GetSystemInfo(SystemInfo);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  SystemInfo: TSystemInfo;
begin
Label13.Caption:= GetNativeSystemInfo(SystemInfo);
end;


Moderiert von user profile iconMartok: Delphi-Tags hinzugefügt


jaenicke - Mi 17.09.14 06:32

Genau vor deinem letzten Beitrag hatte ich das Beispiel noch einmal zitiert...
Die Funktion GetNativeSystemInfo liefert nur zurück, ob sie die Informationen erfolgreich holen konnte.

Du kannst danach mit den Werten in deiner Variable SystemInfo arbeiten. Du kannst auch die fertige als Beispiel genannte Funktion IsWindows64 nutzen.
Zur Umwandlung des boolschen Werts in einem String zur Anzeige gibt es BoolToStr.


WasWeißDennIch - Mi 17.09.14 08:08

Zitat:

Delphi-Quelltext
1:
function GetNativeSystemInfo(var SystemInfo: TSystemInfo): Boolean;                    

Welchen Sinn soll es machen, einen Boolean in einem Label anzeigen zu wollen? Gut, mit BoolToStr kann man ihn umwandeln, sonderlich informativ ist das allerdings nicht. Wären die im TSystemInfo-Record zurückgegebenen Werte nicht eher von Interesse?


Sylar - Mi 17.09.14 09:21

Ich hoffe ich unterbreche nicht die Diskussion, aber ich hatte mal irgendwann so ein ähnliches Problem, dass ich herausfinden muss obs ein 64Bit oder 32Bit System ist.
Nach langem suchen bin ich auf die Funktion


Delphi-Quelltext
1:
IsWindows64;                    


gestoßen in den Jedi Komponenten. Evtl. hilft es ja weiter?

Findet man in der Unit JclSysInfo

Gruß


jaenicke - Mi 17.09.14 09:28

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Wären die im TSystemInfo-Record zurückgegebenen Werte nicht eher von Interesse?
Die zusammen mit dem benutzten Quelltext gepostete Funktion IsWindows64 gibt (wie auch die von den JEDIs) auch einen Boolean zurück. Darauf war das BoolToStr bezogen.


WasWeißDennIch - Mi 17.09.14 10:03

Das war mir schon klar, aber welchen Nutzen hat man davon, zu zeigen, ob die Funktion erfolgreich durchlaufen wurde? Gut, man weiß in diesem Fall, dass GetNativeSystemInfo in der kernel32.dll vorhanden ist, trotzdem stecken die relevanten Informationen IMO im Record.


jaenicke - Mi 17.09.14 13:31

Was hat das jetzt mit dem zu tun was ich geschrieben habe?
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Die zusammen mit dem benutzten Quelltext gepostete Funktion IsWindows64 gibt (wie auch die von den JEDIs) auch einen Boolean zurück. Darauf war das BoolToStr bezogen.


WasWeißDennIch - Mi 17.09.14 13:35

Wer sagt denn, dass ich Dich überhaupt gemeint habe? Meine Frage war an den TE gerichtet.