Lazarus

Programming => Operating Systems => macOS / Mac OS X => Topic started by: ChrisR on April 14, 2021, 06:25:19 pm

Title: [SOLVED] Detect MacOS version
Post by: ChrisR on April 14, 2021, 06:25:19 pm
Prior to MacOS 11, the code below reported MacOS version correctly. It obviously will not work with MacOS 11, as the "10" is hard coded, but can anyone suggest the recommended backward compatible way to detect MacOS version.

Of reference, on MacOS 11.2.3, this program reports "MacOS: 10.16.3"

program ver;
{$mode objfpc}
uses Dos, sysutils;
//fpc ver.pas; ./ver
begin
   writeln('MacOS: 10.' + IntToStr(Lo(DosVersion) - 4) + '.' + IntToStr(Hi(DosVersion))  );
end.
Title: Re: Detect MacOS version
Post by: Hansaplast on April 14, 2021, 06:37:41 pm

The way I do it ... and maybe there is a better way ... but here an example project (just a TForm with 2 TLabels).




Don't forget:
- {$modeswitch objectivec1}
- uses CocoaAll


Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3.  
  4. {$mode objfpc}{$H+}
  5. {$modeswitch objectivec1}
  6. interface
  7.  
  8.  
  9. uses
  10.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, CocoaAll;
  11.  
  12.  
  13. type
  14.  
  15.  
  16.   { TForm1 }
  17.  
  18.  
  19.   TForm1 = class(TForm)
  20.     Label1: TLabel;
  21.     Label2: TLabel;
  22.     procedure FormCreate(Sender: TObject);
  23.   private
  24.  
  25.  
  26.   public
  27.  
  28.  
  29.   end;
  30.  
  31.  
  32. var
  33.   Form1: TForm1;
  34.  
  35.  
  36. implementation
  37.  
  38.  
  39. {$R *.lfm}
  40.  
  41.  
  42. { TForm1 }
  43.  
  44.  
  45. procedure TForm1.FormCreate(Sender: TObject);
  46. begin
  47.   Label1.Caption :=  NSProcessInfo.ProcessInfo.operatingSystemVersionString.UTF8String;
  48.  
  49.  
  50.   Label2.Caption := IntToStr( NSProcessInfo.ProcessInfo.OperatingSystemVersion.majorVersion ) + '.' +
  51.                     IntToStr( NSProcessInfo.ProcessInfo.OperatingSystemVersion.minorVersion ) + '.' +
  52.                     IntToStr( NSProcessInfo.ProcessInfo.OperatingSystemVersion.patchVersion );
  53. end;
  54.  
  55.  
  56. end.
  57.  
Title: Re: Detect MacOS version
Post by: trev on April 15, 2021, 01:34:57 am
Beware NSProcessInfo.ProcessInfo.OperatingSystemVersion is only available from Yosemite (10.10). Whereas operatingSystemVersionString is available from Jaguar (10.2).

See the Wiki article Accessing macOS System Information (https://wiki.freepascal.org/Accessing_macOS_System_Information#NSProcessinfo).
Title: Re: Detect MacOS version
Post by: Hansaplast on April 15, 2021, 12:05:07 pm
Thanks Trev for the heads up!
I wasn't aware ...
Title: Re: Detect MacOS version
Post by: trev on April 15, 2021, 12:18:39 pm
The final solution which works for Mac OS X 10.0 through macOS 11.2.3:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2. {$mode objfpc}{$H+}
  3. {$modeswitch objectivec2}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Dialogs, StdCtrls, ExtCtrls,
  9.   MacOSAll,
  10.   CocoaAll;
  11.  
  12. type
  13.   TForm1 = Class(TForm)
  14.     Memo1: TMemo;
  15.     Button1: TButton;
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.   public
  19.   end;
  20.  
  21. var
  22.   Form1: TForm1;
  23.   counter: Int64;
  24.  
  25. implementation
  26.  
  27. {$R *.lfm}
  28.  
  29. { TForm1 }
  30. procedure ProcessInfo;
  31. begin
  32.     Form1.Memo1.Lines.Clear;
  33.  
  34.     Form1.Memo1.Lines.Add('macOS version: '
  35.       + IntToStr(NSProcessInfo.ProcessInfo.operatingSystemVersion.majorVersion)
  36.       + '.'
  37.       + IntToStr(NSProcessInfo.ProcessInfo.operatingSystemVersion.minorVersion)
  38.       + '.'
  39.       + IntToStr(NSProcessInfo.ProcessInfo.operatingSystemVersion.patchVersion)
  40.     );
  41. end;
  42.  
  43. Procedure GestaltInfo;
  44. var
  45.     majorVersion: LongInt = 0;
  46.     minorVersion: LongInt = 0;
  47.     patchVersion: LongInt = 0;
  48. begin
  49.     Form1.Memo1.Lines.Clear;
  50.     Form1.Memo1.Lines.Add('Trying another way...');
  51.  
  52.     Gestalt(gestaltSystemVersionMajor, majorVersion);
  53.     Gestalt(gestaltSystemVersionMinor, minorVersion);
  54.     Gestalt(gestaltSystemVersionBugFix, patchVersion);
  55.  
  56.     Form1.Memo1.Lines.Add('macOS vedrsion: ' + IntToStr(majorVersion) + '.' +
  57.       IntToStr(minorVersion) + '.' + IntToStr(patchVersion));
  58. end;
  59.  
  60. procedure TForm1.Button1Click(Sender: TObject);
  61. var
  62.   aSEL : SEL;
  63. begin
  64.   // Check whether OS version responds to this selector
  65.   aSEL := objcselector('operatingSystemVersion');
  66.   if NSProcessInfo.processInfo.respondsToSelector(aSEL) then
  67.     processInfo
  68.   // Fallback to the deprecated Gestalt function
  69.   else
  70.      GestaltInfo;
  71. end;
  72. end.
Title: Re: [SOLVED] Detect MacOS version
Post by: ChrisR on April 15, 2021, 12:55:03 pm
Sorry I missed the well written wiki page. Thanks for the rapid solution.
Title: Re: [SOLVED] Detect MacOS version
Post by: jwdietrich on March 02, 2024, 09:00:24 am
The following code supports current operating systems (macOS Ventura 13.6 or newer):

Code: Pascal  [Select][+][-]
  1. function SystemVersion: String;
  2. begin
  3.   result := NSProcessInfo.ProcessInfo.operatingSystemVersionString.UTF8String;
  4. end;
TinyPortal © 2005-2018