which version of Windows is running

** note: this topic is outdated, needs to be adjusted for ME and XP **
The API is not exactly the same for the different Windows versions so it is sometimes usefull to know which Windows version is running. However the differences may disappear when Windows 95/98 and Windows NT mature (or when add-ons are installed) so checking for the Windows version may become less interesting: you should prefer to check for features instead versions.
This procedure here shows what Windows version you are running providing it's a 32-bit version. These are:
* Windows 3.1 with win32s
* Windows 95
* Windows 95 OSR 2
* Windows 98
* NT 3.51
* NT 4.0
* Windows 2000
* Windows CE also runs a subset of WIN32 but CE isn't interesting for us.
The procedure also shows buildnumber and CSDversion. What a CSDversion is, is not always clear: on NT it's a string describing the latest installed Service Pack. On 95 it can be anything but CSDversion will be "a" if Service Pack 1 is installed.

{windows.i}
 
DEFINE VARIABLE lpVersionInfo AS MEMPTR.
DEFINE VARIABLE dwPlatformID AS INTEGER NO-UNDO.
DEFINE VARIABLE chPlatformID AS CHARACTER NO-UNDO.
DEFINE VARIABLE BuildNumber AS INTEGER NO-UNDO.
DEFINE VARIABLE MajorVersion AS INTEGER NO-UNDO.
DEFINE VARIABLE MinorVersion AS INTEGER NO-UNDO.
DEFINE VARIABLE ReturnValue  AS INTEGER NO-UNDO.
 
SET-SIZE(lpVersionInfo)   = 148.
PUT-LONG(lpVersionInfo,1) = 148.
RUN GetVersionExA IN hpApi( GET-POINTER-VALUE(lpVersionInfo), 
                            OUTPUT ReturnValue).
dwPlatformID = GET-LONG(lpVersionInfo,17).
 
CASE dwPlatformID :
  WHEN 0 THEN chPlatformID = "Win32s on Windows 3.1".
  WHEN 1 THEN chPlatformID = "Win32 on Windows 95 or 98".
  WHEN 2 THEN chPlatformID = "Win32 on Windows NT".
END.        
 
CASE dwPlatformID :
  WHEN 1 THEN BuildNumber = GET-SHORT(lpVersionInfo,13).
  WHEN 2 THEN BuildNumber = GET-LONG (lpVersionInfo,13).
  /* what about 'when 0' for 3.1 with win32s ?? */
END.
 
/* You have Windows 95 OSR 2 if:
     dwPlatformID=1
         and 
     LOWORD(BuildNumber)=1111 (probably hex??)
   Unfortunately I have not had a chance to test that.
*/
 
CASE dwPlatformID :
  WHEN 1 THEN DO:
                 MinorVersion = GET-BYTE(lpVersionInfo,15).
                 MajorVersion = GET-BYTE(lpVersionInfo,16).
              END.
  OTHERWISE DO:
                 MajorVersion = GET-LONG(lpVersionInfo, 5).
                 MinorVersion = GET-LONG(lpVersionInfo, 9).
              END.
END.
 
MESSAGE "MajorVersion=" MajorVersion SKIP
        "MinorVersion=" MinorVersion SKIP
        "BuildNumber="  BuildNumber SKIP
        "PlatformID="   chPlatFormId SKIP
        "CSDversion="   GET-STRING(lpVersionInfo,21) SKIP(2)
        "on NT, CSDversion contains version of latest Service Pack" SKIP
        "on 95/98, CSDversion contains arbitrary extra info, if any"
        VIEW-AS ALERT-BOX.
 
SET-SIZE(lpVersionInfo) = 0.

NT4 Terminal Server Edition

To check if you are running on Terminal Server Edition you can use function ValidateProductSuite("Terminal Server").
Old documentation suggested that this function would be added to the WIN32 API in Windows 2000. But newer documentation for Windows 2000 describes a new function VerifyVersionInfo - to be called with wSuiteMask = VER_SUITE_TERMINAL. We will see.
In the meantime you can write your own function ValidateProductSuite in Progress 4GL and some registry functions. An example is on page Disallowing multiple instances of your application.

A couple of convenient functions

FUNCTION RunningWindows95 RETURNS LOGICAL () :
  /* returns TRUE if you are running Windows 95 */
 
  DEFINE VARIABLE Win95         AS LOGICAL NO-UNDO.
  DEFINE VARIABLE lpVersionInfo AS MEMPTR.
  DEFINE VARIABLE dwPlatformID  AS INTEGER NO-UNDO.
  DEFINE VARIABLE MinorVersion  AS INTEGER NO-UNDO.
  DEFINE VARIABLE ReturnValue   AS INTEGER NO-UNDO.
 
  SET-SIZE(lpVersionInfo)   = 148.
  PUT-LONG(lpVersionInfo,1) = 148.
  RUN GetVersionExA IN hpApi( GET-POINTER-VALUE(lpVersionInfo), 
                              OUTPUT ReturnValue).
  dwPlatformID = GET-LONG(lpVersionInfo,17).
  MinorVersion = GET-BYTE(lpVersionInfo,15).
 
  Win95 = (dwPlatformId=1 AND MinorVersion=0).
 
  SET-SIZE(lpVersionInfo) = 0.
  RETURN Win95.
 
END FUNCTION.
 
FUNCTION RunningWindows98 RETURNS LOGICAL () :
  /* returns TRUE if you are running Windows 98 */
 
  DEFINE VARIABLE Win98         AS LOGICAL NO-UNDO.
  DEFINE VARIABLE lpVersionInfo AS MEMPTR.
  DEFINE VARIABLE dwPlatformID  AS INTEGER NO-UNDO.
  DEFINE VARIABLE MinorVersion  AS INTEGER NO-UNDO.
  DEFINE VARIABLE ReturnValue   AS INTEGER NO-UNDO.
 
  SET-SIZE(lpVersionInfo)   = 148.
  PUT-LONG(lpVersionInfo,1) = 148.
  RUN GetVersionExA IN hpApi( GET-POINTER-VALUE(lpVersionInfo), 
                              OUTPUT ReturnValue).
  dwPlatformID = GET-LONG(lpVersionInfo,17).
  MinorVersion = GET-BYTE(lpVersionInfo,15).
 
  Win98 = (dwPlatformId=1 AND MinorVersion=10).
 
  SET-SIZE(lpVersionInfo) = 0.
  RETURN Win98.
 
END FUNCTION.
 
FUNCTION RunningWindowsNT4 RETURNS LOGICAL () :
  /* returns TRUE if you are running Windows NT4.
     I have not had a chance to test this yet */
 
  DEFINE VARIABLE NT4           AS LOGICAL NO-UNDO.
  DEFINE VARIABLE lpVersionInfo AS MEMPTR.
  DEFINE VARIABLE dwPlatformID  AS INTEGER NO-UNDO.
  DEFINE VARIABLE MajorVersion  AS INTEGER NO-UNDO.
  DEFINE VARIABLE ReturnValue   AS INTEGER NO-UNDO.
 
  SET-SIZE(lpVersionInfo)   = 148.
  PUT-LONG(lpVersionInfo,1) = 148.
  RUN GetVersionExA IN hpApi( GET-POINTER-VALUE(lpVersionInfo), 
                              OUTPUT ReturnValue).
 
  dwPlatformID = GET-LONG(lpVersionInfo,17).
  MajorVersion = GET-BYTE(lpVersionInfo, 5).
 
  NT4 = (dwPlatformId=2 AND MajorVersion=4).
 
  SET-SIZE(lpVersionInfo) = 0.
  RETURN NT4.
 
END FUNCTION.
 
FUNCTION RunningWindows2000 RETURNS LOGICAL () :
  /* returns TRUE if you are running Windows 2000 */
 
  DEFINE VARIABLE Win2000       AS LOGICAL NO-UNDO.
  DEFINE VARIABLE lpVersionInfo AS MEMPTR.
  DEFINE VARIABLE dwPlatformID  AS INTEGER NO-UNDO.
  DEFINE VARIABLE MajorVersion  AS INTEGER NO-UNDO.
  DEFINE VARIABLE ReturnValue   AS INTEGER NO-UNDO.
 
  SET-SIZE(lpVersionInfo)   = 148.
  PUT-LONG(lpVersionInfo,1) = 148.
  RUN GetVersionExA IN hpApi( GET-POINTER-VALUE(lpVersionInfo), 
                              OUTPUT ReturnValue).
 
  dwPlatformID = GET-LONG(lpVersionInfo,17).
  MajorVersion = GET-BYTE(lpVersionInfo, 5).
 
  Win2000 = (dwPlatformId=2 AND MajorVersion=5).
 
  SET-SIZE(lpVersionInfo) = 0.
  RETURN Win2000.
 
END FUNCTION.

Another convenient function

Brad Long added this procedure which is indeed convenient.

FUNCTION WINGetVersion RETURNS CHARACTER () :
/*-----------------------------------------------------------------------------
  Purpose: Calls the WINAPI function GetVersionExA to determine the version
           of the Windows operating system that is running on the machine.
    Notes: Returns "95" for Windows 95, "98" for Windows 98, "NT" for Windows NT
           Returns "undef" if unable to determine platform.
------------------------------------------------------------------------------*/
 
    DEFINE VARIABLE v_version-buf AS MEMPTR.
    DEFINE VARIABLE v_platform-id AS INTEGER NO-UNDO.
    DEFINE VARIABLE v_platform-desc AS CHARACTER NO-UNDO.
    DEFINE VARIABLE v_major-version AS INTEGER NO-UNDO.
    DEFINE VARIABLE v_minor-version AS INTEGER NO-UNDO.
    DEFINE VARIABLE v_return-value  AS INTEGER NO-UNDO.
 
    SET-SIZE(v_version-buf)   = 148.
    PUT-LONG(v_version-buf,1) = 148.
 
    RUN GetVersionExA (INPUT GET-POINTER-VALUE(v_version-buf),
                       OUTPUT v_return-value).
 
    v_platform-id = GET-LONG(v_version-buf,17).
 
    CASE v_platform-id:
        WHEN 1 THEN DO:
            v_minor-version = GET-BYTE(v_version-buf,15).
            v_major-version = GET-BYTE(v_version-buf,16).
        END.
        OTHERWISE DO:
            v_major-version = GET-LONG(v_version-buf,5).
            v_minor-version = GET-LONG(v_version-buf,9).
        END.
    END.
 
    CASE v_platform-id:
        WHEN 0 THEN v_platform-desc = "3.1".
        WHEN 1 THEN
        DO:
            IF v_minor-version EQ 0 THEN v_platform-desc = "95".
            ELSE IF v_minor-version GT 0 THEN v_platform-desc = "98".
            ELSE v_platform-desc = "undef".
        END.
        WHEN 2 THEN
            v_platform-desc = "NT".
        OTHERWISE
            v_platform-desc = "undef".
    END.
 
    SET-SIZE(v_version-buf) = 0.
 
    RETURN v_platform-desc.
 
END FUNCTION.

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

How to determine Vista x64 with +2GB memory

Can anyone extend the example code to include support for Vista?
I am running on Vista 64bit with 4GB of RAM.
Besides the problem that the example code does not 'recognize' Vista, I am also trying to determine the amount of RAM installed on my machine.

I use the function calls listed below, but the memory reported by the function call returns a negative value. Thanks.

Jos Hennen

procedure GetFreeSystemResources external "user.exe":
define input parameter flags as short.
define return parameter res as short.
end.

RUN GlobalMemoryStatus (INPUT-OUTPUT lpmemorystatus).

ASSIGN PctMemInUse = GET-LONG(lpmemorystatus,5)
TotPhysMem = GET-LONG(lpmemorystatus,9) / 1024
FreePhysMem = GET-LONG(lpmemorystatus,13) / 1024
ProcNum = GET-SHORT(lpsysteminfo,1)
ProcType = STRING(GET-LONG(lpsysteminfo,25))
SwapFree = GET-LONG(lpmemorystatus,21) / 1024.


The following function

The following function builds on what was already submitted here, revised to detect Windows 2000 and XP.
It does not detect Windows ME or Vista -- I do not have such machines available for testing.

FUNCTION OS-GetVersion RETURNS CHARACTER
  ( ) :
/*-----------------------------------------------------------------------------
  Purpose: Calls the WINAPI function GetVersionExA to determine the version
           of the Windows operating system that is running on the machine.
           Relies on "windows.i" to define the handle hpApi.
    Notes: Returns "95" for Windows 95, "98" for Windows 98, "NT" for Windows NT
           Returns "undef" if unable to determine platform.
           Does not yet detect Windows ME or Vista.
------------------------------------------------------------------------------*/

  def var v_version-buf as memptr.
  def var v_platform-id as integer no-undo.
  def var v_platform-desc as char no-undo.
  def var v_major-version as integer no-undo.
  def var v_minor-version as integer no-undo.
  def var v_return-value  as integer no-undo.

  set-size(v_version-buf)   = 148.
  put-long(v_version-buf,1) = 148.

  run GetVersionExA in hpApi ( input get-pointer-value(v_version-buf), output v_return-value ).

  v_platform-id = get-long(v_version-buf,17).

  case v_platform-id:
    when 1 then do:
      v_minor-version = get-byte(v_version-buf,15).
      v_major-version = get-byte(v_version-buf,16).
    end.
    otherwise do:
      v_major-version = get-long(v_version-buf,5).
      v_minor-version = get-long(v_version-buf,9).
    end.
  end.

  case v_platform-id:
    when 0 then v_platform-desc = "3.1".
    when 1 then
    do:
      if v_minor-version eq 0 then v_platform-desc = "95".
      else if v_minor-version gt 0 then v_platform-desc = "98".
      else v_platform-desc = "undef".
    end.
    when 2 THEN 
    DO:
      IF v_major-version EQ 5 THEN DO:
        IF v_minor-version EQ 1 THEN
          v_platform-desc = "XP".
        ELSE
          v_platform-desc = "2000".
      END.
      ELSE
        v_platform-desc = "NT".
    END.
    otherwise
      v_platform-desc = "undef".
  end.

  set-size(v_version-buf) = 0.

  return v_platform-desc.

END FUNCTION.   /* OS-GetVersion */

Updated for Windows 7?

I was wondering if you have an updated version of this that will detect a Windows 7 platform, since MS was so kind as to change everything with the "RUN AS ADMINISTRATOR" "feature" in Windows 7.

Bruce


let Standard LIBraries do the work for you

{slib/slibwin.i}

MESSAGE
win_cVersionName SKIP
win_cVersionStr SKIP
win_iProductType
VIEW-AS ALERT-BOX.

Standard Libraries can be found here on OEHIVE. Look on this screen to the bottom right under Active Project + Libraries

(btw the captcha thing on here is friggin annoying)


Worked First Time

Thanks so much. Nice utility!