How to change the downloadpath in InnoSetup? - inno-setup

I want to download and install the .net framework 4.5 with silent installation in innosetup,using below condition i will check whether .netframework 4.5 available or not, if not i will download from web using shellexec. here i attached the code.
function Framework45IsNotInstalled: Boolean;
var
bVer4x5: Boolean;
bSuccess: Boolean;
iInstalled: Cardinal;
strVersion: String;
iPos: Cardinal;
ErrorCode: Integer;
begin
Result := True;
bVer4x5 := False;
bSuccess := RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Install', iInstalled);
if (1 = iInstalled) AND (True = bSuccess) then
begin
bSuccess := RegQueryStringValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Version', strVersion);
if (True = bSuccess) then
Begin
iPos := Pos('4.5.', strVersion);
if (0 < iPos) then bVer4x5 := True;
End
end;
if (True = bVer4x5) then begin
Result := False;
end;
ShellExec('', 'http://go.microsoft.com/fwlink/?LinkId=225702','{app}', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
Now my doubt is,while starting the download it opens the web browser, and it doesn't install the .net framework automatically, user need to install manually,i want innosetup to install automatically after download is happening, installation should happen in silent manner.Can i get any idea to achieve this task??

When using ShellExec() to tell the default browser to download something, then you have no control over what it does.
If you want to be able to run it afterwards, you will need to use an integrated downloader like InnoTools Downloader, or just ask the user to run it the install.

Related

Including a summary of the files to download with Inno Setup 6.1.1 beta to Ready page?

With Inno Download Plugin I had a code that registers a list of files to download and adds the list to "Ready" page memo at the same time:
Building memo text for Inno Download Plugin
I have modified the code to work with Inno Setup 6.1.1 download page, instead of IDP:
procedure AddFileForDownload(Url, FileName: string);
begin
DownloadPage.Add(Url, FileName, '');
FilesToDownload := FilesToDownload + ' ' + ExtractFileName(FileName) + #13#10;
Log('File to download: ' + Url);
end;
Then I adjusted NextButtonClick like this:
function NextButtonClick(CurPageID: integer): boolean;
begin
Result := True;
if (CurPageID = wpReady) then
begin
DownloadPage.Clear;
if (dotNetNeeded) then begin
{ We need to download the 4.6.2 setup from the Microsoft Website }
dotNetRedistPath := ExpandConstant('{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
AddFileForDownload(dotnetRedistURL, 'NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
end;
if (bVcRedist64BitNeeded) then
begin
{ We need to download the 64 Bit VC Redistributable from the Microsoft Website }
vcRedist64BitPath := ExpandConstant('{tmp}\vc_redist.x64.exe');
AddFileForDownload(vcRedist64BitURL, 'vc_redist.x64.exe');
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');
AddFileForDownload(vcRedist32BitURL, 'vc_redist.x86.exe');
end;
if (WizardIsTaskSelected('downloadhelp')) then
AddFileForDownload('{#HelpDocSetupURL}', 'HelpDocSetup.exe');
DownloadPage.Show;
try
try
DownloadPage.Download;
Result := True;
except
SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
Result := False;
end;
finally
DownloadPage.Hide;
end;
end;
end;
I ran the installer, and checked the wizard option to download the help documentation, and yet the Ready page displays only:
The Download section is not being added. How can that be? When I click Next it does continue to the next page to download the file.
I added some extra logging for FilesToDownload and it is interesting:
2020-11-01 11:44:22.409 UpdateReadyMemo FileToDownload:
2020-11-01 11:44:25.671 File to download: https://www.publictalksoftware.co.uk/downloads/MSAHelpDocumentationSetup.exe
2020-11-01 11:44:25.671 FileToDownload: HelpDocSetup.exe
The UpdateReadyMemo method is being called before we populate the variable. Confused!
I got confused a bit initially. Because the issue is obvious. Your code executes when you click "Install" button on the "Ready" page. So obviously only after the "Ready" page shows.
You have to call the AddFileForDownload earlier. Maybe to NextButtonClick(wpSelectTasks).
function NextButtonClick(CurPageID: integer): boolean;
begin
Result := True;
if (CurPageID = wpSelectTasks) then
begin
DownloadPage.Clear;
if (dotNetNeeded) then
begin
// We need to download the 4.6.2 setup from the Microsoft Website
dotNetRedistPath :=
ExpandConstant('{tmp}\NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
AddFileForDownload(
dotnetRedistURL, 'NDP451-KB2858728-x86-x64-AllOS-ENU.exe');
end;
if (bVcRedist64BitNeeded) then
begin
// We need to download the 64 Bit VC Redistributable
// from the Microsoft Website
vcRedist64BitPath := ExpandConstant('{tmp}\vc_redist.x64.exe');
AddFileForDownload(vcRedist64BitURL, 'vc_redist.x64.exe');
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');
AddFileForDownload(vcRedist32BitURL, 'vc_redist.x86.exe');
end;
if (WizardIsTaskSelected('downloadhelp')) then
AddFileForDownload('{#HelpDocSetupURL}', 'HelpDocSetup.exe');
end
else
if (CurPageID = wpReady) then
begin
DownloadPage.Show;
try
try
DownloadPage.Download;
Result := True;
except
SuppressibleMsgBox(
AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
Result := False;
end;
finally
DownloadPage.Hide;
end;
end;
end;
(untested)

How to show user if installer is installing or upgrading [duplicate]

This question already has answers here:
Inno Setup: How to automatically uninstall previous installed version?
(13 answers)
Closed 1 year ago.
How do I detect whether the user already installed the software and if so, how to offer the possibility of removing the old version?
I have written some lines to check that. Is that correct for now? If this is correct, then how can I let the user choose whether he wants to continue the installation or uninstall the old version?
#define UNINSTKEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\setupname_is1"
var
uninstallPath: string;
function InitializeSetup: Boolean;
begin
if (RegQueryStringValue(HKLM,'{#UNINSTKEY}','UninstallString',uninstallPath)) and
(uninstallPath <> '') and (fileexists(uninstallPath)) then
begin
Result :=
(MsgBox(CustomMessage('NotVerifiedVersionFound'), mbConfirmation,
MB_YESNO or MB_DEFBUTTON2) = IDYES);
end;
{ ... }
end;
You could use Craig McQueen's solution originally posted here: InnoSetup: How to automatically uninstall previous installed version?
function GetUninstallString: string;
var
sUnInstPath: string;
sUnInstallString: String;
begin
Result := '';
sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{{A227028A-40D7-4695-8BA9-41DF6A3895C7}_is1'); { Your App GUID/ID }
sUnInstallString := '';
if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then
RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString);
Result := sUnInstallString;
end;
function IsUpgrade: Boolean;
begin
Result := (GetUninstallString() <> '');
end;
function InitializeSetup: Boolean;
var
V: Integer;
iResultCode: Integer;
sUnInstallString: string;
begin
Result := True; { in case when no previous version is found }
if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\{A227028A-40D7-4695-8BA9-41DF6A3895C7}_is1', 'UninstallString') then { Your App GUID/ID }
begin
V := MsgBox(ExpandConstant('Hey! An old version of app was detected. Do you want to uninstall it?'), mbInformation, MB_YESNO); { Custom Message if App installed }
if V = IDYES then
begin
sUnInstallString := GetUninstallString();
sUnInstallString := RemoveQuotes(sUnInstallString);
Exec(ExpandConstant(sUnInstallString), '', '', SW_SHOW, ewWaitUntilTerminated, iResultCode);
Result := True; { if you want to proceed after uninstall }
{ Exit; //if you want to quit after uninstall }
end
else
Result := False; { when older version present and not uninstalled }
end;
end;
For anyone interested, I wrote a small DLL for Inno Setup 6 and newer that provides the ability to detect if an application is installed and to automatically uninstall the previous installed version based on your own criteria.
https://github.com/Bill-Stewart/UninsIS
Using the DLL you can automatically uninstall only when downgrading, only when upgrading, or either.

How to set StatusMsg from PrepareToInstall event function

My application requires .NET Framework to be installed so I run .NET installation in PrepareToIntall event function. While the installation is running I would like to display some simple message on Wizard.
I found How to set the status message in [Code] Section of Inno install script? but the solution there doesn't work for me.
I tried
WizardForm.StatusLabel.Caption := CustomMessage('InstallingDotNetMsg');
and also
WizardForm.PreparingLabel.Caption := CustomMessage('InstallingDotNetMsg');
EDIT
I have to do this in PrepareToInstall function, because I need to stop the setup when .net installation fails.
Code looks like this right now:
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
isDotNetInstalled : Boolean;
errorCode : Integer;
errorDesc : String;
begin
isDotNetInstalled := IsDotNetIntalledCheck();
if not isDotNetInstalled then
begin
//WizardForm.PreparingLabel.Caption := CustomMessage('InstallingDotNetMsg');
WizardForm.StatusLabel.Caption := CustomMessage('InstallingDotNetMsg');
ExtractTemporaryFile('dotNetFx40_Full_x86_x64.exe');
if not ShellExec('',ExpandConstant('{tmp}\dotNetFx40_Full_x86_x64.exe'),'/passive /norestart', '', SW_HIDE, ewWaitUntilTerminated, errorCode) then
begin
errorDesc := SysErrorMessage(errorCode);
MsgBox(errorDesc, mbError, MB_OK);
end;
isDotNetInstalled := WasDotNetInstallationSuccessful();
if not isDotNetInstalled then
begin
Result := CustomMessage('FailedToInstalldotNetMsg');
end;
end;
end;
Any Ideas how to achieve this?
The StatusLabel is hosted by the InstallingPage wizard page while you're on PreparingPage page in the PrepareToInstall event method. So that's a wrong label. Your attempt to set the text to the PreparingLabel was correct, but failed because that label is hidden by default (it is shown when you return non empty string as a result to the event method).
But you can show it for a while (you are using ewWaitUntilTerminated flag, so your installation is synchronous, thus it won't hurt anything):
[Code]
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
WasVisible: Boolean;
begin
// store the original visibility state
WasVisible := WizardForm.PreparingLabel.Visible;
try
// show the PreparingLabel
WizardForm.PreparingLabel.Visible := True;
// set a label caption
WizardForm.PreparingLabel.Caption := CustomMessage('InstallingDotNetMsg');
// do your installation here
finally
// restore the original visibility state
WizardForm.PreparingLabel.Visible := WasVisible;
end;
end;
Another solution is to use CreateOutputProgressPage to display a progress page over the top of the Preparing to Install page. See the CodeDlg.iss example script included with Inno for an example of the usage; it's fairly straightforward.

How to install .net framework 4.5 after download completes from web using innosetup?

I want to download and install the .netframework 4.5 from web using innosetup.
I followed these procedure,
1.I downloaded and installed InnoTools Downloader.
2.In InitializeWizard i declared
itd_init;
itd_addfile('http://go.microsoft.com/fwlink/?LinkId=225702',expandconstant('{tmp}\dotNetFx45_Full_x86_x64.exe'));
itd_downloadafter(10);
Where 10 is the curpageId.
And in
NextButtonClick(CurPageID: Integer) i added ,
if CurPageId=104 then begin
`filecopy(expandconstant('{tmp}\dotNetFx45_Full_x86_x64.exe'),expandconstant('{app}\dotNetFx`45_Full_x86_x64.exe'),false);
end
*Now what i need to do is,i want to check whether .net framework 4.5 is installed in my pc or not, using the function how can i check *,
function Framework45IsNotInstalled(): Boolean;
var
bVer4x5: Boolean;
bSuccess: Boolean;
iInstalled: Cardinal;
strVersion: String;
iPos: Cardinal;
ErrorCode: Integer;
begin
Result := True;
bVer4x5 := False;
bSuccess := RegQueryDWordValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Install', iInstalled);
if (1 = iInstalled) AND (True = bSuccess) then
begin
bSuccess := RegQueryStringValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Version', strVersion);
if (True = bSuccess) then
Begin
iPos := Pos('4.5.', strVersion);
if (0 < iPos) then bVer4x5 := True;
End
end;
if (True = bVer4x5) then begin
Result := False;
end;
end;
where i need to check this condition, in my side downloading and installing of .netframework 4.5 is happening fine,the only condition i need to check whether .net framework 4.5 is installed or not,before calling this **itd_downloadafter(10)Where 10 is the curpageId.**.
Then only download wont happen, if .netframework is already exist in my enduser pc.
How can i achieve this task? any ideas?
The release version numbers in the registry for .NET 4.5 are highlighted in MSDN: http://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx
Your code needs to be modified to look at the 'Release' key in the registry as specified in the MDSN article above and can be simplified just to check for this value.
function Framework45IsNotInstalled(): Boolean;
var
bSuccess: Boolean;
regVersion: Cardinal;
begin
Result := True;
bSuccess := RegQueryStringValue(HKLM, 'Software\Microsoft\NET Framework Setup\NDP\v4\Full', 'Release', regVersion);
if (True = bSuccess) and (regVersion >= 378389) then begin
Result := False;
end;
end;
end;
For a more complete example of checking .NET version numbers with Inno Setup you can also look at the code in this very useful article: http://kynosarges.org/DotNetVersion.html

Uninstall when running inno setup with application already installed

I have just started using inno setup, and it seems to work well. However, when I run the installer with the app already installed it reinstalls. I would like to give the user to uninstall. Is this possible, and if so, how can it be done?
To be specific, I have written a game for a homework assignment. I made an installer using inno setup. The app installs fine and can be uninstalled using the control panel, but my professor would like to be able to uninstall the application by re-running the installer and choosing an uninstall option. This will save him time since he has about 50 of these assignments to mark.
Thanks,
Gerry
The next script will make the following options form when the application is already installed on the target system when the setup is started:
When the user clicks Repair button, the setup is normally started. When user clicks the Uninstall button, the previously installed application is uninstalled. When user closes that form, nothing happens.
Here is the script (don't forget to specify, ideally some unique, value for the AppId setup directive in your script):
[Setup]
AppName=My Program
AppVersion=1.5
AppId=1C9FAC66-219F-445B-8863-20DEAF8BB5CC
DefaultDirName={pf}\My Program
OutputDir=userdocs:Inno Setup Examples Output
[CustomMessages]
OptionsFormCaption=Setup options...
RepairButtonCaption=Repair
UninstallButtonCaption=Uninstall
[Code]
const
mrRepair = 100;
mrUninstall = 101;
function ShowOptionsForm: TModalResult;
var
OptionsForm: TSetupForm;
RepairButton: TNewButton;
UninstallButton: TNewButton;
begin
Result := mrNone;
OptionsForm := CreateCustomForm;
try
OptionsForm.Width := 220;
OptionsForm.Caption := ExpandConstant('{cm:OptionsFormCaption}');
OptionsForm.Position := poScreenCenter;
RepairButton := TNewButton.Create(OptionsForm);
RepairButton.Parent := OptionsForm;
RepairButton.Left := 8;
RepairButton.Top := 8;
RepairButton.Width := OptionsForm.ClientWidth - 16;
RepairButton.Caption := ExpandConstant('{cm:RepairButtonCaption}');
RepairButton.ModalResult := mrRepair;
UninstallButton := TNewButton.Create(OptionsForm);
UninstallButton.Parent := OptionsForm;
UninstallButton.Left := 8;
UninstallButton.Top := RepairButton.Top + RepairButton.Height + 8;
UninstallButton.Width := OptionsForm.ClientWidth - 16;
UninstallButton.Caption := ExpandConstant('{cm:UninstallButtonCaption}');
UninstallButton.ModalResult := mrUninstall;
OptionsForm.ClientHeight := RepairButton.Height + UninstallButton.Height + 24;
Result := OptionsForm.ShowModal;
finally
OptionsForm.Free;
end;
end;
function GetUninstallerPath: string;
var
RegKey: string;
begin
Result := '';
RegKey := Format('%s\%s_is1', ['Software\Microsoft\Windows\CurrentVersion\Uninstall',
'{#emit SetupSetting("AppId")}']);
if not RegQueryStringValue(HKEY_LOCAL_MACHINE, RegKey, 'UninstallString', Result) then
RegQueryStringValue(HKEY_CURRENT_USER, RegKey, 'UninstallString', Result);
end;
function InitializeSetup: Boolean;
var
UninstPath: string;
ResultCode: Integer;
begin
Result := True;
UninstPath := RemoveQuotes(GetUninstallerPath);
if UninstPath <> '' then
begin
case ShowOptionsForm of
mrRepair: Result := True;
mrUninstall:
begin
Result := False;
if not Exec(UninstPath, '', '', SW_SHOW, ewNoWait, ResultCode) then
MsgBox(FmtMessage(SetupMessage(msgUninstallOpenError), [UninstPath]), mbError, MB_OK);
end;
else
Result := False;
end;
end;
end;
For some reason your code
RegKey := Format('%s\%s_is1', ['Software\Microsoft\Windows\CurrentVersion\Uninstall',
'{#emit SetupSetting("AppId")}']);
returned an extra { to the _is1 value. I didn't had the time to check why or where i was wrong in my implementation,
all i confirm is that my installer works with the
RegKey := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1');
alternate.
Hope it helps.
Thank you for the code sample.
When using Inno Setup, there's no reason to uninstall a previous version unless that version was installed by a different installer program. Otherwise upgrades are handled automatically.
Your answer is here :
InnoSetup: How to automatically uninstall previous installed version? previous-installed-version

Resources