Wersja systemu Windows
mgyver
Jak wiadomo Microsoft wypuszcza coraz to nowsze wersje systemu Windows. Istnieje więc potrzeba rozpoznawania nowszych wersji tego systemu, ale kod w delphi potrzebny do tego najczęściej pozostaje stary i nieaktualny. Proponuję wiec skorzystanie z poniższego modułu który na stan obecny rozpoznaje wersje Windows do Windows Seven włącznie. Zapraszam również do aktualizacji kodu tego arta w przyszłości.
Moduł OS_Version:
unit OS_Version;
interface
uses Windows, Registry, SysUtils;
type
TWindowsType = (winUnknown, win31, win95, win95OSR2, winNT, win98, win98se, winME, win2000, winXP,
winXPx64, win2003, win2003R2, winVista, winServer2008, winServer2008R2, winSeven);
TWindowsProductType = ( wptWorkstation, wptServer );
TWindowsProductKind = record
AsString : String;
AsType : TWindowsProductType;
end;
TWindowsProductVersion = record
AsString : String;
Major : Integer;
Minor : Integer;
end;
TWindowsTypeEx = record
Full : String;
Product : String;
Kind : TWindowsProductKind;
OSKind : TWindowsType;
OSVersion : TWindowsProductVersion;
Server : Boolean;
OSBuild : Integer;
ServicePack : String;
ServicePackVersion : TWindowsProductVersion;
end;
function GetWindowsOS: TWindowsTypeEx;
implementation
function IsBitSet(const val: Longint; const TheBit: Byte): Boolean;
begin
Result := (val and (1 shl TheBit)) <> 0;
end;
function GetWindowsOS: TWindowsTypeEx;
const
VER_NT_WORKSTATION : integer = $1;
VER_NT_DOMAIN_CONTROLLER : integer = $2; // The system is a domain controller.
VER_NT_SERVER : integer = $3; // The system is a server.
VER_WORKSTATION_NT : integer = $40000000;
SM_SERVERR2 : integer = 89;
VER_SUITE_SMALLBUSINESS : integer = 0; // Bit 0 { int 1 } = Microsoft Small Business Server was once installed on the system,
// but may have been upgraded to another version of Windows.
VER_SUITE_SMALLBUSINESS_RESTRICTED : integer = 5; // Bit 5 { int 32 } = Microsoft Small Business Server is installed with the restrictive client license in force.
VER_SUITE_ENTERPRISE : integer = 1; // Bit 1 { int 2 } = Windows Server "Longhorn", Enterprise Edition,
// Windows Server 2003, Enterprise Edition,
// Windows 2000 Advanced Server,
// Windows NT Server 4.0 Enterprise Edition is installed.
// Refer to the Remarks section for more information about this bit flag.
VER_SUITE_BACKOFFICE : integer = 2; // Bit 2 { int 4 } = Microsoft BackOffice components are installed.
VER_SUITE_COMMUNICATIONS : integer = 3; // Bit 3 { int 8 }
VER_SUITE_TERMINAL : integer = 4; // Bit 4 { int 16 } = Terminal Services is installed.
// Refer to the Remarks section for more information about this bit flag.
VER_SUITE_EMBEDDEDNT : integer = 6; // Bit 6 { int 64 } = Windows XP Embedded is installed.
VER_SUITE_DATACENTER : integer = 7; // Bit 7 { int 128 } = Windows Server "Longhorn", Datacenter Edition
// Windows Server 2003, Datacenter Edition
// Windows 2000 Datacenter Server is installed.
VER_SUITE_SINGLEUSERTS : integer = 8; // Bit 8 { int 256 } = Terminal server in remote admin mode
VER_SUITE_PERSONAL : integer = 9; // Bit 9 { int 512 } = Windows XP Home Edition is installed.
VER_SUITE_BLADE : integer = 10; // Bit 10 { int 1024 } = Windows Server 2003, Web Edition is installed.
VER_SUITE_COMPUTE_SERVER : integer = 14; // Bit 14 { int 16384 } = Windows Server 2003, Compute Cluster Edition is installed.
VER_SUITE_STORAGE_SERVER : integer = 13; // Bit 13 { int 8192 } = Windows Storage Server 2003 R2 is installed.
PROCESSOR_ARCHITECTURE_AMD64 : integer = 9; // x64 (AMD or Intel)
PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 : integer = 10; // WOW64
PROCESSOR_ARCHITECTURE_IA64 : integer = 6; // Intel Itanium Processor Family (IPF)
PROCESSOR_ARCHITECTURE_INTEL : integer = 0; // x86
PROCESSOR_ARCHITECTURE_UNKNOWN : integer = $ffff;
type
OSVERSIONINFOEX = packed record
dwOSVersionInfoSize: DWORD;
dwMajorVersion: DWORD;
dwMinorVersion: DWORD;
dwBuildNumber: DWORD;
dwPlatformId: DWORD;
szCSDVersion: Array [0..127] of Char;
wServicePackMajor: WORD;
wServicePackMinor: WORD;
wSuiteMask: WORD;
wProductType: BYTE;
wReserved: BYTE;
End;
TOSVersionInfoEx = OSVERSIONINFOEX;
POSVersionInfoEx = ^TOSVersionInfoEx;
PSystemInfo = ^System_Info;
TSIProc = procedure( SI : PSystemInfo ); stdcall;
PSIProc = TSIProc;
var OSVI : TOSVersionInfoEx;
OS : TOSVersionInfo;
IsOSVIEx : boolean;
SI : SYSTEM_INFO;
pSI : PSIProc;
pVer : POSVersionInfo; // old version!
r : TRegistry;
ts : string;
begin
// Try calling GetVersionEx using the OSVERSIONINFOEX structure.
// If that fails, try using the OSVERSIONINFO structure.
ZeroMemory(@OSVI,SizeOf(OSVI));
osvi.dwOSVersionInfoSize := sizeof(OSVI);
pVer := @OSVI;
IsOSVIEx := GetVersionEx ( pVer^ );
if not IsOSVIEx then
begin
osvi.dwOSVersionInfoSize := sizeof(OS);
if not GetVersionEx ( pVer^ ) then
exit;
end;
Result.OSVersion.AsString := Format('%d.%d',[OSVI.dwMajorVersion,OSVI.dwMinorVersion]);
Result.OSVersion.Major := OSVI.dwMajorVersion;
Result.OSVersion.Minor := OSVI.dwMinorVersion;
Result.ServicePackVersion.AsString := format('%d.%d',[OSVI.wServicePackMajor,OSVI.wServicePackMinor]);
Result.ServicePackVersion.Major := OSVI.wServicePackMajor;
Result.ServicePackVersion.Minor := OSVI.wServicePackMinor;
Result.Server := False;
Result.OSBuild := OSVI.dwBuildNumber;
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 = 6 ) and ( osvi.dwMinorVersion = 1 ) then
begin
if( osvi.wProductType = VER_NT_WORKSTATION ) then
begin
Result.Product := 'Microsoft Windows Seven';
Result.OSKind := winSeven;
end
else
begin
Result.Product := 'Microsoft Windows Server 2008 R2';
Result.OSKind := winServer2008R2;
end;
end;
if ( osvi.dwMajorVersion = 6 ) and ( osvi.dwMinorVersion = 0 ) then
begin
if( osvi.wProductType = VER_NT_WORKSTATION ) then
begin
Result.Product := 'Microsoft Windows Vista';
Result.OSKind := winVista;
end
else
begin
Result.Product := 'Microsoft Windows Server 2008';
Result.OSKind := winServer2008;
end;
end;
if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 2 ) then
begin
// Use GetProcAddress to avoid load issues on Windows 2000
pSI := GetProcAddress( GetModuleHandle('kernel32.dll'), 'GetNativeSystemInfo');
try
pSI(@SI);
except
end;
if ( GetSystemMetrics( SM_SERVERR2 ) <> 0 ) then
begin
Result.Product := 'Microsoft Windows Server 2003 R2';
Result.OSKind := win2003R2;
end
else if ( osvi.wProductType = VER_NT_WORKSTATION ) and
( SI.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 ) then
begin
Result.Product := 'Microsoft Windows XP Professional x64 Edition';
Result.OSKind := winXPx64;
end
else
begin
Result.Product := 'Microsoft Windows Server 2003 family';
Result.OSKind := win2003;
end;
end;
if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 1 ) then
begin
Result.Product := 'Microsoft Windows XP';
Result.OSKind := winXP;
end;
if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 0 ) then
begin
Result.Product := 'Microsoft Windows 2000';
Result.OSKind := win2000;
end;
if ( osvi.dwMajorVersion <= 4 ) then
begin
Result.Product := 'Microsoft Windows NT';
Result.OSKind := winNT;
end;
// Test for specific product on Windows NT 4.0 SP6 and later.
if( IsOSVIEx ) then
begin
if ( osvi.wProductType = VER_NT_WORKSTATION ) and
( si.wProcessorArchitecture <> PROCESSOR_ARCHITECTURE_AMD64) then
begin
Result.Kind.AsType := wptWorkstation;
if( osvi.dwMajorVersion = 4 ) then
Result.Kind.AsString := 'Workstation 4.0'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_PERSONAL ) then
Result.Kind.AsString := 'Home Edition'
else
Result.Kind.AsString := 'Professional';
end
// Test for the server type.
else if ( osvi.wProductType = VER_NT_SERVER ) or
( osvi.wProductType = VER_NT_DOMAIN_CONTROLLER ) then
begin
Result.Server := True;
Result.Kind.AsType := wptServer;
// 2003 Server family
if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 2 ) then
begin
if ( si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_IA64 ) then
begin
if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then
Result.Kind.AsString := 'Datacenter Edition for Itanium-based Systems'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then
Result.Kind.AsString := 'Enterprise Edition for Itanium-based Systems';
end
else if ( si.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_AMD64 ) then
begin
if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then
Result.Kind.AsString := 'Datacenter x64 Edition'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then
Result.Kind.AsString := 'Enterprise x64 Edition'
else
Result.Kind.AsString := 'Standard x64 Edition'
end
else
begin
if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then
Result.Kind.AsString := 'Datacenter Edition'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then
Result.Kind.AsString := 'Enterprise Edition'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_BLADE ) then
Result.Kind.AsString := 'Web Edition'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_SMALLBUSINESS ) then
Result.Kind.AsString := 'Small Business Server'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_SMALLBUSINESS_RESTRICTED ) then
Result.Kind.AsString := 'Small Business Server ( Restricted )'
else
Result.Kind.AsString := 'Standard Edition'
end;
end
// 2000 Server family
else if ( osvi.dwMajorVersion = 5 ) and ( osvi.dwMinorVersion = 0 ) then
begin
Result.Product := 'Microsoft Windows Server 2000 family';
if IsBitSet(osvi.wSuiteMask, VER_SUITE_DATACENTER ) then
Result.Kind.AsString := 'Datacenter Server'
else if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then
Result.Kind.AsString := 'Advanced Server'
else
Result.Kind.AsString := 'Server';
end
// Windows NT 4.0
else
begin
if IsBitSet(osvi.wSuiteMask, VER_SUITE_ENTERPRISE ) then
Result.Kind.AsString := 'Server 4.0 Enterprise Edition'
else
Result.Kind.AsString := 'Server 4.0';
end;
end;
end
// Test for specific product on Windows NT 4.0 SP5 and earlier
else
begin
r := TRegistry.Create;
r.RootKey := HKEY_LOCAL_MACHINE;
r.OpenKey('SYSTEM\CurrentControlSet\Control\ProductOptions',False);
ts := AnsiUpperCase(R.ReadString('ProductType'));
r.Free;
if ansisametext(ts,'WINNT') then
begin
Result.Kind.AsString := 'Workstation';
end
else if ansisametext(ts,'LANMANNT') then
begin
Result.Kind.AsString := 'Server';
end
else if ansisametext(ts,'SERVERNT') then
begin
Result.Kind.AsString := 'Advanced Server';
end;
Result.Kind.AsString := Result.Kind.AsString + format(' %d.%d ',[osvi.dwMajorVersion, osvi.dwMinorVersion] );
end;
// Display service pack (if any) and build number.
if ( osvi.dwMajorVersion = 4 ) and ansisametext( osvi.szCSDVersion, 'Service Pack 6' ) then
begin
r := TRegistry.Create;
r.RootKey := HKEY_LOCAL_MACHINE;
// Test for SP6 versus SP6a.
if r.OpenKey('SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix\Q246009',False) then
Result.ServicePack := format('Service Pack 6a (Build %d) ' + #13#10, [osvi.dwBuildNumber and $FFFF])
else
Result.ServicePack := format('%s (Build %d) ' + #13#10, [osvi.szCSDVersion,
osvi.dwBuildNumber and $FFFF]);
r.Free;
end
// Windows NT 3.51 and earlier or Windows 2000 and later
else
Result.ServicePack := format('%s (Build %d) ' + #13#10, [osvi.szCSDVersion,
osvi.dwBuildNumber and $FFFF]);
Result.Full := format('%s %s',[Result.Product,Result.Kind.AsString]);
end;
// Test for the Windows 95 product family.
VER_PLATFORM_WIN32_WINDOWS :
begin
Result.Kind.AsType := wptWorkstation;
Result.ServicePack := osvi.szCSDVersion;
if (osvi.dwMajorVersion = 4 ) and ( osvi.dwMinorVersion = 0 ) then
begin
Result.Product := 'Microsoft Windows 95';
Result.OSKind := win95;
if ( osvi.szCSDVersion[1] = 'C' ) or ( osvi.szCSDVersion[1] = 'B' ) then
begin
Result.Kind.AsString := 'OSR2';
Result.OSKind := win95OSR2;
end;
Result.Full := format('%s %s',[Result.Product,Result.Kind.AsString]);
end;
if (osvi.dwMajorVersion = 4 ) and ( osvi.dwMinorVersion = 10 ) then
begin
Result.Product := 'Microsoft Windows 98';
Result.OSKind := win98;
if ( osvi.szCSDVersion[1] = 'A' ) then
begin
Result.Kind.AsString := 'SE';
Result.OSKind := win98se;
end;
Result.Full := format('%s %s',[Result.Product,Result.Kind.AsString]);
end;
if (osvi.dwMajorVersion = 4 ) and ( osvi.dwMinorVersion = 90) then
begin
Result.Product := 'Microsoft Windows Millennium Edition';
Result.Full := format('%s',[Result.Product]);
Result.OSKind := winME;
end;
end;
VER_PLATFORM_WIN32s:
begin
Result.Product := 'Microsoft Win32s';
Result.Kind.AsType := wptWorkstation;
Result.Full := format('%s',[Result.Product]);
Result.OSKind := win31;
end;
end;
Result.ServicePack := Trim(Result.ServicePack);
end;
end.
Przykładowe użycie tego modułu wygląda tak:
procedure TForm1.Button1Click(Sender: TObject);
var
OS: TWindowsTypeEx;
begin
OS:= GetWindowsOS;
Memo.Clear;
with Memo.Lines do
begin
Add('Pełna nazwa systemu: ' + OS.Full);
Add('Nazwa systemu: ' + OS.Product);
Add('Rodzaj systemu: ' + OS.Kind.AsString);
Add('Wersja systemu: ' + OS.OSVersion.AsString);
Add('Service pack: ' + OS.ServicePack);
Add('Wersja service pack: ' + OS.ServicePackVersion.AsString);
end;
end;
Mój program napisany w języku C (źródła Dev-C++, Open Watcom IDE) do sprawdzania wersji systemu
Windows (od 3.1 do 8). Znajduje się na stronie (w budowie): http://romanworkshop.zz.mu/
w dziale WinAPI/Windows Version Checker.
@Ktos: msdn polecam jako lekturę obowiązkową przed dobranocką
A jak już jesteś taki oświecony w temacie to może zaprezentujesz nam swój kod albo chociaż przetestujesz kod który podałem. Wtedy nawet chętnie przyjmę kilka słów krytyki co do moich wypocin.
Może też być Se7en i mi to wisi jak jest. Taki miałem kaprys.
Nie "Windows Seven", a "Windows 7" jak już, bo tak się ten system nazywa.
Nawiasem - nie uruchamiałem tej funkcji (nie mam Delphi), ale tak z analizy kodu to mam wrażenie, że o ile rozróżnia te tzw. wersje SKU np. dla Windows Server 2003, to już nie robi tego dla Visty czy dla Servera 2008. Wraz z Vistą namnożyło się ich trochę, może to być dla niektórych istotne.
Dla Windows Vista i nowszych można by skorzystać z funkcji GetProductInfo(). Przydatne też może być skorzystanie z GetSystemMetrics() by wykryć (podobnie jak jest zrobione wykrycie 2003 R2) specyficzne odmiany XP jak Tablet PC Edition, Media Center Edition czy Starter.
A tak nawiasem to nadal nie uwzględnione - nawet przy moich uwagach - są wszystkie wersje Windows ;-)
U mnie funkcja GetWinowsOS wypluwa to:
Pełna nazwa systemu: Microsoft Windows XP Professional
Nazwa systemu: Microsoft Windows XP
Rodzaj systemu: Professional
Wersja systemu: 5.1
Service pack: Dodatek Service Pack 3 (Build 2600)
Wersja service pack: 3.0