{
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) and (ResultCode <> 1638)
and (ResultCode <> 3010) and (ResultCode <> 5100)) 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;