Úvod do verzí
Pro úplnost začněme u starších verzí. Verze .NET Framework 3.0 a 3.5 nainstalováním rozšířily .NET Framework 2.0 o nové funkce (WPF, WCF a podobně). Používali jeho CLR, ale víceméně jej nijak nemodifikovaly. Tyto jednotlivé verze tedy přidávaly nové knihovny, nemodifikovaly však již ty existující (když nepočítáme opravy bugů a jiné drobnosti).
.NET Framework 4.5 je na rozdíl od nich plnohodnotnou aktualizací verze .NET Framework 4 a zároveň jeho rozšířením (například podpora async/await konstrukce). Důležité tedy je, že krom nových knihoven také přidává a modifikuje funkce existujících knihoven verze 4 a to včetně jeho CLR.
Instalace .NET 4.5
Verze 4.5 se tedy neinstaluje “vedle” ostatních verzí, ale plně přes verzi 4. To je také důvod proč ve složce %WINDIR%\Microsoft.NET\Framework po instalaci nenajdete očekávanou složku v4.5 (viz obrázek).
Hlavní knihovny .NET Framework 4.0 a následně i aktualizace na verzi 4.5 jsou instalovány do výše uvedeného adresáře do podsložky v4.030319. Podívejme se nyní na dalším obrázku na knihovnu mscorlib.dll v kopii verze před a po aktualizaci na .NET 4.5.
Zajímavé je, že po aktualizaci nebyla změněna verze knihovny (zůstává 4.0.30319). Na první pohled se změnilo pouze číslo sestavení a velikost souboru.
Microsoft nicméně tvrdí, že provedené změny jádra v aktualizaci na .NET 4.5 jsou plně zpětně kompatibilní a neměl by být tedy žádný problém po její instalaci dále spouštět aplikace napsané pro původní verzi 4.0.
Detekce .NET 4.5
Popsaný způsob aktualizace může způsobit (subjektivně) nečekané chování při spouštění aplikace napsané pro .NET 4.5 na systému, kde je nainstalovaný pouze .NET 4. Osobně bych čekal, že taková aplikace ve výchozím stavu nepůjde ani spustit. Opak je však pravdou a aplikace nastartuje. Pokud jste nevyužili žádnou novou funkci z verze 4.5, bude pravděpodobně i fungovat. Problém samozřejmě nastane, pokud kdekoliv uvnitř aplikace zavoláte metodu, která ve verzi 4.0 ještě neexistuje. Aplikace se v tu chvíli sesype.
Příkladem může být následující kód, který vypíše verzi knihoven .NET Frameworku a následně použije konstrukci “async/await” z .NET 4.5.
static void Main(string[] args)
{
Console.WriteLine("Aplikace pro .NET 4.5.");
Console.WriteLine("Aktuální verze: {0}", Environment.Version);
Console.WriteLine("Stiskni ENTER...");
Console.ReadLine();
Console.WriteLine("Volám 'async' metodu.");
SomeAsyncMethod().Wait();
Console.ReadLine();
}
private static async Task SomeAsyncMethod()
{
await Task.Run(() => Thread.Sleep(TimeSpan.FromSeconds(1)));
Console.WriteLine("Metoda 'async' dokončena.");
}
Na systému s .NET 4 se aplikace spustí a spadne až ve chvíli, kdy dojde na použití “async/await”. Konkrétněji ve chvíli, kdy se snaží využít rozhraní IAsyncStateMachine (vnitřně využívané pro realizaci async konstrukcí) dostupné až v novější verzi knihovny mscorlib.dll.
Na systému s .NET 4.5 vše funguje jak má:
Detekce za běhu pomocí kódu
Předpokládám, že ve většině případů budeme chtít detekovat přítomnost .NET Frameworku 4.5 již při spuštění aplikace a vyvarovat se tak nečekanému pádu za běhu.
Detekce .NET 4.5 podle verze knihoven není dost dobře možná, protože se liší pouze ve verzi sestavení a to by v ideálním případě neměl být rozhodovací parametr.
Dalším možným řešením je použití reflexe a kontrola nějakého typu, který je přítomný až od verze 4.5. Například toto řešení jsem nalezl na diskusních fórech stackoverflow:
public static bool IsNet45OrNewer()
{
// Class "ReflectionContext" exists from .NET 4.5 onwards
return Type.GetType("System.Reflection.ReflectionContext", false) != null;
}
Další z možností, jak rozhodnout, zda je .NET 4.5 nainstalovaný je práce s registry. Takovou možnost však nemám v tuto chvíli vyzkoušenou.
Detekce při spouštění aplikace
Programová detekce kódem je vhodná především uvnitř samostatných komponent. Pokud však píšeme celou aplikaci, lze omezit potřebný .NET Framework na úrovni konfiguračního souboru. Konkrétně můžeme do App.config zapsat následující kód - což je mimochodem i výchozí stav v šablonách Visual Studia při založení konzolové aplikace:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
Po spuštění v prostředí bez .NET 4.5 se zobrazí chybová hláška a aplikace se nespustí:
Obdoba pro web.config u webových aplikací je:
<configuration>
<system.web>
<compilation debug="true" strict="false" explicit="true" targetFramework="4.5" />
</system.web>
</configuration>
Pokus o spuštění takto nakonfigurované webové aplikace na serveru bez .NET 4.5 skončí s chybou.