Hi I am trying to integrate .NET Framework version check and auto-install in my Inno Setup script.
I am using the code I found here: .../installing-net-framework-4-5-automatically-with-inno-setup/`
The problem is, the code isn't working. The script compiles and outputs fine.
When I try to run the setup in a VM, everything works fine.
However, I don't see the .NET Framework actually being installed.
Just a quick 10 sec progress window showing various files being extracted (shown below).
Then it vanishes and my setup completes.
When I try to start my program, it reports .NET Framework isn't installed.
Here's the complete code:
#include <idp.iss>
function Framework45IsNotInstalled(): Boolean;
var
bSuccess: Boolean;
regVersion: Cardinal;
begin
Result := True;
bSuccess := RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', regVersion);
if (True = bSuccess) and (regVersion >= 378389) then begin
Result := False;
end;
end;
procedure InitializeWizard;
begin
if Framework45IsNotInstalled() then
begin
idpAddFile('http://go.microsoft.com/fwlink/?LinkId=397707', ExpandConstant('{tmp}\NetFrameworkInstaller.exe'));
idpDownloadAfter(wpReady);
end;
end;
procedure InstallFramework;
var
StatusText: string;
ResultCode: Integer;
begin
StatusText := WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Installing .NET Framework 4.5.2. This might take a few minutes…';
WizardForm.ProgressGauge.Style := npbstMarquee;
try
if not Exec(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'), '/passive /norestart','', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
begin
MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.', mbError, MB_OK);
end;
finally
WizardForm.StatusLabel.Caption := StatusText;
WizardForm.ProgressGauge.Style := npbstNormal;
DeleteFile(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'));
end;
end;
procedure CurStepChanged(CurStep: TSetupStep);
begin
case CurStep of
ssPostInstall:
begin
if Framework45IsNotInstalled() then
begin
InstallFramework();
end;
end;
end;
end;
I tried breaking down the code and trying to find the problem. Unfortunately, I can't identify it.
Any help would be highly appreciated. Thanks!
Alright finally I identified the issue, and it's an embarrassing one. My VM didn't have enough space, but this error wasn't being reported correctly in the setup script procedure InstallFramework
.
The condition if not Exec(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'), '/passive /norestart','', SW_SHOW, ewWaitUntilTerminated, ResultCode) then
always returns False
, even if the .NET Framework installation fails.
The correct way is to just call Exec(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'), '/passive /norestart','', SW_SHOW, ewWaitUntilTerminated, ResultCode)
and then check the actual ResultCode
to see if the .NET Framework installation succeeded. In the original script, this ResultCode
's value was 5100
(not enough space).
So, I modified and fixed the routine accordingly.
procedure InstallFramework;
var
StatusText: string;
ResultCode: Integer;
begin
StatusText := WizardForm.StatusLabel.Caption;
WizardForm.StatusLabel.Caption := 'Installing .NET Framework 4.5.2. This might take a few minutes...';
WizardForm.ProgressGauge.Style := npbstMarquee;
try
Exec(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'), '/passive /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode)
if ResultCode <> 0 then
begin
MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.' + #13#10 + #13#10 + 'Setup will now terminate.', mbError, MB_OK);
DeleteFile(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'));
Exterminate;
end
else
begin
WizardForm.StatusLabel.Caption := StatusText;
WizardForm.ProgressGauge.Style := npbstNormal;
end;
finally
DeleteFile(ExpandConstant('{tmp}\NetFrameworkInstaller.exe'));
end;
end;
The Exterminate
procedure aborts the setup (without a prompt) if the .NET Framework installation fails.
var
ForceClose: Boolean;
procedure Exterminate;
begin
ForceClose:= True;
WizardForm.Close;
end;
procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
begin
Confirm:= not ForceClose;
end;