I stało się... Dziś, po raz pierwszy od dłuższego czasu straciłem "programistyczną cierpliwość". Nie będę jednak wylewał tu swoich żalów - nie. Przecież nikomu nie jest to do szczęścia potrzebne. Ale każdą ludzką złość i frustrację można, przy odrobinie kombinatoryki, przedstawić w sposób nieco przyjemniejszy, z pożytkiem dla świata zawsze-młodych-duchem programistów.
Rzecz dotyczy wersji systemu Windows, jego komponentów, i takich tam...
Na potrzeby wykonywanego zawodu wybrałem system operacyjny Windows 7 Enterprise. Swego czasu z wielkim trudem przyszło mi powiedzieć "nie" tej części społeczności, która do dnia dzisiejszego wykorzystuje zasłużonego XP. Bynajmniej nie powiedziałem tego dosłownie. Po prostu projekty, nad którymi pracuję (ich przeważająca większość) z góry nie przewidują współpracy ze starszymi wersjami Windowsa. Z różnych względów... Przed 7-ką pojawiła się jednak Vista, znienawidzona przez niektórych, uwielbiana przez pozostałych. Przygotowywując oprogramowanie desktopowe programista nie może od tak sobie pominąć użytkowników tego systemu bez naprawdę dobrego powodu. Problemy pojawiają się z chwilą, w której programista wyraża chęć integracji programu z wybranym, wbudowanym komponentem systemu.
Mały przykład
Komponent ABC znajduje się w wersji systemu 7. Komponent ABC znajduje się także w wersji systemu Vista. Jednakże funkcjonalność Komponentu ABC różni się pomiędzy systemami, oferując tylko i wyłącznie pewną wspólną bazę. Jeżeli takich komponentów mamy wiele - mamy problem. Niektóre, naprawdę dobre pomysły kończą swój żywot. Oprogramowanie musi przecież być spójne w ramach danej rodziny systemów spod znaku Microsoftu. Ale co w przypadku znacznie mniejszych różnic, pojedynczych funkcji? Można przecież napisać dwie (niedługo także i trzy: Windows 8) wersje kodu, jedną dla Visty, drugą dla 7-ki. Z tym, że wersji systemu mamy więcej, znacznie więcej. Bowiem Komponentu ABC nie ma w wersjach Vista/7 Starter, a wersje Vista/7 Home Basic mają jeszcze bardziej ograniczoną funkcjonalność. O ServicePack'ach nie wspomnę.
Patrząc na problem ze szczytu tej programistycznej piramidy (tj. oczami użytkownika edycji Enterprise) łatwo stracić cierpliwość. Tym bardziej kiedy autorzy dostępnych w sieci rozmaitych kodów źródłowych błędnie przyjmują, że Windows Vista to Windows Vista, a Windows 7 to Windows 7 i nie kwapią się sprawdzić "ile rzeczywiście jest cukru w cukrze".
Widziałem już wiele "sposobów" sprawdzania wersji systemu pod kątem współpracy z wybranymi komponentami Windowsa, ale każdy miał swoje wady, większość działała połowicznie. Droga koleżanko i drogi kolego, jeżeli Twoje oprogramowanie wykorzystuje specyficzne dla danej edycji funkcje systemowe to Twoim obowiązkiem jest wiedzieć z jakim konkretnie systemem masz do czynienia - co do najmniejszych różnic!
Jeśli jesteś entuzjastą technologii .NET, możesz poddać poniższy kod drobnej modyfikacji i pozbędziesz się problemu... ekhm... "raz na zawsze" :) Użytkownicy Javy oraz innych języków będą musieli poszukać odpowiedniej implementacji WMI (Windows Management Instrumentation) dla swojej platformy programistycznej. A takie z całą pewnością są dostępne, więc głowa do góry.
private void OperatingSystemInfo()
{
// Vista i wyżej - OSVersion nie określa zawartości cukru w cukrze
if (System.Environment.OSVersion.Version.Major >= 6)
{
System.Management.ManagementObjectSearcher mos = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
System.Management.ManagementObjectCollection moc = mos.Get();
foreach (System.Management.ManagementObject mo in moc)
{
foreach (System.Management.PropertyData property in mo.Properties)
{
Console.WriteLine("{0} {1}", property.Name, property.Value);
}
}
}
}
Zwróć uwagę na pole OperatingSystemSKU, które definiuje aktualnie zainstalowaną odmianę systemu operacyjnego. Wszystkie właściwości oraz ich dokładny opis przedstawia MSDN:
msdn.microsoft.com/en-us/library/windows/desktop/aa394239(v=vs.85).asp...
Jeżeli interesuje nas wyłącznie edycja Starter prościej jest wywołać funkcję systemową GetSystemMetrics, której zastosowanie nie ogranicza się wyłącznie do poniższej czynności. Więcej na MSDN:
msdn.microsoft.com/en-us/library/windows/desktop/ms724385(v=vs.85).asp...
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int smIndex);
private static int SM_STARTER = 88;
private bool IsStarter()
{
return GetSystemMetrics(SM_STARTER) != 0;
}
Powodzenia!