How can I get the version of Windows at runtime?

Question:
How can I get the version of Windows at runtime?

Answer:
Use the WinAPI call to GetVersion. GetVersion returns 3.1for Win 3.1, 3.11, WfW 3.11 and Win NTwhen called from a 16-bit app in anyof these environments, and 3.95 for Win95.

Also from a 16-bit app, you candetect NT with the following (thanks to Peter Below):

  Const WF_WINNT = $4000;  IsNT := (GetWinFlags and WF_WINNT) <> 0;

Unfortunately, the above doesn’t work for the 32-bit programs that you willbe compiling in Delphi 2.0. For that, you have to use the new Win32 APIcall: GetVersionEx. GetVersionEx supercedes GetVersion forall 32-bit applications. Instead of returning a numeric value as in GetVersion, it fills the contents of a variable of a record of type TOSVersionInfo, from which you can gather much moredetailed information about the Windows environment in which your program isrunning. Let’s look at the various record elements of TOSVersionInfo:

The Window.PAS file lists TOSVersionInfo as the following:

  TOSVersionInfoA = record    dwOSVersionInfoSize: DWORD;    dwMajorVersion: DWORD;    dwMinorVersion: DWORD;    dwBuildNumber: DWORD;    dwPlatformId: DWORD;    szCSDVersion: array[0..127] of AnsiChar; { Maintenance string for PSSusage }  end;  TOSVersionInfo := TOSVersionInfoA;

Notice that TOSVersionInfo is actually an assignment from another type,TOSVersionInfoA. There are actually two different version info types:TOSVersionInfoA and TOSVersionInfoW. The only difference between the two isin the szCSDVersion element. For the ‘A’ version info type, it’s ofan array of AnsiChar. The ‘W’ version info type is of an array of WideChar.

For our purposes, we’re only interested in the ‘A’ type. Look at the tablebelow to see what various elements represent:

Elements of TOSVersionInfo
ElementTypeDescription
dwOSVersionInfoSizeDWORDThis element carries the memory size of the TOSVersionInfo variable. Infact, to use GetVersionEx, you have to initialize this element toSizeOf(TOSVersionInfo). Otherwise, the function will return afailure.
dwMajorVersionDWORDThis is the major release number for Windows, which is on the left-handside of the period. For example, it would be the ‘3’ for version 3.51
dwMinorVersionDWORDThis is the portion of the release number on the right-hand side of theperiod. It would be the ’51’ in 3.51
dwBuildNumberDWORDBuild numbers aren’t readily apparent in Windows 3.1x versions, butshow up often in Win95 and NT. Just a finer level of versioning.
dwPlatformIdDWORDThis parameter tells you what level of Win32(s) your system is. Itreturns one of the three following constants:
  VER_PLATFORM_WIN32s = 0;  VER_PLATFORM_WIN32_WINDOWS = 1;  VER_PLATFORM_WIN32_NT = 2;
For most folks, this will probably be the element they’ll use the most.
szCSDVersionarray[0..127] of AnsiCharThis parameter provides additional textual information about theversion. For NT, it would list the Service Pack level installed.

How you employ this is entirely up to you. If you’re writing apps thatneed to know what version of Windowsthey’re running under, a function like this is essential. For example,let’s say you write a Winsock application under Windows 95. With that typeofapp, you can address either a 16-bit Winsock DLL or a32-bit Winsock. A good example of this is CompuServe InformationManager for Windows. It comes with its own 16-bit Winsock, but can also use WinNT’s native WSOCK32.DLL as its winsock. It’s obviously a matter oflooking under the hood of Windows to decide what to use.

I have source code to share with you. This isa simple unit I built to display in string format all the elements of theTOSVersionInfo type. If you want to build the form to use this code, justfollow these simple steps:

  1. Start a new project
  2. Drop the following on the form: six TEdits, six TLabels and a TButton.
  3. Then insert the code below for the TButton’s OnClick event, and that’s it!

The TLabels should be named dwOSVersionInfoSize, dwMajorVersion,dwMinorVersion, dwBuildNumber, dwPlatformId, and szCSDVersion, respectively.

unit u;interfaceuses  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,  StdCtrls;type  TForm1 = class(TForm)    Button1: TButton;    Edit1: TEdit;    Edit2: TEdit;    Edit3: TEdit;    Edit4: TEdit;    Edit5: TEdit;    Edit6: TEdit;    Label1: TLabel;    Label2: TLabel;    Label3: TLabel;    Label4: TLabel;    Label5: TLabel;    Label6: TLabel;    procedure Button1Click(Sender: TObject);  private    { Private declarations }  public    { Public declarations }  end;var  Form1: TForm1;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);var  verInfo : TOSVERSIONINFO;  str     : String;  I       : Word;begin  verInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);  if GetVersionEx(verInfo) then begin    Edit1.Text := IntToStr(verInfo.dwOSVersionInfoSize);    Edit2.Text := IntToStr(verInfo.dwMajorVersion);    Edit3.Text := IntToStr(verInfo.dwMinorVersion);    Edit4.Text := IntToStr(verInfo.dwBuildNumber);    case verInfo.dwPlatformId of      VER_PLATFORM_WIN32s         : Edit5.Text := ‘Win16 running Win32s’;      VER_PLATFORM_WIN32_WINDOWS  : Edit5.Text := ‘Win32 Windows, probablyWin95’;      VER_PLATFORM_WIN32_NT       : Edit5.Text := ‘WinNT, full 32-bit’;    end;    str := ”;    for I := 0 to 127 do      str := str + verInfo.szCSDVersion[I];    Edit6.Text := str;  endend;end.

The program above doesn’t have tangible uses other than getting information, but it’s a good way to dig into the TOSVersionInforecord. You can even use GetVersionEx on a splash screen to add a little”intelligence” to your apps.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: