I have a question similar to Inno Setup: Verify that .NET 4.0 is installed, but it seems to be slightly different.
[Files] Source: "dependencies\dotNetFx40_Full_x86_x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall; Check: FrameworkIsNotInstalled Source: "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\MySql.Data\v4.0_6.5.4.0__c5687fc88969c44d\MySql.Data.dll"; DestDir: "{app}\lib"; StrongAssemblyName: "MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, ProcessorArchitecture=MSIL"; Flags: "gacinstall sharedfile uninsnosharedfileprompt" [Run] Filename: {tmp}\dotNetFx40_Full_x86_x64.exe; Description: Install Microsoft .NET Framework 4.0; Parameters: /q /norestart; Check: FrameworkIsNotInstalled [code] function FrameworkIsNotInstalled: Boolean; begin Result := not RegKeyExists(HKEY_LOCAL_MACHINE, 'Software\Microsoft\.NETFramework\policy\v4.0'); end;
As you can see, I'm trying to register a file with the GAC. Unfortunately on some machines it's possible that the .NET framework is not installed. So I need to install it first. Is there anyway that I can force an installation of the .NET runtime before I try to register my files?
Since the [Run]
section is processed after the [Files]
section, it is naturally impossible to do it with the script you've shown (hence your question). There are few ways where the one I would recommend is to execute the .NET setup from the AfterInstall
parameter function of the setup entry itself. So you would remove your current [Run]
section and write a script like this:
[Files] Source: "dependencies\dotNetFx40_Full_x86_x64.exe"; DestDir: {tmp}; Flags: deleteafterinstall; AfterInstall: InstallFramework; Check: FrameworkIsNotInstalled Source: "C:\Windows\Microsoft.NET\assembly\GAC_MSIL\MySql.Data\v4.0_6.5.4.0__c5687fc88969c44d\MySql.Data.dll"; DestDir: "{app}\lib"; StrongAssemblyName: "MySql.Data, Version=6.5.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, ProcessorArchitecture=MSIL"; Flags: gacinstall sharedfile uninsnosharedfileprompt [Code] procedure InstallFramework; var ResultCode: Integer; begin if not Exec(ExpandConstant('{tmp}\dotNetFx40_Full_x86_x64.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin { you can interact with the user that the installation failed } MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.', mbError, MB_OK); end; end;
The process is easy, if the Check
function of the .NET setup entry of the [Files]
section evaluates to True (FrameworkIsNotInstalled
), the entry is processed, which copies the setup binary into the Inno Setup's temporary folder and if that succeeds, the AfterInstall
function InstallFramework
is called immediately after. Inside of this function, the .NET setup is manually executed by calling Exec
function.
And finally, if all of that succeeds, the installation continues to process the next [Files]
section entry, which is your assembly that is going to be registered. Now, with the installed .NET framework. So as you can see, the order of the [Files]
section entries is crucial here.
You've additionally asked in your comment, how to show to the user some progress, since executing the .NET setup in the way I've posted here blocks the [Files]
entry, which leads to showing the stopped progress bar and text about extracting files. Since it wouldn't be easy to get the .NET setup's installation progress, I would simply show to the user endless marquee progress bar during that setup execution.
To do this wrap that setup execution into a code like this:
procedure InstallFramework; var StatusText: string; begin StatusText := WizardForm.StatusLabel.Caption; WizardForm.StatusLabel.Caption := 'Installing .NET framework...'; WizardForm.ProgressGauge.Style := npbstMarquee; try { here put the .NET setup execution code } finally WizardForm.StatusLabel.Caption := StatusText; WizardForm.ProgressGauge.Style := npbstNormal; end; end;
This is how the wizard form looks like during that .NET setup execution (the progress bar is animated):
I just want to add something to @TLama: The close when the setup fails. It's not so easy because WizardForm.Close;
just invokes the cancel-button which can be aborted by the user. Finally, the code can look like that:
[Code] var CancelWithoutPrompt: boolean; function InitializeSetup(): Boolean; begin CancelWithoutPrompt := false; result := true; end; procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean); begin if CurPageID=wpInstalling then Confirm := not CancelWithoutPrompt; end; function FrameworkIsNotInstalled: Boolean; begin Result := not RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full'); end; procedure InstallFramework; var StatusText: string; ResultCode: Integer; begin StatusText := WizardForm.StatusLabel.Caption; WizardForm.StatusLabel.Caption := 'Installing .NET framework...'; WizardForm.ProgressGauge.Style := npbstMarquee; try if not Exec(ExpandConstant('{tmp}\dotNetFx45_Full_asetup.exe'), '/q /norestart', '', SW_SHOW, ewWaitUntilTerminated, ResultCode) then begin // you can interact with the user that the installation failed MsgBox('.NET installation failed with code: ' + IntToStr(ResultCode) + '.', mbError, MB_OK); CancelWithoutPrompt := true; WizardForm.Close; end; finally WizardForm.StatusLabel.Caption := StatusText; WizardForm.ProgressGauge.Style := npbstNormal; end; end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With