Recent

Author Topic: How to detect which OS and bitness my app is running on?  (Read 14342 times)


Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: How to detect which OS and bitness my app is running on?
« Reply #1 on: October 03, 2016, 07:15:45 am »
Just for fun!
Machines need java installed
compile: ppcjvm -Fu/usr/local/lib/fpc/3.1.1/units/jvm-java/rtl/org/freepascal/rtl testjava.pas
run: java -cp /usr/local/lib/fpc/3.1.1/units/jvm-java/rtl:. testjava
Code: Pascal  [Select][+][-]
  1. program testjava;
  2. {$mode objfpc}{$modeswitch unicodestrings}{$H+}
  3. {$macro on}
  4. {$define writeln:=jlsystem.fout.println}
  5. uses
  6.   jdk15;
  7. begin
  8.  // OS info in ppcjvm
  9.   writeln(jlsystem.getProperty('os.name'));
  10.   writeln(jlsystem.getProperty('os.version'));
  11.   writeln(jlsystem.getProperty('os.arch'));
  12. end.

You can also use jni and link into a native app.
Anyway, you didn't expect that answer, did you ;)
« Last Edit: October 03, 2016, 07:54:36 am by Thaddy »
Specialize a type, not a var.

valdir.marcos

  • Hero Member
  • *****
  • Posts: 1106
Re: How to detect which OS and bitness my app is running on?
« Reply #2 on: October 03, 2016, 12:04:01 pm »
Just for fun!
Machines need java installed

You can also use jni and link into a native app.
Anyway, you didn't expect that answer, did you ;)

No, I didn't expected that at all.  :) :) :)
It seems so simple to get that information on Java.

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: How to detect which OS and bitness my app is running on?
« Reply #3 on: October 03, 2016, 12:57:39 pm »
You can use conditional defines to detect most OS'es, like described here:

http://forum.lazarus.freepascal.org/index.php/topic,15869.msg85689.html#msg85689

Detecting if you program is 32bit or 64bit can be done with:

Code: Pascal  [Select][+][-]
  1. Function Is64Bit: Boolean;
  2. Begin
  3.   Result:= SizeOf(Pointer) > 4;
  4. End;
  5.  
  6. Function Is32Bit: Boolean;
  7. Begin
  8.   Result:= SizeOf(Pointer) <= 4;
  9. End;

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: How to detect which OS and bitness my app is running on?
« Reply #4 on: October 03, 2016, 01:09:29 pm »
You can use conditional defines to detect most OS'es, like described here:
........
Detecting if you program is 32bit or 64bit can be done with:
.......
Which is not what he asked.
1. You can not use only ifdefs at runtime. The example detects where the code is compiled for. Doesn't answer the question.
2. You can not detect the bitness of the OS based on pointer size (e.g. a win32 application will happily run on win64 and happily return a 32 bit pointer....). Doesn't answer the question.
3. It is definitely possible to detect OS, Version, Endianness and bitness at runtime (partially using ifdefs, but with syscalls to determine the true identity... Regardless of the subsystem the program is compiled for.

What he DOES ask is a generic, cross-platform set of routines that return OS, bitness and version at runtime.
That's the reason I used ppcjvm code: Java contains such a set of routines.
There is some code that is semi-crossplatform: just linux and windows and 32 and 64 bit.
« Last Edit: October 03, 2016, 01:17:59 pm by Thaddy »
Specialize a type, not a var.

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: How to detect which OS and bitness my app is running on?
« Reply #5 on: October 03, 2016, 01:22:45 pm »
Which is not what he asked.
1. You can not use ifdefs at runtime
2. You can not detect the bitness of the OS based on pointer size (e.g. a win32 application will happily run on win64 and happily return a 32 bit pointer....)

1. Nope, you cant. But a Win32 binary will not run in MacOS, Linux or others. You can use Wine, but since this will emulate a Windows environment, you will not be able to detect otherwise.
2. Using the SizeOf(Pointer) will work in order to detect if the binary is compiled as 32bit or 64bit. To detect the what the OS is you could use a TProcess with redirect and get the output of the commands:

Windows: wmic os get osarchitecture
Linux: uname -m

The Linux command should work on mac as well.

valdir.marcos

  • Hero Member
  • *****
  • Posts: 1106
Re: How to detect which OS and bitness my app is running on?
« Reply #6 on: October 03, 2016, 04:58:49 pm »
Which is not what he asked.
...
What he DOES ask is a generic, cross-platform set of routines that return OS, bitness and version at runtime.

Yes, you are right.
I am compiling the same source code on Windows and Linux. Mac will come in a near future.
That's why I am searching for a generic cross-platform solution.

If possible, I do not want to have Java as a prerequisite for my Lazarus Free Pascal project.


Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: How to detect which OS and bitness my app is running on?
« Reply #7 on: October 03, 2016, 06:02:17 pm »
You need to conditional compile and on Windows use GetSystemInfo for architecture and GetVersion (or better; GetVersionEx) for Windows version codes. On Unix'es you just use a TProcess to execute the command "uname -a" since this will output an OS name and version - you can search this result for "x86_64" or "x86-64" to detect if the OS is a 64bit version. This will be a cross-platform sollution that will work :-)

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: How to detect which OS and bitness my app is running on?
« Reply #8 on: October 03, 2016, 06:24:48 pm »
Yes, you are right.

If possible, I do not want to have Java as a prerequisite for my Lazarus Free Pascal project.
That's why I wrote it for fun ;) I don't want Java all over the place either ;)
But I am working on it along the lines me and Fungus explained.
(That will work for windows, linux (incl arm, and Mac OSX).

Five routines:
- OS
- BItness
- Version
- Endianness.
- CPU architecture  (restricted)

All of this is alreadyy available in the standard FPC libraries, but not unified.
Specialize a type, not a var.

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: How to detect which OS and bitness my app is running on?
« Reply #9 on: October 03, 2016, 08:35:57 pm »
The following should work on all unixes:

Code: Pascal  [Select][+][-]
  1. Procedure UnixSysInfo;
  2. Var P: TProcess;
  3.  
  4.     Function ExecParam(Param: String): String;
  5.     Begin
  6.       P.Parameters[0]:= '-' + Param;
  7.       P.Execute;
  8.       SetLength(Result, 1000);
  9.       SetLength(Result, P.Output.Read(Result[1], Length(Result)));
  10.       While (Length(Result) > 0) And (Result[Length(Result)] In [#8..#13,#32]) Do
  11.         SetLength(Result, Length(Result) - 1);
  12.     End;
  13.  
  14. Begin
  15.   P:= TProcess.Create(Nil);
  16.   P.Options:= [poWaitOnExit, poUsePipes];
  17.   P.Executable:= 'uname';
  18.   P.Parameters.Add('');
  19.   WriteLn('Operating System: ', ExecParam('o'));
  20.   WriteLn('Kernel Name: ', ExecParam('s'));
  21.   WriteLn('Kernel Release: ', ExecParam('r'));
  22.   WriteLn('Kernel Version: ', ExecParam('v'));
  23.   WriteLn('Network Node: ', ExecParam('n'));
  24.   WriteLn('Architecture: ', ExecParam('m'));
  25.   P.Free;
  26. End;

On Linux Mint 17.3 the output is:

Operating System: GNU/Linux
Kernel Name: Linux
Kernel Release: 3.19.0-32-generic
Kernel Version: #37~14.04.1-Ubuntu SMP Thu Oct 22 09:41:40 UTC 2015
Network Node: ***
Architecture: x86_64
« Last Edit: October 03, 2016, 08:38:13 pm by Fungus »

Thaddy

  • Hero Member
  • *****
  • Posts: 14205
  • Probably until I exterminate Putin.
Re: How to detect which OS and bitness my app is running on?
« Reply #10 on: October 03, 2016, 08:40:30 pm »
@Fungus
Yes, but that is not cross-platform.
I have similar code for several platforms and will give a unified interface for it.
That should answer the question
Sometime tomorrow. win-dos-unix.
Specialize a type, not a var.

Fungus

  • Sr. Member
  • ****
  • Posts: 353
Re: How to detect which OS and bitness my app is running on?
« Reply #11 on: October 03, 2016, 08:49:06 pm »
@Fungus
Yes, but that is not cross-platform.
I have similar code for several platforms and will give a unified interface for it.
That should answer the question
Sometime tomorrow. win-dos-unix.

It was not ment to be cross platform. I'm supplying a sollution that will work on Unix'es. Kernel Name will be Linux, Darwin (MacOS), FreeBSD, NetBSD and so on. With a conditional compile that checks for {$IFDEF LINUX} or {IFDEF UNIX} you can use the unix code. If {$IFDEF WIN32} you must use GetSystemInfo and GetVersionEx to get the Windows values. You could then create a record like:

Code: Pascal  [Select][+][-]
  1. TOSInfo = Record
  2.   Kernel: String;
  3.   OSName: String;
  4.   OSVersion: String;
  5.   Architecture: String;
  6. End;

And fill in the values from Unix or Windows and thus have a cross-platform result. Should be a breeze to do :D

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: How to detect which OS and bitness my app is running on?
« Reply #12 on: October 04, 2016, 07:18:30 am »
If {$IFDEF WIN32} you must use GetSystemInfo and GetVersionEx to get the Windows values.

If the code is compiled for 32bit but is run on a 64bit system, GetSystemInfo() will return 32bit information emulated by WOW64.  To get the real system info, you have to use GetNativeSystemInfo() instead.

As for GetVersion/Ex(), be careful with it, because it lies about the OS version number on Windows 8.1 and later based on your app's manifest.  And VerifyVersionInfo() lies on Windows 10 and later based on your app's manifest as well.  To get the true OS version, you can use RtlGetVersion(), NetServerGetInfo(), or NetWkstaGetInfo() instead.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

jma_sp

  • Full Member
  • ***
  • Posts: 150
  • El conocimiento si ocupa lugar.
Re: How to detect which OS and bitness my app is running on?
« Reply #13 on: October 04, 2016, 10:19:41 am »
Thanks for all responses :)

Uname is a good resource.

Before it i was tried looking into registry for 64 bits for the existence of wow entry....indicating is 64 bit, also if filesystem  program files(x86)....

Under windows thereis some interesting entries to get OS details

Thanks Remy Lebeau for those interesting functions.

Into de registry you can search for ProductName/CurrentVersion/CurrentBuildNumber and BuildLab..........

You can study the code of this program https://sourceforge.net/projects/ekeyfinder/?source=directory



Saludos.
« Last Edit: October 04, 2016, 10:36:02 am by jma_sp »
Devuan Beowulf 3.0( JWM/ROX/iDesk) - Puppy Linux,  Haiku OS,.ReactOS 0.4.xx  - FreeDos .

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1312
    • Lebeau Software
Re: How to detect which OS and bitness my app is running on?
« Reply #14 on: October 05, 2016, 11:11:44 pm »
Before it i was tried looking into registry for 64 bits for the existence of wow entry....indicating is 64 bit, also if filesystem  program files(x86)....

Under windows thereis some interesting entries to get OS details

You should not rely on the Registry to get OS details.  You should ask the OS itself instead.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018