[BlueLeaf1336]> PROGRAM>

OSのバージョンは?

historyTOP

2003/08/07:作成
2003/08/09:自信のない部分で何かが起きた時のための保険追加・見せる必要の無いコードを隠蔽
2005/02/19:「オペランドの拡張」警告が出ないように出ないように調節したものを別のところで作成したので、そこへのリンクを追加(HTML化しているソースでは出ます)。

downloadTOP

20030807iOsInfo.zip(2,530bytes)
20030809iOsInfo.zip(2,814bytes)(保険付き)
20050127winbeads.zip(186,982bytes)(オペランドの拡張とかいう警告が出なくしたもの)

memoTOP

MSのPlatform SDK(C言語)に書いてあるとおりにDelphiに翻訳し(ようとし)たものです。
びっくりするほど自身がありません...でも、誰かの役に立ちますように。

最初に断っておきますが、Windows2000(Pro,sp4)でしか試していません。つまり、コードの大部分は通過していません。 試した環境では望みどおりの答えが得られていますが、何かを何かし忘れてたりどれかがどうにかなっていたりする可能性があります。

codeTOP

(*
    #######################################################

    目的    :   OS のバージョン取得
    注意    :   全く自信なし
    履歴    :   2003/08/07 作成

    ------------------------------------------------------
    ms-help://MS.PSDK.1033/sysinfo/base/osversioninfo_str.htm
    ------------------------------------------------------

    #######################################################
*)

unit iOsInfo;

interface

uses
    Windows, SysUtils, Registry;

type
    TOSVersionInfoEx = record
        dwOSVersionInfoSize : DWORD;
        dwMajorVersion      : DWORD;
        dwMinorVersion      : DWORD;
        dwBuildNumber       : DWORD;
        dwPlatformId        : DWORD;
        szCSDVersion        : array[0..127] of AnsiChar;
        wServicePackMajor   : WORD;
        wServicePackMinor   : WORD;
        wSuiteMask          : WORD;
        wProductType        : BYTE;
        wReserved           : BYTE;
    end;

function    GetOsInfo(): string;

// Windows.pas
function GetVersionEx(var lpVersionInformation: TOSVersionInfoEx): BOOL; stdcall;
function GetVersionEx; external kernel32 name 'GetVersionExA';

implementation

// http://www.geocities.jp/ht_deko/ft0203.html
// http://plaza5.mbn.or.jp/~heropa/vb25.htm
const
    VER_NT_WORKSTATION       = 1;
    VER_NT_DOMAIN_CONTROLLER = 2;
    VER_NT_SERVER            = 3;
    VER_SUITE_SMALLBUSINESS            = $0001;
    VER_SUITE_ENTERPRISE               = $0002;
    VER_SUITE_BACKOFFICE               = $0004;
    VER_SUITE_TERMINAL                 = $0010;
    VER_SUITE_SMALLBUSINESS_RESTRICTED = $0020;
    VER_SUITE_DATACENTER               = $0080;
    VER_SUITE_PERSONAL                 = $0200;
    VER_SUITE_BLADE                    = $0400;

function    GetOsInfo(): string;
var
    osvi:TOSVersionInfoEx;
    res : Boolean;
    Key: HKEY;
    szProductType: string;
    dwBufLen: DWORD;
    lRet: integer;
begin
    Result := 'Unknown';

    // OSVERSIONINFOEX で GetVersionEx をやってみる 
    // 失敗したら OSVERSIONINFO でやってみる 

    // 初期化
    FillChar(osvi, SizeOf(TOSVersionInfoEx), #0);

    // 構造体サイズセット
    osvi.dwOSVersionInfoSize := SizeOf(TOSVersionInfoEx);

    // やってみる
    res := GetVersionEx(osvi);

    // 失敗したら
    if not res then
    begin
        // もうひとつの構造体で
        osvi.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
        // それもだめならあきらめな
        if not GetVersionEx(osvi) then Exit;
    end;

    // dwPlatformId で嫌になるほど場合わけ
    case osvi.dwPlatformId of

    // Windows NT 系.
    VER_PLATFORM_WIN32_NT:
        begin

            // もっと特定してみる
            if (osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 2) then
            begin
                Result := 'Microsoft Windows .NET Server 2003 family, ';
            end else
            if (osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 1) then
            begin
                Result := 'Microsoft Windows XP ';
            end else
            if (osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 0) then
            begin
                Result := 'Microsoft Windows 2000 ';
            end else
            begin
            if (osvi.dwMajorVersion <= 4) then
            begin
                Result := 'Microsoft Windows NT ';
            end else
                Result := 'Windows NT product family? ';
            end;

            // Windows NT 4.0 SP6 以降をもっと突っ込んで調べる.
            if res then
            begin

                // workstation タイプ
                if (osvi.wProductType = VER_NT_WORKSTATION) then
                begin
                    if (osvi.dwMajorVersion = 4) then
                    begin
                        Result := Result + 'Workstation 4.0 ';
                    end else
                    if (osvi.wSuiteMask and VER_SUITE_PERSONAL) = VER_SUITE_PERSONAL then
                    begin
                        Result := Result + 'Home Edition ';
                    end else
                    begin
                        Result := Result + 'Professional ';
                    end;
                end else

                // server タイプ
                if (osvi.wProductType = VER_NT_SERVER) then
                begin
                    if (osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 2) then
                    begin
                        if (osvi.wSuiteMask and VER_SUITE_DATACENTER) = VER_SUITE_DATACENTER then
                        begin
                            Result := Result + 'Datacenter Edition ';
                        end else
                        if (osvi.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
                        begin
                            Result := Result + 'Enterprise Edition ';
                        end else
                        if (osvi.wSuiteMask = VER_SUITE_BLADE) then
                        begin
                            Result := Result + 'Web Edition ';
                        end else
                        begin
                            Result := Result + 'Standard Edition ';
                        end;
                    end else
                    if (osvi.dwMajorVersion = 5) and (osvi.dwMinorVersion = 0) then
                    begin
                        if (osvi.wSuiteMask and VER_SUITE_DATACENTER) = VER_SUITE_DATACENTER then
                        begin
                            Result := Result + 'Datacenter Server ';
                        end else
                        if (osvi.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
                        begin
                            Result := Result + 'Advanced Server ';
                        end else
                        begin
                            Result := Result + 'Server ';
                        end;
                    end else
                    // Windows NT 4.0
                    begin
                        if (osvi.wSuiteMask and VER_SUITE_ENTERPRISE) = VER_SUITE_ENTERPRISE then
                        begin
                            Result := Result + 'Server 4.0, Enterprise Edition ';
                        end else
                        begin
                            Result := Result + 'Server 4.0 ';
                        end;
                    end;
                end;

            end else
            // Windows NT 4.0 SP5 以前のもの
            begin
                lRet := RegOpenKeyEx(
                            HKEY_LOCAL_MACHINE,
                            'SYSTEM\CurrentControlSet\Control\ProductOptions',
                            0,
                            KEY_QUERY_VALUE,
                            Key
                        );
                if lRet <> ERROR_SUCCESS then Exit;

                dwBufLen := 255;
                szProductType := '';
                SetLength(szProductType, dwBufLen);

                lRet := RegQueryValueEx(
                            Key,
                            'ProductType',
                            nil,
                            nil,
                            @szProductType[1],
                            @dwBufLen
                        );
                if (lRet <> ERROR_SUCCESS) or (dwBufLen > Length(szProductType)) then Exit;
                SetLength(szProductType, dwBufLen);

                RegCloseKey(Key);

                if UpperCase(szProductType) = 'WINNT' then
                begin
                    Result := Result + 'Workstation ';
                end else
                if UpperCase(szProductType) = 'LANMANNT' then
                begin
                    Result := Result + 'Server ';
                end else
                if UpperCase(szProductType) = 'SERVERNT' then
                begin
                    Result := Result + 'Advanced Server ';
                end;

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

            // サービスパックとかビルド番号とか

            if (osvi.dwMajorVersion = 4) and (lstrcmpi( osvi.szCSDVersion, 'Service Pack 6' ) = 0 ) then
            begin
                // SP6 ? SP6a?

                lRet := RegOpenKeyEx(
                            HKEY_LOCAL_MACHINE,
                            'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix\Q246009',
                            0,
                            KEY_QUERY_VALUE,
                            Key
                        );
                if (lRet = ERROR_SUCCESS) then
                begin
                    Result := Result + Format('Service Pack 6a (Build %d)', [osvi.dwBuildNumber and $FFFF]);
                end else

                // Windows NT 4.0 prior to SP6a
                begin
                    Result := Result + Format('%s (Build %d)', [osvi.szCSDVersion, osvi.dwBuildNumber and $FFFF]);
                end;
                RegCloseKey(Key);
            end else

            // Windows NT 3.51 and earlier or Windows 2000 and later
            begin
                Result := Result + Format('%s (Build %d)', [osvi.szCSDVersion, osvi.dwBuildNumber and $FFFF]);
            end;

        end;

    // Windows 95 系.
    VER_PLATFORM_WIN32_WINDOWS:
        begin
            // win95
            if (osvi.dwMajorVersion = 4) and (osvi.dwMinorVersion = 0) then
            begin
                Result := 'Microsoft Windows 95 ';
                if (osvi.szCSDVersion[1] = 'C') or (osvi.szCSDVersion[1] = 'B') then
                begin
                    Result := Result + 'OSR2 ';
                end;
            end else
            // win98
            if (osvi.dwMajorVersion = 4) and (osvi.dwMinorVersion = 10) then
            begin
                Result := 'Microsoft Windows 98 ';
                if ( osvi.szCSDVersion[1] = 'A') then
                begin
                    Result := Result + 'SE ';
                end;
            end else
            // winme
            if (osvi.dwMajorVersion = 4) and (osvi.dwMinorVersion = 90) then
            begin
                Result := 'Microsoft Windows Millennium Edition';
            end;
        end;

    // それ以外
    VER_PLATFORM_WIN32s:
        begin
            Result := 'Microsoft Win32s';
        end;

    end;

end;

end.

sample codeTOP

こんな感じで使えるはずです。

uses iOsInfo;
        :
ShowMessage(GetOsInfo());

ちなみにうちの環境ではこんな答えになっています。

Microsoft Windows 2000 Professional Service Pack 4 (Build 2195)

とりあえず正解です。

EOFTOP