Search code examples
.netinno-setup.net-framework-versioninno-download-plugin

InnoSetup: Check .NET Framework - installation not working


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.

enter image description here

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!


Solution

  • 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;