19

Can anyone help me detect which version of Windows the user may be using?

I have seen some examples to do this, but they are not updated for Vista/7 Operating Systems.

Additionally it would be useful to detect if the OS is running on x32 or x64 architecture.

Thanks in advance.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Also see http://stackoverflow.com/questions/2523957/how-to-get-information-about-the-computer-32bit-or-64bit and http://stackoverflow.com/questions/1268178/how-to-check-in-delphi-the-os-version-windows-7-or-server-2008-r2 – Marcus Adams Nov 15 '11 at 23:39
  • 1
    @Craig FWIW, this question would be a little easier to answer if you had included a tag specifying which version of Delphi you use – David Heffernan Nov 16 '11 at 00:03

4 Answers4

43

On XE2 a new class was introduced to deal with this: TOSVersion.

  • Read TOSVersion.Architecture to check for 32 or 64 bit OS.
  • Read TOSVersion.Platform to check for Windows or Mac.
  • Read TOSVersion.Major and TOSVersion.Minor for version numbers.
  • Read TOSVersion.Name to obtain the basic product name, e.g. Windows 7.
  • Read TOSVersion.ToString to obtain the full product name with version, e.g. Windows 7 Service Pack 1 (Version 6.1, Build 7601, 64-bit Edition).

For older versions of Delphi I recommend the following:

In order to check for 2000, XP, Vista, 7 I suggest you read Win32MajorVersion and Win32MinorVersion.

  • major.minor = 5.0 => Windows 2000
  • major.minor = 5.1 => Windows XP
  • major.minor = 5.2 => Windows 2003 server or XP64
  • major.minor = 6.0 => Windows Vista/2008 server
  • major.minor = 6.1 => Windows 7/2008 server R2

The same information is available on MSDN, but the above came from my head!

If you are wanting very detailed product information then that takes a bit more work. Warren's answer gives one good route to obtaining that information. If you are wanting to test capability then version numbers are fine.

Use CheckWin32Version to check if the prevailing OS exceeds a certain version level. Although you should check that the function works correctly in your Delphi since the implementation of that function in Delphi 6 and earlier was incorrect.

To find out what the native OS architecture is (32 or 64 bit), use the GetNativeSystemInfo function. This function is not available on older operating systems so you should load it explicitly with GetProcAddress. Test for wProcessorArchitecture=PROCESSOR_ARCHITECTURE_AMD64 to check for 64 bit OS.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Updated link to TOSVersion - https://docwiki.embarcadero.com/Libraries/en/System.SysUtils.TOSVersion – complete_stranger Aug 09 '22 at 07:50
  • Annoyingly, in XE2 this doesn't seem to work for the newest Windows versions. I have Windows 10 but it reports version 6.2, which is for Windows 8. The ToString didn't help either. I don't know if this is fixed in later versions of Delphi. Microsoft itself doesn't seem to have a good solution either, other than "testing for the presence/absence of a feature": https://learn.microsoft.com/en-us/windows/win32/sysinfo/operating-system-version – Kevin North Mar 04 '23 at 20:39
  • @KevinNorth since I wrote this answer things changed. And XE2 is ancient now. There are loads of posts on this topic from a winapi perspective. Some search will get you home. – David Heffernan Mar 04 '23 at 22:02
10

The JEDI JCL already does this, even on versions older than XE2. See David's answer for the built-in solution in XE2 and later.

Using the Jedi JCL, you can add unit JclSysInfo, and call function GetWindowsVersion. It returns an enumerated type TWindowsVersion.

Currently JCL contains all shipped windows versions, and gets changed each time Microsoft ships a new version of Windows in a box:

  TWindowsVersion =
   (wvUnknown, wvWin95, wvWin95OSR2, wvWin98, wvWin98SE, wvWinME,
    wvWinNT31, wvWinNT35, wvWinNT351, wvWinNT4, wvWin2000, wvWinXP,
    wvWin2003, wvWinXP64, wvWin2003R2, wvWinVista, wvWinServer2008,
    wvWin7, wvWinServer2008R2);

If you want to know if you're running 64-bit windows 7 instead of 32-bit, then call JclSysInfo.IsWindows64.

Note that JCL allso handles Editions, like Pro, Ultimate, etc. For that call GetWindowsEdition, and it returns one of these:

TWindowsEdition =
   (weUnknown, weWinXPHome, weWinXPPro, weWinXPHomeN, weWinXPProN, weWinXPHomeK,
    weWinXPProK, weWinXPHomeKN, weWinXPProKN, weWinXPStarter, weWinXPMediaCenter,
    weWinXPTablet, weWinVistaStarter, weWinVistaHomeBasic, weWinVistaHomeBasicN,
    weWinVistaHomePremium, weWinVistaBusiness, weWinVistaBusinessN,
    weWinVistaEnterprise, weWinVistaUltimate, weWin7Starter, weWin7HomeBasic,
    weWin7HomePremium, weWin7Professional, weWin7Enterprise, weWin7Ultimate);

For historical interest, you can check the NT-level edition too with the NtProductType function, it returns:

 TNtProductType =       (ptUnknown, ptWorkStation, ptServer, ptAdvancedServer,        
        ptPersonal, ptProfessional, ptDatacenterServer, 
        ptEnterprise, ptWebEdition);

Note that "N editions" are detected above. That's an EU (Europe) version of Windows, created due to EU anti-trust regulations. That's a pretty fine gradation of detection inside the JCL.

Here's a sample function that will help you detect Vista, and do something special when on Vista.

function IsSupported:Boolean;
begin
  case GetWindowsVersion of
     wvVista:  result := false; 
    else
      result := true;
  end;
end;

Note that if you want to do "greater than" checking, then you should just use other techniques. Also note that version checking can often be a source of future breakage. I have usually chosen to warn users and continue, so that my binary code doesn't become the actual source of breakage in the future.

Recently I tried to install an app, and the installer checked my drive free space, and would not install, because I had more than 2 gigabytes of free space. The 32 bit integer signed value in the installer became negative, breaking the installer. I had to install it into a VM to get it to work. Adding "smart code" often makes your app "stupider". Be wary.

Incidentally, I found that from the command line, you can run WMIC.exe, and type path Win32_OperatingSystem (The "Select * from Win32_OperatingSystem" didn't work for me). In future perhaps JCL could be extended to use the WMI information.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • 2
    I have used the JEDI code for the last 6-7 years. Much better not to have to write the code yourself! – Misha Nov 16 '11 at 00:57
  • 1
    Also when the new version of Windows Thingy comes out, JCL will be auto-magically updated by a team of trained monkeys. Just do an svn update and bob is the uncle of the you. – Warren P Nov 16 '11 at 01:01
  • The advantage to David Heffernan's XE2 method is that it's Firemonkey compatible and thus doesn't need any of the workarounds in order to get it working with FMX. For VCL or pre-XE2 though, i'd also agree with JEDI. – Scott P Apr 17 '12 at 00:30
2

The unit (GetWinVersionInfo) shown here detects up to Vista. I can't imagine updating it for Windows 7 would be that difficult. I don't think it tells you x86.x64 though.

Community
  • 1
  • 1
Vic Adam
  • 146
  • 2
  • Win32 major version is still the same, the Minor version goes up 1. So Vista+WSrv2003 was "6.0", and Win7+WinServ2008 is "6.1". It's pretty darn easy. – Warren P Nov 16 '11 at 01:01
1

On delphidabbler.com there is a complete article about getting operating system version including 64 bits versions. The article hasn't been updated to include Vista/7 though. But the same functions might still work.

Name
  • 3,430
  • 4
  • 30
  • 34