Solved

Windows Version

Posted on 2004-10-15
19
258 Views
Last Modified: 2010-04-05
I use Win32Platform to check for the Windows version but what i would like to do is have a SMALL function that i can call with a minimum windows version and it will return true or false.

example:  

If i call with a minimum version of NT and the program is running on W2K or XP then return true
but if minimum is W2K and program is on an NT computer then return false.

I need it to work only with NT, 2K and XP regardless of the versions.

I'm looking for the shortest but complete way to do this.

Any help?
0
Comment
Question by:mi6agent
  • 8
  • 5
  • 3
  • +1
19 Comments
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12318568
If you use Delphi 5 or above, check the variables:
* Win32Platform
* Win32MajorVersion
* Win32MinorVersion
* Win32BuildNumber
* Win32CSDVersion

in the SysUtils unit. I bet most others would show you the appropiate API call, though... But from SysUtils, this would be the proper code for it:

procedure InitPlatformId;
var
  OSVersionInfo: TOSVersionInfo;
begin
  OSVersionInfo.dwOSVersionInfoSize := SizeOf(OSVersionInfo);
  if GetVersionEx(OSVersionInfo) then
    with OSVersionInfo do
    begin
      Win32Platform := dwPlatformId;
      Win32MajorVersion := dwMajorVersion;
      Win32MinorVersion := dwMinorVersion;
      Win32BuildNumber := dwBuildNumber;
      Win32CSDVersion := szCSDVersion;
    end;
end;

And yes, that procedute is in SysUtils... :)

Win32Platform is one of these values:
VER_PLATFORM_WIN32s      System is Win32s.
VER_PLATFORM_WIN32_WINDOWS      System is Windows 95. (or 95-based.)
VER_PLATFORM_WIN32_NT      System is Windows NT. (or NT-based.)
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12318585
From the Delphi help files: (Copy, Paste)

The OSVERSIONINFO data structure contains operating system version information. The information includes major and minor version numbers, a build number, a platform identifier, and descriptive text about the operating system. This structure is used with the GetVersionEx function.

typedef struct _OSVERSIONINFO{  
    DWORD dwOSVersionInfoSize;
    DWORD dwMajorVersion;
    DWORD dwMinorVersion;
    DWORD dwBuildNumber;
    DWORD dwPlatformId;
    TCHAR szCSDVersion[ 128 ];
} OSVERSIONINFO;
 
Members

dwOSVersionInfoSize
Specifies the size, in bytes, of this data structure. Set this member to sizeof(OSVERSIONINFO) before calling the GetVersionEx function.

dwMajorVersion
Identifies the major version number of the operating system. For example, for Windows NT version 3.51, the major version number is 3; and for Windows NT version 4.0, the major version number is 4.

dwMinorVersion
Identifies the minor version number of the operating system. For example, for Windows NT version 3.51, the minor version number is 51; and for Windows NT version 4.0, the minor version number is 0.

dwBuildNumber
Windows NT: Identifies the build number of the operating system.
Windows 95: Identifies the build number of the operating system in the low-order word. The high-order word contains the major and minor version numbers.

dwPlatformId
Identifies the operating system platform. This member can be one of the following values:

Value      Platform
VER_PLATFORM_WIN32s      Win32s on Windows 3.1.
VER_PLATFORM_WIN32_WINDOWS      Win32 on Windows 95.
VER_PLATFORM_WIN32_NT      Win32 on Windows NT.
 
szCSDVersion
Windows NT: Contains a null-terminated string, such as "Service Pack 3", that indicates the latest Service Pack installed on the system. If no Service Pack has been installed, the string is empty.
Windows 95: Contains a null-terminated string that provides arbitrary additional information about the operating system.
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12318733
My Simple Sample:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
const
WNT = 4;
W2K = 5;
WXP = 6;
implementation

{$R *.dfm}
Function CheckMinVersion(MinVersion: Cardinal):Boolean;
var
AFOSVersionInfo: TOSVersionInfo;
begin
      result := False;
      AFOSVersionInfo.dwOSVersionInfoSize := SizeOf(AFOSVersionInfo);
      If GetVersionEx(AFOSVersionInfo) then
      begin
            case AFOSVersionInfo.dwPlatformId of
                  VER_PLATFORM_WIN32s,
                  VER_PLATFORM_WIN32_WINDOWS: result := False;
         VER_PLATFORM_WIN32_NT:
                  begin
            Case MinVersion of
               WNT: Result := True;
                           W2K: Result := AFOSVersioninfo.dwMinorVersion >= 0;
                           WXP: Result := AFOSVersioninfo.dwMinorVersion = 1;
               end;
                  end;
            end;
      end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if not CheckMinVersion(WNT) then Halt(0); //run on NT and up
//if not CheckMinVersion(W2K) then Halt(0); //run on 2K and up
//if not CheckMinVersion(WXP) then Halt(0); //run just on XP
end;

end.
0
 

Author Comment

by:mi6agent
ID: 12318780
I know about using Win32Platform - Win32MajorVersion and Win32MinorVersion to get the Window version and can easily obtain that.

What i was looking for is a short way of "testing" if the window version is equal or better than what the program is running on.

At the moment i have made the routine but it uses a lot of IF statements

ie:

Minimum = what the minimum requirement is 0=NT 1=2K 3=XP

Function WinType(Minimum: Integer): boolean;

The function then uses Win32Platform - Win32MajorVersion and Win32MinorVersion  to detect the value of Windows
that the program is running on and compares to the Minimum value - returns true if the detected windows value is equal or greater than
Minimum

What i am looking for is a much shorter and efficient way to do it
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12318827
mi6agent that's exactly what i've posted!!!

F68 ;-)
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12318843
Function WinType(MinVersion: Cardinal):Boolean;
var
AFOSVersionInfo: TOSVersionInfo;
begin
     result := False;
     AFOSVersionInfo.dwOSVersionInfoSize := SizeOf(AFOSVersionInfo);
     If GetVersionEx(AFOSVersionInfo) then
     begin
          case AFOSVersionInfo.dwPlatformId of
               VER_PLATFORM_WIN32s,
               VER_PLATFORM_WIN32_WINDOWS: result := False;
         VER_PLATFORM_WIN32_NT:
               begin
            Case MinVersion of
              0: Result := True;
                       1: Result := AFOSVersioninfo.dwMinorVersion >= 0;
                       2: Result := AFOSVersioninfo.dwMinorVersion = 1;
               end;
               end;
          end;
     end;
end;
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12318873
Function WinType(Minimum: Integer): boolean;
begin
  if (Platform <> VER_PLATFORM_WIN32_NT) then begin
    Minimum = 0; // 95-98-ME
  end else begin
    if (Win32MajorVersion = < 5) then begin
      Minimum = 1; // NT
    end else begin
      if (Win32MinorVersion = 0) then begin
        Minimum = 2; // W2K
      end else begin
        Minimum = 3; // XP or better.
      end;
    end;
  end;
end;
0
 
LVL 17

Accepted Solution

by:
Wim ten Brink earned 250 total points
ID: 12318931
Oh, darned. Wrong... :-)

Function WinType(Minimum: Integer): boolean;
begin
  case Minimum of
    0: Result := (Platform = VER_PLATFORM_WIN32_NT);
    1: Result := (Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5);
    2: Result := (Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) and (Win32MinorVersion > 0);
  else Result := False;
  end;
end;
0
 
LVL 6

Assisted Solution

by:rbohac
rbohac earned 100 total points
ID: 12319089
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getting_the_system_version.asp

procedure TComputerInformation.GetWindowsVersion(var OSName:String; var OSServicePack: String; var MajorMinor:String);
var
  osvi             : TOSVersionInfo;
  bOsVersionInfoEx : boolean;
  key              : HKEY;
  szProductType    : array[0..79]of char;
  dwBuflen         : dword;
  Result:String;
begin
  // Try calling GetVersionEx using the OSVERSIONINFOEX structure.
  // If that fails, try using the OSVERSIONINFO structure.
  ZeroMemory(@osvi,sizeof(TOSVersionInfo));
  osvi.dwOSVersionInfoSize := sizeof(TOSVersionInfo);

  bOsVersionInfoEx := GetVersionEx(osvi);
  if(not bOsVersionInfoEx) then begin
    osvi.dwOSVersionInfoSize := VERSIONINFOSIZE;

    if(not GetVersionEx(osvi)) then begin
      Result := 'Could not get Windows-Version';
      exit;
    end;
  end;

  OSName:='';
  OSServicePack:='';
  MajorMinor:='';
 
  case osvi.dwPlatformId of
    // Test for the Windows NT product family.
    VER_PLATFORM_WIN32_NT:
      begin
        // Test for the specific product family.
        if(osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 2) then
          Result := 'Microsoft Windows Server 2003 family, ';

        if(osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 1) then
          Result := 'Microsoft Windows XP ';

        if(osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 0) then
          Result := 'Microsoft Windows 2000 ';

        if(osvi.dwMajorVersion <= 4) then
          Result := 'Microsoft Windows NT ';

        // Test for specific product on Windows NT 4.0 SP6 and later.
        if(bOsVersionInfoEx) then begin
          // Test for the workstation type.
          if(osvi.wProductType = VER_NT_WORKSTATION) then begin
            if(osvi.dwMajorVersion = 4) then
              Result := Result + 'Workstation 4.0 '
            else if(osvi.wSuiteMask and VER_SUITE_PERSONAL <> 0) then
              Result := Result + 'Home Edition '
            else
              Result := Result + 'Professional ';
          end
          // Test for the server type.
          else if(osvi.wProductType = VER_NT_SERVER) then begin
            if(osvi.dwMajorVersion = 5) and
              (osvi.dwMinorVersion = 2) then
            begin // Win 2003
              if(osvi.wSuiteMask and VER_SUITE_DATACENTER <> 0) then
                Result := Result + 'Datacenter Edition '
              else if(osvi.wSuiteMask and VER_SUITE_ENTERPRISE <> 0) then
                Result := Result + 'Enterprise Edition '
              else if(osvi.wSuiteMask = VER_SUITE_BLADE) then
                Result := Result + 'Web Edition '
              else
                Result := Result + 'Standard Edition ';
            end // Win 2000
            else if(osvi.dwMajorVersion = 5) and
              (osvi.dwMinorVersion = 0) then
            begin
              if(osvi.wSuiteMask and VER_SUITE_DATACENTER <> 0) then
                Result := Result + 'Datacenter Server '
              else if(osvi.wSuiteMask and VER_SUITE_ENTERPRISE <> 0) then
                Result := Result + 'Advanced Server '
              else
                Result := Result + 'Server ';
            end
            else begin // Windows NT 4.0
              if(osvi.wSuiteMask and VER_SUITE_ENTERPRISE <> 0) then
                Result := Result + 'Server 4.0, Enterprise Edition '
              else
                Result := Result + 'Server 4.0 ';
            end;
          end
        end
        // Test for specific product on Windows NT 4.0 SP5 and earlier
        else begin
          dwBufLen := sizeof(szProductType);

          if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            'SYSTEM\CurrentControlSet\Control\ProductOptions',0,
            KEY_QUERY_VALUE,key) = ERROR_SUCCESS) then
          try
            ZeroMemory(@szProductType,sizeof(szProductType));

            if(RegQueryValueEx(key,'ProductType',nil,nil,
              @szProductType,@dwBufLen) <> ERROR_SUCCESS) or
              (dwBufLen > sizeof(szProductType)) then
            ZeroMemory(@szProductType,sizeof(szProductType));
          finally
            RegCloseKey(key);
          end;

          if(lstrcmpi('WINNT',szProductType) = 0) then
            Result := Result + 'Workstation ';
          if(lstrcmpi('LANMANNT',szProductType) = 0) then
            Result := Result + 'Server ';
          if(lstrcmpi('SERVERNT',szProductType) = 0) then
            Result := Result + 'Advanced Server ';

          {Result := Format('%s%d.%d',[Result,osvi.dwMajorVersion,
            osvi.dwMinorVersion]);}
        end;

        // Display service pack (if any) and build number.
        if(osvi.dwMajorVersion = 4) and
          (lstrcmpi(osvi.szCSDVersion,'Service Pack 6') = 0) then
        begin
          // Test for SP6 versus SP6a.
          if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix\Q246009',
            0,KEY_QUERY_VALUE,key) = ERROR_SUCCESS) then

            OSServicePack := 'Service Pack 6a'
          else
            // Windows NT 4.0 prior to SP6a
            OSServicePack := Format('%s%s',[OSServicePack,
              osvi.szCSDVersion]);
          RegCloseKey(key);
        end
        // Windows NT 3.51 and earlier or Windows 2000 and later
        else begin
          OSServicePack := Format('%s%s',[OSServicePack,
            osvi.szCSDVersion]);
        end;
      end;
    // Test for the Windows 95 product family.
    VER_PLATFORM_WIN32_WINDOWS:
      begin
        if(osvi.dwMajorVersion = 4) and
          (osvi.dwMinorVersion = 0) then
        begin
          Result := 'Microsoft Windows 95 ';
          if(osvi.szCSDVersion[0] = 'C') or
            (osvi.szCSDVersion[0] = 'B') then Result := Result + 'OSR2 ';
        end;

        if(osvi.dwMajorVersion = 4) and
          (osvi.dwMinorVersion = 10) then
        begin
          Result := 'Microsoft Windows 98 ';
          //MessageBox(0,pchar(osvi.szCSDVersion[0]),'TEST',0);
          if(osvi.szCSDVersion[0] = 'A') then Result:= Result + 'SE ';
        end;

        if(osvi.dwMajorVersion = 4) and
          (osvi.dwMinorVersion = 90) then
        begin
          Result := 'Microsoft Windows Millennium Edition';
        end;
      end;
    VER_PLATFORM_WIN32s:
      Result := 'Microsoft Win32s';
  end;


  OsName := Result;
  MajorMinor := IntToStr(osvi.dwMajorVersion)+'.'+IntToStr(osvi.dwMinorVersion);
end;
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12319182
@rbohac, you're a bit late. :-)
But you are very complete in your answer.
0
 
LVL 6

Expert Comment

by:rbohac
ID: 12319219
ya, not fishing for points here. I just remember having to put some time into it before, so I thought I would share it
0
 

Author Comment

by:mi6agent
ID: 12319795
Ferruccio68 - i posted my reply to  Workshop_Alex  and did not see your post.

also, AFOSVersioninfo.dwMinorVersion >= 0; will always result in a True - any reason for using AFOSVersioninfo.dwMinorVersion >= 0;?

Workshop_Alex - shall test your code out soon

rbohac - thanks, but i was looking for "short and sweet"
0
 
LVL 22

Expert Comment

by:Ferruccio Accalai
ID: 12320025
@any reason for using AFOSVersioninfo.dwMinorVersion >= 0;?

Yes....
MinVersion is the value passed to the function:

Case MinVersion of
               0 : Result := True; // NT
               1: Result := AFOSVersioninfo.dwMinorVersion >= 0; //this is true even if is 0 or 1 thus W2K(0) or XP(1) and
               2: Result := AFOSVersioninfo.dwMinorVersion = 1; //but this is true only if it's XP(1)
               end;
So when we check for a >= W2K we check for AFOSVersioninfo.dwMinorVersion >= 0
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12320088
@Ferruccio68, you were just shown a bug in your code. :-) Accept it... :-P

Here:
  AFOSVersioninfo.dwMinorVersion >= 0;
This is ALWAYS true so you could have used
  Result := True;
It is always true since dwMinorVersion is a DWORD, an unsigned 32-bits integer...

You should have checked the major version number too... :-P
0
 
LVL 6

Expert Comment

by:rbohac
ID: 12320123
That looks to me like its more of a feature than a bug :)
0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12320511
No, it's a bug. Ferruccio68s code would return true on an NT system if you ask for Minimum=0 and Minimum=1. But it should return False for Minimum=1...
0
 
LVL 22

Assisted Solution

by:Ferruccio Accalai
Ferruccio Accalai earned 150 total points
ID: 12321120
yeah i see , you're right WA
I've stripped the code from a my old string return function and yes, missed the mayorversion check....

VER_PLATFORM_WIN32_NT: begin
                                          IF AFOSVersionInfo.dwMajorVersion <= 4 then
                           Result := 'Windows NT'
                                                                   else begin
                              case AFOSVersioninfo.dwMinorVersion of
                                 0: result := 'Windows 2000';
                                 1: result := 'Windows XP';
                              end;
                                                                   end;
                      end;
That's what happen writing here directly without testing in Delphi :)
BTW Workshop Alex at the end the best one is your function ....

F68 ;-)

0
 
LVL 17

Expert Comment

by:Wim ten Brink
ID: 12323579
Thanks, F68! :-)
0
 

Author Comment

by:mi6agent
ID: 12326483
Sorry for getting back to you all so late - guess my victory lap around the block for being able to spot a bug took longer than i thought :)

i tested your function out Workshop Alex and it is just what the doctor ordered.

BUT

I appreciate all of the help from all three of you - so i have increased the points so i can give some to all three of you.


Workshop Alex - original 200 points + 50 additional points
Ferruccio68  - 150 points
rbohac - 100 points

Thanks to all of you for your help.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now