Determining Running OS

All of a sudden I needdd to find out if I was running Catalina or not, and I don’t want to use MBS in this case. Checking the forum and blog, there’s lots of old information. There’s even a blog that suggests System.VersionData, introduced in 2019r3, but I’m running 2020r1 and it says it doesn’t exist when compiling (it shows it under text.detect). Now, when I go to the documentation, it says it’s only for Mobile.


So - whats the best idea to find out OS, in particular OSX 10.9 through MacOS 11?

What does

dim temp as System.VersionData = System.Version

do? I only tested 2020r2.1 on M1.

If System.Version >= "10.15" then
    // something Catalina specific
End If

One could send a

sw_vers -productVersion

Using a shell() call and read the result.


I do read that he is using 2020r1, but something changed after 2019, and the said 2019 System.VersionData he depends on vanished.

Greg said another way, close to what he said: System.Version

Right, I read the [wrong] other way around, sorry…

No need to sorry, people do misread things all the time, me included.


System.Version returns a VersionData object which has an Operator_Compare method on it so you can use = < > to compare against string OS versions. It compares each individual segment from left to right to determine the relationship between the OS version and the supplied version.

All of these work

If system.version = "10" // anything 10.x.x

If system.version < "10.14" // anything earlier than 10.14

If system.version >= "11.2.1" // anything from 11.2.1 forward

It’s important to remember that we translate 10.16 into 11 automagically. If you need to find out if it’s Intel or ARM, use TargetARM to distinguish.

1 Like

Thanks, I think I got it. With some supplemental code, it works like I would need it to.

But to my defense, in 2020r1 at least, this is really implemented weird. I mean, what you explain, while “it works” works just because you say it does (and you are right). Earlier, I looked at this and said to myself “string comparisons to determine numerics???”

I was burned in the past by this financially - I printed like 10,000 CD’s about 10 years ago that had programs that used Apple’s installer, which had a bug in it that screwed up OS comparisons once they hit 10.10, because Apple used string comparisons to compare numbers. (Not just Xojo!) Once 10.10 hit, the installers took 10.10 to mean 10.1. Had to throw out about 8,000 of the CD’s. Thanks, Apple. grrrr

In this case, I saw the System.VersionData.MajorVersion, tried it and got “Item doesn’t exist”. I tried obtaining a VersionData class instance, and I got some “Static object…” junk error.

It seems like only this System.Version mystery string comparison, and System.Version.ToString work in MacOS. (And the ToString returns more than the comparison, e.g. “macOS 10.14.6”) All that other stuff involving VersionData seems to be iOS only.

Forgive me if I didn’t want to compare strings in numerical contexts =) But I guess I have to, and it does work, but… why would this ever be implemented like this? I seems so easy right behind the curtain to simply allow MajorVersion/MinorVersion/etc. to exist? Sorry to complain, but this is yuuch, you gotta admit, to a function that couldn’t ever be called esoteric.

It was implemented this way because version numbers can have more than two parts to them. You can’t just put something like this:

If n = 2.2.3 then

That won’t compile

FWIW, it converts each segment to an integer and compares them that way. As I said, it’s more for code readability.

My personal preference (“If I Were The Designer”) would be that the full responsibility of the function should be exposing the MajorVersion, MinorVersion, and Revision/Patch (and perhaps Build) in the form of integers. I’m really not sure how strings are even part of the discussion. And from what I read (Software versioning - Wikipedia), despite the typical historical complications, Maj/Min/Rev is pretty much a total standard and has been for some time. It’d be up to the programmer to make a string if he wanted to, and the integers allow perfect natural comparison standards. I don’t see why the framework should accede to our whims. (But I’m being a whiner at this point, but hey, fun! =))

Well, they do exist.


Well, I was wrong and I’m man enough to admit it. =) I was doing System.VersionData.MajorVersion. I think I was expecting VersionData (a class) to be a property of System and thus able to access it directly. My fault.

However, a small bit of my pride remains and I don’t think any of us should be doing string comparisons when it comes to versioning; so that Operator_Compare carrot isn’t the wonderful thing it makes itself out to be. But I could be wrong (I was before). Thanks

But we’re not comparing strings. As I said above, we’re using a string simply because it supports multiple decimals like in a version string. Once we get into the Operator_Compare method, we split into an array and convert each part to an integer. Each part is compared to determine (in)equality.

If you can prove that it’s failing in some odd way, we would love to hear about it. If you simply don’t like it, that’s fine too. You can always use the individual properties and ignore the simpler mechanism if you prefer.

1 Like