{ CheckForNetFx.iss -- Written by Joe Mistachkin. Released to the public domain, use at your own risk! } var IsNetFx2Setup : Boolean; IsNetFx4Setup : Boolean; NetFxSubKeyName: String; NetFxInstallRoot: String; NetFxSetupSubKeyName: String; NetFxIsInstalled: String; NetFx2Version: String; NetFx2SetupVersion: String; NetFx2HasServicePack: String; NetFx2ServicePack: Integer; NetFx2ErrorMessage: String; NetFx35SetupVersion: String; NetFx35HasServicePack: String; NetFx35ServicePack: Integer; NetFx35ErrorMessage: String; NetFx4Version: String; NetFx4SetupVersion: String; NetFx4HasServicePack: String; NetFx4ServicePack: Integer; NetFx4ErrorMessage: String; VcRuntimeRedistributable: String; function TrimSlash(const Path: String): String; var LastCharacter: String; begin Result := Path; if Result <> '' then begin LastCharacter := Copy(Result, Length(Result), 1); if (LastCharacter = '\') or (LastCharacter = '/') then begin Result := Copy(Result, 1, Length(Result) - 1); end; end; end; function CheckForNetFx2(const NeedServicePack: Integer): Boolean; var SubKeyName: String; IsInstalled: Cardinal; HasServicePack: Cardinal; begin Result := False; SubKeyName := NetFxSetupSubKeyName + '\' + NetFx2SetupVersion; if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFxIsInstalled, IsInstalled) then begin if IsInstalled <> 0 then begin if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFx2HasServicePack, HasServicePack) then begin if HasServicePack >= NeedServicePack then begin Result := True; end; end; end; end; end; function CheckForNetFx35(const NeedServicePack: Integer): Boolean; var SubKeyName: String; IsInstalled: Cardinal; HasServicePack: Cardinal; begin Result := False; SubKeyName := NetFxSetupSubKeyName + '\' + NetFx35SetupVersion; if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFxIsInstalled, IsInstalled) then begin if IsInstalled <> 0 then begin if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFx35HasServicePack, HasServicePack) then begin if HasServicePack >= NeedServicePack then begin Result := True; end; end; end; end; end; function CheckForNetFx4(const NeedServicePack: Integer): Boolean; var SubKeyName: String; IsInstalled: Cardinal; HasServicePack: Cardinal; begin Result := False; SubKeyName := NetFxSetupSubKeyName + '\' + NetFx4SetupVersion; if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFxIsInstalled, IsInstalled) then begin if IsInstalled <> 0 then begin if RegQueryDWordValue(HKEY_LOCAL_MACHINE, SubKeyName, NetFx4HasServicePack, HasServicePack) then begin if HasServicePack >= NeedServicePack then begin Result := True; end; end; end; end; end; function GetNetFx2InstallRoot(const FileName: String): String; var InstallRoot: String; begin Result := ''; if RegQueryStringValue(HKEY_LOCAL_MACHINE, NetFxSubKeyName, NetFxInstallRoot, InstallRoot) then begin if InstallRoot <> '' then begin Result := TrimSlash(InstallRoot) + '\' + NetFx2Version; if FileName <> '' then begin Result := TrimSlash(Result) + '\' + FileName; end; end; end; end; function GetNetFx4InstallRoot(const FileName: String): String; var InstallRoot: String; begin Result := ''; if RegQueryStringValue(HKEY_LOCAL_MACHINE, NetFxSubKeyName, NetFxInstallRoot, InstallRoot) then begin if InstallRoot <> '' then begin Result := TrimSlash(InstallRoot) + '\' + NetFx4Version; if FileName <> '' then begin Result := TrimSlash(Result) + '\' + FileName; end; end; end; end; function CheckIsNetFx2Setup(): Boolean; begin Result := IsNetFx2Setup; end; function CheckIsNetFx4Setup(): Boolean; begin Result := IsNetFx4Setup; end; function ExtractAndInstallVcRuntime(var ResultCode: Integer): Boolean; begin ExtractTemporaryFile(VcRuntimeRedistributable); if Exec(ExpandConstant( '{tmp}\' + VcRuntimeRedistributable), '/q', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin Result := True; end else begin Result := False; end; end; function NetFxInitializeSetup(): Boolean; var ResultCode: Integer; begin IsNetFx2Setup := {#IsNetFx2}; IsNetFx4Setup := not IsNetFx2Setup; NetFxSubKeyName := 'Software\Microsoft\.NETFramework'; NetFxInstallRoot := 'InstallRoot'; NetFxSetupSubKeyName := 'Software\Microsoft\NET Framework Setup\NDP'; NetFxIsInstalled := 'Install'; NetFx2Version := 'v2.0.50727'; NetFx2SetupVersion := 'v2.0.50727'; NetFx2HasServicePack := 'SP'; NetFx2ServicePack := 2; NetFx2ErrorMessage := 'The Microsoft .NET Framework v2.0 with Service Pack ' + IntToStr(NetFx2ServicePack) + ' or higher is required.'; NetFx35SetupVersion := 'v3.5'; NetFx35HasServicePack := 'SP'; NetFx35ServicePack := 1; NetFx35ErrorMessage := 'The Microsoft .NET Framework v3.5 with Service Pack ' + IntToStr(NetFx35ServicePack) + ' or higher is required for LINQ support.'; NetFx4Version := 'v4.0.30319'; NetFx4SetupVersion := 'v4\Full'; NetFx4HasServicePack := 'Servicing'; NetFx4ServicePack := 0; NetFx4ErrorMessage := 'The Microsoft .NET Framework v4.0 with Service Pack ' + IntToStr(NetFx4ServicePack) + ' or higher is required.'; VcRuntimeRedistributable := 'vcredist_{#AppProcessor}_{#VcRuntime}.exe'; if IsNetFx2Setup then begin Result := CheckForNetFx2(NetFx2ServicePack); if not Result then begin MsgBox(NetFx2ErrorMessage, mbError, MB_OK); end; if Result and not CheckForNetFx35(NetFx35ServicePack) then begin MsgBox(NetFx35ErrorMessage, mbInformation, MB_OK); end; end; if IsNetFx4Setup then begin Result := CheckForNetFx4(NetFx4ServicePack); if not Result then begin MsgBox(NetFx4ErrorMessage, mbError, MB_OK); end; end; if Result then begin Result := ExtractAndInstallVcRuntime(ResultCode); if not Result or (ResultCode <> 0) then begin MsgBox('Failed to install Microsoft Visual C++ Runtime: ' + VcRuntimeRedistributable + ', ' + SysErrorMessage(ResultCode), mbError, MB_OK); if Result then begin Result := False; end; end; end; end;