Jak pracovat s verzí OS ve svém programu

28. června 2007

O autorovi

Portrét

Jan Aubrecht
.NET vývojář a konzultant IS/IT
honza@intellisoft.cz

Honza se zabývá vývojem webových aplikací od roku 2000. Rád používá ASP.NET 2.0 a je přímo posedlý neustálým zlepšováním svých aplikací.

Ve volném čase je jeho vášní dobré jídlo a pití. Nejraději se baví přípravou středomořských specialit a báječnými víny z Francie.

Soubory ke stažení

Zdrojové kódy použité v článku a další související soubory si můžete stáhnout zde:

Další články

Článek vám představí jednoduchý nápad, jak získat verzi operačního systému a jak s ní dále pracovat ve své aplikaci. Informaci o verzi OS často využijete třeba při volání Win32 API, ve kterém se dostupnost funkcí často liší podle verze Windows.

Zjišťujeme verzi OS

Pro zjištění verze operačního systému je v prostředí .NET možné použít třídu System.Environment a její vlastnost OSVersion.

Pokud budete chtít zjistit, jestli je verze operačního systému, ve kterém běží vaše aplikace, shodná nebo vyšší s požadovanou verzí OS, bude váš kód vypadat nějak takto:

OperatingSystem current = Environment.OSVersion;
 
if (current.Platform == PlatformID.Win32NT && current.Version >= new Version(5, 1))
    Console.WriteLine("Používáte Windows XP a vyšší.");
else
    Console.WriteLine("Používáte jiný operační systém.");

Jistě uznáte, tento kód není zrovna dvakrát přehledný a příliš se nehodí pro opakované použití.

Pojďme se tedy podívat, jak si vytvořit vlastní třídu pro zjištění verze OS, která bude umožňovat jednoduché porovnání verzí pomocí běžně používaných operátorů.

Třída pro porovnání OS

Naše třída bude velmi podobná třídě Version s tím rozdílem, že bude obsahovat i informace o platformě. Budeme tak moci zjistit, zda daná verze OS spadá do rodiny Windows NT, Windows CE apod.

Protože naše třída bude opravdu jednoduchá, vynechám v článku nepodstatné detaily implementace a zaměřím se jen na důležité části kódu.

Rozhraní IComparable

Pro porovnání verzí OS použijeme rozhraní IComparable. Pomocí tohoto rozhraní bude možné určit třeba to, zda-li je daná verze OS vyšší nebo shodná s porovnávanou verzí.

Implementace rozhraní IComparable včetně jeho generické podoby vypadá následovně:

public int CompareTo(object obj)
{
    if (obj == null)
        return 1;
 
    OSVersion version = obj as OSVersion;
 
    if (version == null)
        throw new ArgumentException("The object to compare must be an OSVersion.", "obj");
 
    return this.CompareTo(version);
}
 
public int CompareTo(OSVersion other)
{
    if (other == null)
        return 1;
 
    if (_platform != other._platform)
    {
        if (_platform > other._platform)
            return 1;
        else
            return -1;
    }
    if (_major != other._major)
    {
        if (_major > other._major)
            return 1;
        else
            return -1;
    }
    if (_minor != other._minor)
    {
        if (_minor > other._minor)
            return 1;
        else
            return -1;
    }
    if (_revision != other._revision)
    {
        if (_revision > other._revision)
            return 1;
        else
            return -1;
    }
    return 0;
}

Rozhraní IEquatable

Dále v naší třídě implementujeme rozhraní IEquatable a přepíšeme metodu Equals. Pomocí metody Equals bude možné zjistit, zda-li jsou dvě verze OS stejné.

Implementace rozhraní IEquatable a metody Equals vypadá následovně:

public override bool Equals(object obj)
{
    return this.Equals(obj as OSVersion);
}
 
public bool Equals(OSVersion other)
{
    if (other != null)
        return
            (_platform == other._platform &&
            _major == other._major &&
            _minor == other._minor &&
            _revision == other._revision);
    else
        return false;
}

Implementace operátorů

Abychom mohli verze operačního systému mezi sebou snadno porovnávat, vytvoříme si i vlastní operátory. Díky nim se bude s naší třídou snadno pracovat a kód v naší aplikaci se stane čitelnějším.

Implementace operátorů bude velmi jednoduchá, protože budou používat metody CompareTo a Equals, které jsme vytvořili v předchozím odstavci.

public static bool operator ==(OSVersion a, OSVersion b)
{
    return object.Equals(a, b);
}
 
public static bool operator !=(OSVersion a, OSVersion b)
{
    return !object.Equals(a, b);
}
 
public static bool operator <(OSVersion a, OSVersion b)
{
    if (a == null)
        throw new ArgumentNullException("a");
 
    if (b == null)
        throw new ArgumentNullException("b");
 
    return a.CompareTo(b) < 0;
}
 
public static bool operator <=(OSVersion a, OSVersion b)
{
    if (a == null)
        throw new ArgumentNullException("a");
 
    if (b == null)
        throw new ArgumentNullException("b");
 
    return a.CompareTo(b) <= 0;
}
 
public static bool operator >(OSVersion a, OSVersion b)
{
    if (a == null)
        throw new ArgumentNullException("a");
 
    if (b == null)
        throw new ArgumentNullException("b");
 
    return a.CompareTo(b) > 0;
}
 
public static bool operator >=(OSVersion a, OSVersion b)
{
    if (a == null)
        throw new ArgumentNullException("a");
 
    if (b == null)
        throw new ArgumentNullException("b");
 
    return a.CompareTo(b) >= 0;
}

Základní verze Windows

Protože jsme od této třídy požadovali, aby práce s ní byla co nejjednodušší, zbývá nám vytvořit několik statických členů, které budou obsahovat informace o současných verzích Windows. Pomocí nich pak bude možné snadno zjistit, zda-li náš OS vyhovuje dané verzi Windows.

public static readonly OSVersion Windows95 = new OSVersion(PlatformID.Win32Windows, 4, 0, 0);
public static readonly OSVersion Windows98 = new OSVersion(PlatformID.Win32Windows, 4, 10, 0);
public static readonly OSVersion WindowsMe = new OSVersion(PlatformID.Win32Windows, 4, 90, 0);
public static readonly OSVersion WindowsNT = new OSVersion(PlatformID.Win32NT, 4, 0, 0);
public static readonly OSVersion Windows2000 = new OSVersion(PlatformID.Win32NT, 5, 0, 0);
public static readonly OSVersion WindowsXP = new OSVersion(PlatformID.Win32NT, 5, 1, 0);
public static readonly OSVersion Windows2003 = new OSVersion(PlatformID.Win32NT, 5, 2, 0);
public static readonly OSVersion WindowsVista = new OSVersion(PlatformID.Win32NT, 6, 0, 0);

Zároveň si vytvoříme property, která bude vracet verzi OS, který běží na našem počítači.

private static OSVersion _current;
 
public static OSVersion Current
{
    get
    {
        if (_current == null)
        {
            Version version = Environment.OSVersion.Version;
 
            _current = new OSVersion(Environment.OSVersion.Platform, version.Major, version.Minor, version.Revision);
        }
        return _current;
    }
}

Používáme OSVersion

Použití naší třídy je velmi snadné. Pro zjištění, zda-li je aktuální verze Windows větší nebo shodná s verzí Windows XP, použijeme následující kód:

if (OSVersion.Current >= OSVersion.WindowsXP)
    Console.WriteLine("Používáte Windows XP a vyšší.");

Pokud budeme chtít zjistit, zda-li je verze Windows z rodiny NT, použijeme tuto podmínku:

if (OSVersion.Current.Platform == PlatformID.Win32NT)
    Console.WriteLine("Používáte Windows z rodiny NT.");

Z příkladů je tedy patrné, že třídu OSVersion využijeme zejména v kódu, ve kterém potřebujeme pracovat s verzí Windows opakovaně.

Takovým případem může být např. volání Windows API, ve kterém jsou některé funkce podporovány pouze od určitých verzí Windows. Porovnání verze pomocí údajů ze System.Environment a třídy OperatingSystem by pak bylo zbytečně zdlouhavé a snižovalo by čitelnost kódu.

Kompletní zdrojové kódy příkladu si můžete stáhnout zde.