Inno Setup by Jordan Russell is a great installation scripting program, but lacks a built-in function to determine the .NET Framework version installed on the target machine. Fortunately, it’s easy to write such a function using Inno Setup’s Pascal scripting language.
Microsoft maintains a set of registry keys that indicate the installed .NET Framework versions and service packs. C# MVP Scott Dorman has posted a list comprising versions 1.0 through 4.0 (at the time of this writing) in this Stack Overflow thread. The required registry keys are quite similar for most .NET Framework versions except 1.0. We’ll ignore that version which has been obsoleted by 1.1 anyway.
Versions 4.5 and newer are somewhat tricky since they install as in-place updates for version 4.0 and reuse the exact same registry keys. The official MSDN page How to: Determine Which .NET Framework Versions Are Installed suggests checking for the presence of
Release, so that’s what I’m doing below. An alternative would be to examine the
Version which equals 4.0.30319 for .NET 4.0, 4.5.50709 for .NET 4.5, and 4.6.00079 for .NET 4.6. (Sadly, I didn’t think to record the version strings for 4.5.1 & 4.5.2 while I had them installed.)
Version 4.5.1 introduced an additional complication: there are two possible
Release values, depending on the Windows version! The script handles this by treating all queries for versions 4.5 or newer as minimum requirements, i.e. they will succeed if the
Release value is equal to or greater than the specified version’s minimum value on any system. Queries for .NET 4.0 are also fulfilled by .NET 4.5 or newer, due to the latter installing as in-place updates. Queries for older versions require exact matches, i.e. they are not fulfilled by .NET 4.0 or newer even if the application would be compatible.
In the following Inno Setup scripting code block, function
IsDotNetDetected checks whether the specified .NET Framework version and at least the specified service pack level are installed. All listed version strings are for final release versions; betas and release candidates typically have different version numbers. Function
InitializeSetup demonstrates how to use
IsDotNetDetected to check for .NET Framework 4.6 without service packs.
I’m placing this small bit of code in the public domain, so you may embed it in your own projects, modify and redistribute it as you see fit.
[Code] function IsDotNetDetected(version: string; service: cardinal): boolean; // Indicates whether the specified version and service pack of the .NET Framework is installed. // // version -- Specify one of these strings for the required .NET Framework version: // 'v1.1' .NET Framework 1.1 // 'v2.0' .NET Framework 2.0 // 'v3.0' .NET Framework 3.0 // 'v3.5' .NET Framework 3.5 // 'v4\Client' .NET Framework 4.0 Client Profile // 'v4\Full' .NET Framework 4.0 Full Installation // 'v4.5' .NET Framework 4.5 // 'v4.5.1' .NET Framework 4.5.1 // 'v4.5.2' .NET Framework 4.5.2 // 'v4.6' .NET Framework 4.6 // 'v4.6.1' .NET Framework 4.6.1 // 'v4.6.2' .NET Framework 4.6.2 // 'v4.7' .NET Framework 4.7 // // service -- Specify any non-negative integer for the required service pack level: // 0 No service packs required // 1, 2, etc. Service pack 1, 2, etc. required var key, versionKey: string; install, release, serviceCount, versionRelease: cardinal; success: boolean; begin versionKey := version; versionRelease := 0; // .NET 1.1 and 2.0 embed release number in version key if version = 'v1.1' then begin versionKey := 'v1.1.4322'; end else if version = 'v2.0' then begin versionKey := 'v2.0.50727'; end // .NET 4.5 and newer install as update to .NET 4.0 Full else if Pos('v4.', version) = 1 then begin versionKey := 'v4\Full'; case version of 'v4.5': versionRelease := 378389; 'v4.5.1': versionRelease := 378675; // 378758 on Windows 8 and older 'v4.5.2': versionRelease := 379893; 'v4.6': versionRelease := 393295; // 393297 on Windows 8.1 and older 'v4.6.1': versionRelease := 394254; // 394271 before Win10 November Update 'v4.6.2': versionRelease := 394802; // 394806 before Win10 Anniversary Update 'v4.7': versionRelease := 460798; // 460805 before Win10 Creators Update end; end; // installation key group for all .NET versions key := 'SOFTWARE\Microsoft\NET Framework Setup\NDP\' + versionKey; // .NET 3.0 uses value InstallSuccess in subkey Setup if Pos('v3.0', version) = 1 then begin success := RegQueryDWordValue(HKLM, key + '\Setup', 'InstallSuccess', install); end else begin success := RegQueryDWordValue(HKLM, key, 'Install', install); end; // .NET 4.0 and newer use value Servicing instead of SP if Pos('v4', version) = 1 then begin success := success and RegQueryDWordValue(HKLM, key, 'Servicing', serviceCount); end else begin success := success and RegQueryDWordValue(HKLM, key, 'SP', serviceCount); end; // .NET 4.5 and newer use additional value Release if versionRelease > 0 then begin success := success and RegQueryDWordValue(HKLM, key, 'Release', release); success := success and (release >= versionRelease); end; result := success and (install = 1) and (serviceCount >= service); end; function InitializeSetup(): Boolean; begin if not IsDotNetDetected('v4.6', 0) then begin MsgBox('MyApp requires Microsoft .NET Framework 4.6.'#13#13 'Please use Windows Update to install this version,'#13 'and then re-run the MyApp setup program.', mbInformation, MB_OK); result := false; end else result := true; end;