I don't have a virtual computer so I am not able to beta test this installation. Therefore I am kindly asking if I have gone about this correctly. It compiles OK.
Step 1
I declared these variables:
var
vcRedist64BitPath: string;
vcRedist32BitPath: string;
bVcRedist64BitNeeded : boolean;
bVcRedist32BitNeeded : boolean;
const
// See: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads
vcRedist64BitURL = 'https://aka.ms/vs/16/release/vc_redist.x64.exe';
vcRedist32BitURL = 'https://aka.ms/vs/16/release/vc_redist.x86.exe';
Step 2
I implemented these functions to test if the x86 and x64 redistributables are already installed:
// See: https://stackoverflow.com/a/51614652/2287576
function IsVCRedist64BitNeeded(): boolean;
var
strVersion: string;
begin
if (RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64', 'Version', strVersion)) then
begin
// Is the installed version at least 14.14 ?
Log('VC Redist x64 Version : found ' + strVersion);
Result := (CompareStr(strVersion, 'v14.14.26429.03') < 0);
end
else
begin
// Not even an old version installed
Log('VC Redist x64 is not already installed');
Result := True;
end;
end;
function IsVCRedist32BitNeeded(): boolean;
var
strVersion: string;
begin
if (RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Version', strVersion)) then
begin
// Is the installed version at least 14.14 ?
Log('VC Redist x86 Version : found ' + strVersion);
Result := (CompareStr(strVersion, 'v14.14.26429.03') < 0);
end
else
begin
if (RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86', 'Version', strVersion)) then
begin
// Is the installed version at least 14.14 ?
Log('VC Redist x86 Version : found ' + strVersion);
Result := (CompareStr(strVersion, 'v14.14.26429.03') < 0);
end
else
begin
// Not even an old version installed
Log('VC Redist x86 is not already installed');
Result := True;
end;
end;
end;
As I understand it, from the SO answer in the comment, 14.14 is the 2015 redistributable package and 2015 through 2019 use the same binaries. So I assume it is acceptable to look for this version in the registry.
Step 3
I updated PrepareToInstall
:
function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
result := '';
bVcRedist64BitNeeded := false;
if(IsWin64()) then
begin
bVcRedist64BitNeeded := IsVCRedist64BitNeeded();
end;
bVcRedist32BitNeeded := IsVCRedist32BitNeeded();
end;
Step 4
Since I am using DWinsHs for downloading remote files I added the following two entries to the BeforeDownload
callback:
function BeforeDownload(): boolean;
begin
if(bVcRedist64BitNeeded) then
begin
// We need to download the 64 Bit VC Redistributable from the Microsoft Website
vcRedist64BitPath := ExpandConstant('{tmp}\vc_redist.x64.exe');
DwinsHs_AppendRemoteFile( vcRedist64BitPath,
vcRedist64BitURL, 'My_Setup', rmGet, FILESIZE_QUERY_SERVER );
end;
if(bVcRedist32BitNeeded) then
begin
// We need to download the 32 Bit VC Redistributable from the Microsoft Website
vcRedist32BitPath := ExpandConstant('{tmp}\vc_redist.x86.exe');
DwinsHs_AppendRemoteFile( vcRedist32BitPath,
vcRedist32BitURL, 'My_Setup', rmGet, FILESIZE_QUERY_SERVER );
end;
result := true;
end;
Step 5
Since I am using DWinsHs for downloading remote files I added the following two entries to the AfterDownload
callback:
procedure AfterDownload(State: integer);
var
ResultCode: integer;
begin
if (State = READ_OK) then
begin
if(bVcRedist64BitNeeded) then
begin
if Exec(ExpandConstant(vcRedist64BitPath), '/install /passive /norestart', '',
SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
// handle success if necessary; ResultCode contains the exit code
if not (ResultCode = 0) then begin
MsgBox(ExpandConstant('The installation of Visual Studio x64 Redistributable failed. The Meeting Schedule Assistant installation will be aborted.'), mbInformation, MB_OK);
Abort();
end;
end
else begin
// The execution failed for some reason
MsgBox(SysErrorMessage(ResultCode), mbInformation, MB_OK);
Abort();
end;
end;
if(bVcRedist32BitNeeded) then
begin
if Exec(ExpandConstant(vcRedist32BitPath), '/install /passive /norestart', '',
SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin
// handle success if necessary; ResultCode contains the exit code
if not (ResultCode = 0) then begin
MsgBox(ExpandConstant('The installation of Visual Studio x86 Redistributable failed. The Meeting Schedule Assistant installation will be aborted.'), mbInformation, MB_OK);
Abort();
end;
end
else begin
// The execution failed for some reason
MsgBox(SysErrorMessage(ResultCode), mbInformation, MB_OK);
Abort();
end;
end;
end;
end;
The installer parameters and registry keys I have obtained are from resources I have found on the internet.
My installer caters for both x86 and x64 file .exe files which is why I am detecting if both redistributables are installed.
Have I in principle done this correctly? Again, I do not have a virtual environment to test with.