Determine is OS is 32 or 64 bit at runtime?

Just starting out? Need help? Post your questions and find answers here.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Determine is OS is 32 or 64 bit at runtime?

Post by PB »

I thought there was a native runtime command for this?
I'm currently using a procedure but would rather use a
native command. I'm sure I've seen it before? :shock:

And no, I don't mean CompilerIf with #PB_Processor_x64,
because that's not a runtime check. ;)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
PureGuy
Enthusiast
Enthusiast
Posts: 102
Joined: Mon Aug 30, 2010 11:51 am

Re: Determine is OS is 32 or 64 bit at runtime?

Post by PureGuy »

PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Determine is OS is 32 or 64 bit at runtime?

Post by PB »

Thanks PureGuy... I could've sworn there's a native command though.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
User avatar
idle
Always Here
Always Here
Posts: 5900
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Determine is OS is 32 or 64 bit at runtime?

Post by idle »

can't you just use sizeof(integer) for this?
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
Demivec
Addict
Addict
Posts: 4269
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Determine is OS is 32 or 64 bit at runtime?

Post by Demivec »

idle wrote:can't you just use sizeof(integer) for this?
No, he wants to know what the environment that the program is running in. It could be a 32bit process running on a 64bit OS. SizeOf(integer) would just tell you what it was compiled under not the processor or OS it is executed with.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Determine is OS is 32 or 64 bit at runtime?

Post by RASHAD »

Use the next good procedure by NM
It is always fine with me

Code: Select all

Procedure Is64Bit()
Protected bIsWow64.l = #False, fnIsWow64Process
 
  fnIsWow64Process = GetProcAddress_(GetModuleHandle_("kernel32"), "IsWow64Process")
 
  If fnIsWow64Process
    If Not CallFunctionFast(fnIsWow64Process, GetCurrentProcess_(), @bIsWow64)
    EndIf
  EndIf
 
  ProcedureReturn bIsWow64
EndProcedure

Egypt my love
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Determine is OS is 32 or 64 bit at runtime?

Post by ts-soft »

@RASHAD
The question is not, is process 64-bit, the question is: Is OS 64-Bit.

The example by freak is okay for this!
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
skywalk
Addict
Addict
Posts: 4218
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Determine is OS is 32 or 64 bit at runtime?

Post by skywalk »

I just check for the existence of 'SysWow64\*.dll' on Windows.
I don't have a Linux machine, but I think it is 'X86_64/something'.

Code: Select all

Macro FL_FileExists(Fname)
  ;  0 = File or Folder does not exist
  ;  1 = File Exists
  ; -1 = Folder Exists
  ; Since FileSize() returns:
  ;       -1 = File Not found.
  ;       -2 = File is a directory.
  ;        0 = Empty File, > 1 = File Exists
  ;        FileSize() respects '*' wildcards and reports results accordingly.
  FileSize(Fname) + 1
EndMacro
Macro SL_Is64BitOS()
  ; Windows 64-bit OS Info
  ; ----------------------   ----------------------------------
  ; C:\Windows\System32      System directory for 64-bit files
  ; C:\Windows\SysWOW64      System directory for 32-bit files
  ; C:\Program Files         Apps directory for 64-bit files
  ; C:\Program Files (x86)   Apps directory for 32-bit files
  ; --------------------------------   -------------------------------------------------------------------
  ; WoW64 uses 3 DLLs                  Description
  ; --------------------------------   -------------------------------------------------------------------
  ; C:\Windows\System32\Wow64.dll      core interface to Windows NT kernel that translates between
  ;                                    32-bit & 64-bit calls including pointer & call stack manipulations
  ; C:\Windows\System32\Wow64win.dll   provide appropriate entry-points for 32-bit apps
  ; C:\Windows\System32\Wow64cpu.dll   switch processor from 32-bit to 64-bit mode
  ; 32-bit apps runnning on 64-bit OS are redirected, so query the existence of C:\Windows\SysWOW64\*.dll's
  FL_FileExists(GetEnvironmentVariable("WinDir")+"\SysWow64\*.dll")
EndMacro
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Determine is OS is 32 or 64 bit at runtime?

Post by luis »

I use this on Win, practically what described here -> http://blogs.msdn.com/b/oldnewthing/arc ... 64563.aspx and similar but not identical to what posted by RASHAD.

Some more reading -> http://mfctips.com/2013/04/18/detect-wh ... or-64-bit/

Code: Select all

Procedure.i Is64BitOS()
; [DESC]
; Check if the OS under which the program is running is a 64 bit OS.
;
; [RETURN]
; 1 for 64 bit OS, else 0.

 Protected Is64BitOS = 0
 Protected hDLL, IsWow64Process_
 
 If SizeOf(Integer) = 8
    Is64BitOS = 1 ; this is a 64 bit exe
 Else
    hDll = OpenLibrary(#PB_Any,"kernel32.dll")
    If hDll
        IsWow64Process_ = GetFunction(hDll,"IsWow64Process")
        If IsWow64Process_
            CallFunctionFast(IsWow64Process_, GetCurrentProcess_(), @Is64BitOS)
        EndIf
        CloseLibrary(hDll)
    EndIf     
 EndIf
 
 ProcedureReturn Is64BitOS
EndProcedure
 
Debug Is64bitOS()
To answer the original question: No, there isn't :)
"Have you tried turning it off and on again ?"
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Determine is OS is 32 or 64 bit at runtime?

Post by RASHAD »

@ts-soft
Yes I missed
But at least the thread started to be more informative with you,skywalk and luis :)
Next is all what I got

#1 :

Code: Select all

lRetVal.l
sRemMachName.s
lTopLevelKey.l
lHKeyhandle.l
sKeyName.s
lhkey.l
sValueName.s
vValue.s
msg.s ;

#ERROR_NONE = 0

Procedure.l QueryValueEx(lhkey.l, sValueName.s)
  Define.l cch, lrc, lType, lValue
  Define.s sValue
  Shared vValue
  cch    = 255
  sValue = Space(255)
  lrc    = RegQueryValueEx_(lhkey, sValueName, 0, @lType, @sValue, @cch)
;   If lrc = #ERROR_NONE
;     vValue = Left(sValue, cch - 1)
;   Else
;     vValue = "Empty"
;   EndIf
  ProcedureReturn lrc
EndProcedure

lTopLevelKey = #HKEY_LOCAL_MACHINE 
sRemMachName = ""
sKeyName = "Software"
sValueName = ""
lRetVal = RegConnectRegistry_(sRemMachName, lTopLevelKey, @lHKeyhandle)
Debug lRetVal
lRetVal = RegOpenKeyEx_(lHKeyhandle, sKeyName, 0,#KEY_READ, @lhkey)
lRetVal = QueryValueEx(lhkey, sValueName)
RegCloseKey_(lhkey)

If lRetVal = 0
  MessageRequester("Information","Running System is 64 bit", #MB_ICONINFORMATION)
Else
  MessageRequester("Information","Running System is 32 bit", #MB_ICONINFORMATION)
EndIf

#2 :

Code: Select all

#COINIT_MULTITHREAD=0 
#RPC_C_AUTHN_LEVEL_CONNECT=2 
#RPC_C_IMP_LEVEL_IDENTIFY=2 
#EOAC_NONE=0 
#RPC_C_AUTHN_WINNT=10 
#RPC_C_AUTHZ_NONE=0 
#RPC_C_AUTHN_LEVEL_CALL=3 
#RPC_C_IMP_LEVEL_IMPERSONATE=3 
#CLSCTX_INPROC_SERVER=1 
#wbemFlagReturnImmediately=16 
#wbemFlagForwardOnly=32 
#IFlags = #wbemFlagReturnImmediately + #wbemFlagForwardOnly 
#WBEM_INFINITE=$FFFFFFFF 
#WMISeparator="," 
;} 

Procedure.l ansi2uni(ansi.s) 
  size.l=MultiByteToWideChar_(#CP_ACP,0,ansi,-1,0,0) 
  Dim unicode.w(size) 
  MultiByteToWideChar_(#CP_ACP, 0, ansi, Len(ansi), unicode(), size) 
  ProcedureReturn SysAllocString_(@unicode()) 
EndProcedure 

Procedure uni2ansi(uni) 
  Shared WMIResult.s 
  WMIResult.s = "" 
  mem=uni 
  While PeekW (mem) 
    WMIResult=WMIResult+Chr(PeekW(mem)) 
    mem=mem+2 
  Wend 
  ProcedureReturn @WMIResult 
EndProcedure 

ProcedureDLL.s WMI(WMICommand.s) 
  CoInitializeEx_(0,#COINIT_MULTITHREAD) 
  hres=CoInitializeSecurity_(0, -1,0,0,#RPC_C_AUTHN_LEVEL_CONNECT,#RPC_C_IMP_LEVEL_IDENTIFY,0,#EOAC_NONE,0) 
  If hres <> 0: MessageRequester("ERROR", "unable to call CoInitializeSecurity", #MB_OK): Goto cleanup: EndIf 
  hres=CoCreateInstance_(?CLSID_WbemLocator,0,#CLSCTX_INPROC_SERVER,?IID_IWbemLocator,@loc.IWbemLocator) 
  If hres <> 0: MessageRequester("ERROR", "unable to call CoCreateInstance", #MB_OK): Goto cleanup: EndIf
  
  CompilerIf #PB_Compiler_Unicode 
      hres=loc\ConnectServer(SysAllocString_(@"root\cimv2"),0,0,0,0,0,0,@svc.IWbemServices)
  CompilerElse  
      hres=loc\ConnectServer(ansi2uni("root\cimv2"),0,0,0,0,0,0,@svc.IWbemServices)
  CompilerEndIf

  If hres <> 0: MessageRequester("ERROR", "unable to call IWbemLocator::ConnectServer", #MB_OK): Goto cleanup: EndIf 
  hres=svc\QueryInterface(?IID_IUnknown,@pUnk.IUnknown) 
  hres=CoSetProxyBlanket_(svc,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE) 
  If hres <> 0: MessageRequester("ERROR", "unable to call CoSetProxyBlanket", #MB_OK): Goto cleanup: EndIf 
  hres=CoSetProxyBlanket_(pUnk,#RPC_C_AUTHN_WINNT,#RPC_C_AUTHZ_NONE,0,#RPC_C_AUTHN_LEVEL_CALL,#RPC_C_IMP_LEVEL_IMPERSONATE,0,#EOAC_NONE) 
  If hres <> 0: MessageRequester("ERROR", "unable to call CoSetProxyBlanket", #MB_OK): Goto cleanup: EndIf 
  pUnk\Release()
  
  k=CountString(WMICommand,#WMISeparator) 
  Dim wmitxt$(k) 
  For i=0 To k 
    wmitxt$(i) = StringField(WMICommand,i+1,#WMISeparator) 
  Next
   
  CompilerIf #PB_Compiler_Unicode
      hres=svc\ExecQuery(SysAllocString_(@"WQL"),SysAllocString_(@wmitxt$(0)), #IFlags,0,@pEnumerator.IEnumWbemClassObject) 
  CompilerElse 
      hres=svc\ExecQuery(ansi2uni("WQL"),ansi2uni(wmitxt$(0)), #IFlags,0,@pEnumerator.IEnumWbemClassObject)
  CompilerEndIf
   
  If hres <> 0: MessageRequester("ERROR", "unable to call IWbemServices::ExecQuery", #MB_OK): Goto cleanup: EndIf 
  hres=pEnumerator\reset() 
  Repeat 
  hres=pEnumerator\Next(#WBEM_INFINITE, 1, @pclsObj.IWbemClassObject, @uReturn) 
  For i=1 To k 
    mem=AllocateMemory(1000)
    
  CompilerIf #PB_Compiler_Unicode
    hres=pclsObj\get(SysAllocString_(@wmitxt$(i)), 0, mem, 0, 0)
  CompilerElse 
    hres=pclsObj\get(ansi2uni(wmitxt$(i)), 0, mem, 0, 0)
  CompilerEndIf
   
    Type=PeekW(mem) 
    Select Type 
      Case 8 
        val.s=PeekS(uni2ansi(PeekL(mem+8))) 
      Case 3 
        val.s=Str(PeekL(mem+8)) 
      Default 
        val.s="" 
    EndSelect 
    If uReturn <> 0: wmi$=wmi$+wmitxt$(i)+" = "+val+Chr(10)+Chr(13): EndIf 
    FreeMemory(mem) 
  Next 
Until uReturn = 0 

cleanup: 
svc\Release() 
loc\Release() 
pEnumerator\Release() 
pclsObj\Release() 
CoUninitialize_() 

ProcedureReturn wmi$ 
EndProcedure 


DataSection 
CLSID_IEnumWbemClassObject: 
Data.l $1B1CAD8C 
Data.w $2DAB, $11D2 
Data.b $B6, $04, $00, $10, $4B, $70, $3E, $FD 

IID_IEnumWbemClassObject: 
Data.l $7C857801 
Data.w $7381, $11CF 
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24 

CLSID_WbemLocator: 
Data.l $4590F811 
Data.w $1D3A, $11D0 
Data.b $89, $1F, $00, $AA, $00, $4B, $2E, $24 

IID_IWbemLocator: 
Data.l $DC12A687 
Data.w $737F, $11CF 
Data.b $88, $4D, $00, $AA, $00, $4B, $2E, $24 

IID_IUnknown: 
Data.l $00000000 
Data.w $0000, $0000 
Data.b $C0, $00, $00, $00, $00, $00, $00, $46 

EndDataSection 


Procedure.s Between(string.s, LString.s, RString.s) 
  Protected Between.s, LIndex.l, RIndex.l 
  
  LIndex = FindString(string, LString, 0) 
  RIndex = FindString(string, RString, 0) 
  
  If LIndex And RIndex 
    LIndex  + Len(LString) 
    Between = Mid(string, LIndex, RIndex-LIndex) 
  EndIf 
  
  ProcedureReturn Between 
EndProcedure

Procedure.s GetWindowsDirectory()
  Path.s=Space(500)
  GetWindowsDirectory_(@Path,500)
  ProcedureReturn Path
EndProcedure  

Text$ = WMI("Select * FROM Win32_OperatingSystem,Name")
Text$ = Between(Text$,"Name = ","|")

If FileSize(GetWindowsDirectory()+"\SysWOW64") = -2
Text$ = Text$ + ",64 bit"
Else
Text$ = Text$ + ",32 bit"
EndIf

MessageRequester("OS Version",Text$)
Egypt my love
User avatar
J. Baker
Addict
Addict
Posts: 2181
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: Determine is OS is 32 or 64 bit at runtime?

Post by J. Baker »

OS X example...

Code: Select all

Terminal = RunProgram("uname", "-m", "", #PB_Program_Open | #PB_Program_Read)
  bit$ = ReadProgramString(Terminal)
  CloseProgram(Terminal)
MessageRequester("You're OS is...", bit$)
Will display x86_64 or i386.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef


Even the vine knows it surroundings but the man with eyes does not.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: Determine is OS is 32 or 64 bit at runtime?

Post by ts-soft »

J. Baker wrote:Will display x86_64 or i386.
Same results on Linux :wink:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Determine is OS is 32 or 64 bit at runtime?

Post by PB »

What Rashad posted above by NM is what I'm using. :)

But I wondered why I was using it, because I thought
I saw a native command once. Maybe I'm confused with
the CompilerIf version.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply