|
@@ -116,6 +116,8 @@ DisableProgramGroupPage=yes
|
|
|
MinVersion=0,5.1
|
|
MinVersion=0,5.1
|
|
|
SetupIconFile=winscpsetup.ico
|
|
SetupIconFile=winscpsetup.ico
|
|
|
DisableDirPage=no
|
|
DisableDirPage=no
|
|
|
|
|
+; We do not want the Explorer restarts as that is not pleasant to the user
|
|
|
|
|
+CloseApplications=no
|
|
|
#ifdef Sign
|
|
#ifdef Sign
|
|
|
SignTool=sign $f "WinSCP Installer" https://winscp.net/eng/docs/installation
|
|
SignTool=sign $f "WinSCP Installer" https://winscp.net/eng/docs/installation
|
|
|
#endif
|
|
#endif
|
|
@@ -270,12 +272,12 @@ Source: "license.txt"; DestDir: "{app}"; \
|
|
|
Components: main; Flags: ignoreversion
|
|
Components: main; Flags: ignoreversion
|
|
|
Source: "{#ShellExtFileSource}"; DestDir: "{app}"; \
|
|
Source: "{#ShellExtFileSource}"; DestDir: "{app}"; \
|
|
|
Components: shellext; \
|
|
Components: shellext; \
|
|
|
- Flags: regserver restartreplace uninsrestartdelete; \
|
|
|
|
|
- Check: not IsWin64 and IsShellExtNewer(ExpandConstant('{app}\{#ShellExtFileName}'), '{#GetFileVersion(ShellExtFileSource)}')
|
|
|
|
|
|
|
+ Flags: regserver restartreplace uninsrestartdelete ignoreversion; \
|
|
|
|
|
+ Check: not IsWin64 and ShouldInstallShellExt(ExpandConstant('{app}\{#ShellExtFileName}'), '{#GetFileVersion(ShellExtFileSource)}')
|
|
|
Source: "{#ShellExt64FileSource}"; DestDir: "{app}"; \
|
|
Source: "{#ShellExt64FileSource}"; DestDir: "{app}"; \
|
|
|
Components: shellext; \
|
|
Components: shellext; \
|
|
|
- Flags: regserver restartreplace uninsrestartdelete; \
|
|
|
|
|
- Check: IsWin64 and IsShellExtNewer(ExpandConstant('{app}\{#ShellExt64FileName}'), '{#GetFileVersion(ShellExt64FileSource)}')
|
|
|
|
|
|
|
+ Flags: regserver restartreplace uninsrestartdelete ignoreversion; \
|
|
|
|
|
+ Check: IsWin64 and ShouldInstallShellExt(ExpandConstant('{app}\{#ShellExt64FileName}'), '{#GetFileVersion(ShellExt64FileSource)}')
|
|
|
Source: "{#PuttySourceDir}\LICENCE"; DestDir: "{app}\PuTTY"; \
|
|
Source: "{#PuttySourceDir}\LICENCE"; DestDir: "{app}\PuTTY"; \
|
|
|
Components: pageant puttygen; Flags: ignoreversion
|
|
Components: pageant puttygen; Flags: ignoreversion
|
|
|
Source: "{#PuttySourceDir}\putty.chm"; DestDir: "{app}\PuTTY"; \
|
|
Source: "{#PuttySourceDir}\putty.chm"; DestDir: "{app}\PuTTY"; \
|
|
@@ -380,6 +382,7 @@ var
|
|
|
PrevVersion: string;
|
|
PrevVersion: string;
|
|
|
ShellExtNewerCacheFileName: string;
|
|
ShellExtNewerCacheFileName: string;
|
|
|
ShellExtNewerCacheResult: Boolean;
|
|
ShellExtNewerCacheResult: Boolean;
|
|
|
|
|
+ ShellExtNoRestart: Boolean;
|
|
|
#ifdef Donations
|
|
#ifdef Donations
|
|
|
DonationPanel: TPanel;
|
|
DonationPanel: TPanel;
|
|
|
AboutDonationCaption: TLabel;
|
|
AboutDonationCaption: TLabel;
|
|
@@ -426,7 +429,7 @@ begin
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
-function IsShellExtNewer(FileName: string; InstalledVersion: string): Boolean;
|
|
|
|
|
|
|
+function ShouldInstallShellExt(FileName: string; InstalledVersion: string): Boolean;
|
|
|
var
|
|
var
|
|
|
ExistingMS, ExistingLS: Cardinal;
|
|
ExistingMS, ExistingLS: Cardinal;
|
|
|
ExistingMajor, ExistingMinor, ExistingRev, ExistingBuild: Cardinal;
|
|
ExistingMajor, ExistingMinor, ExistingRev, ExistingBuild: Cardinal;
|
|
@@ -444,17 +447,20 @@ begin
|
|
|
Log(Format('Skipping installation of shell extension %s as already decided', [FileName]));
|
|
Log(Format('Skipping installation of shell extension %s as already decided', [FileName]));
|
|
|
Result := False;
|
|
Result := False;
|
|
|
end;
|
|
end;
|
|
|
|
|
+ // Keeping ShellExtNoRestart value
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
if not FileExists(FileName) then
|
|
if not FileExists(FileName) then
|
|
|
begin
|
|
begin
|
|
|
Log(Format('Shell extension %s does not exist yet, allowing installation', [FileName]));
|
|
Log(Format('Shell extension %s does not exist yet, allowing installation', [FileName]));
|
|
|
|
|
+ ShellExtNoRestart := False;
|
|
|
Result := True;
|
|
Result := True;
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
if not GetVersionNumbers(FileName, ExistingMS, ExistingLS) then
|
|
if not GetVersionNumbers(FileName, ExistingMS, ExistingLS) then
|
|
|
begin
|
|
begin
|
|
|
Log(Format('Cannot retrieve version of existing shell extension %s, allowing installation', [FileName]));
|
|
Log(Format('Cannot retrieve version of existing shell extension %s, allowing installation', [FileName]));
|
|
|
|
|
+ ShellExtNoRestart := False;
|
|
|
Result := True;
|
|
Result := True;
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
@@ -472,16 +478,36 @@ begin
|
|
|
CutVersionPart(InstalledVersion, InstalledBuild);
|
|
CutVersionPart(InstalledVersion, InstalledBuild);
|
|
|
Log(Format('Installed extension version: %d.%d.%d[.%d]', [InstalledMajor, InstalledMinor, InstalledRev, InstalledBuild]));
|
|
Log(Format('Installed extension version: %d.%d.%d[.%d]', [InstalledMajor, InstalledMinor, InstalledRev, InstalledBuild]));
|
|
|
|
|
|
|
|
- if ((InstalledMajor > ExistingMajor)) or
|
|
|
|
|
- ((InstalledMajor = ExistingMajor) and (InstalledMinor > ExistingMinor)) or
|
|
|
|
|
- ((InstalledMajor = ExistingMajor) and (InstalledMinor = ExistingMinor) and (InstalledRev > ExistingRev)) then
|
|
|
|
|
|
|
+ if (InstalledMajor <> ExistingMajor) or
|
|
|
|
|
+ ((ExistingMajor = 1) and (ExistingMinor <= 1)) then
|
|
|
begin
|
|
begin
|
|
|
- Log('Installed extension is newer than existing extension, allowing installation');
|
|
|
|
|
|
|
+ // Still on 1.x, so this won't be used when upgrading,
|
|
|
|
|
+ // but it will be useful, if downgrading from future version with a different major version.
|
|
|
|
|
+ if InstalledMajor <> ExistingMajor then
|
|
|
|
|
+ begin
|
|
|
|
|
+ Log('Installed extension has different major version, allowing installation, and will require restart, if it is locked.')
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ // 1.1 uses Ansi encoding, and is incompatible with 1.2 and newer which uses Unicode
|
|
|
|
|
+ Log('Installed extension is 1.1 or older, allowing installation, and will require restart, if it is locked.');
|
|
|
|
|
+ end;
|
|
|
|
|
+
|
|
|
Result := True;
|
|
Result := True;
|
|
|
|
|
+ ShellExtNoRestart := False;
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
|
|
+ if (InstalledMinor > ExistingMinor) or
|
|
|
|
|
+ ((InstalledMinor = ExistingMinor) and (InstalledRev > ExistingRev)) then
|
|
|
begin
|
|
begin
|
|
|
- Log('Installed extension is same or older than existing extension, skipping installation');
|
|
|
|
|
|
|
+ Log('Installed extension is newer than existing extension, but major version is the same, allowing installation, but we will delay replacing the extension until the next system start, if it is locked.');
|
|
|
|
|
+ Result := True;
|
|
|
|
|
+ ShellExtNoRestart := True;
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ Log('Installed extension is same or older than existing extension (but the same major version), skipping installation');
|
|
|
|
|
+ ShellExtNoRestart := False;
|
|
|
Result := False;
|
|
Result := False;
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
@@ -552,11 +578,6 @@ begin
|
|
|
ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
|
|
ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
|
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
-function IsRestartingApplicationsPage: Boolean;
|
|
|
|
|
-begin
|
|
|
|
|
- Result := WizardForm.PreparingMemo.Visible;
|
|
|
|
|
-end;
|
|
|
|
|
-
|
|
|
|
|
function IsRestartPage: Boolean;
|
|
function IsRestartPage: Boolean;
|
|
|
begin
|
|
begin
|
|
|
Result := WizardForm.YesRadio.Visible;
|
|
Result := WizardForm.YesRadio.Visible;
|
|
@@ -584,10 +605,6 @@ begin
|
|
|
wpReady:
|
|
wpReady:
|
|
|
HelpKeyword := 'ui_installer_ready';
|
|
HelpKeyword := 'ui_installer_ready';
|
|
|
|
|
|
|
|
- wpPreparing:
|
|
|
|
|
- if IsRestartingApplicationsPage then
|
|
|
|
|
- HelpKeyword := 'ui_installer_restartingapplications';
|
|
|
|
|
-
|
|
|
|
|
wpFinished:
|
|
wpFinished:
|
|
|
HelpKeyword := 'ui_installer_finished';
|
|
HelpKeyword := 'ui_installer_finished';
|
|
|
|
|
|
|
@@ -1328,6 +1345,7 @@ var
|
|
|
Delta: Integer;
|
|
Delta: Integer;
|
|
|
LineHeight: Integer;
|
|
LineHeight: Integer;
|
|
|
LaunchCheckboxTop: Integer;
|
|
LaunchCheckboxTop: Integer;
|
|
|
|
|
+ S: string;
|
|
|
begin
|
|
begin
|
|
|
if CurPageID = wpLicense then
|
|
if CurPageID = wpLicense then
|
|
|
begin
|
|
begin
|
|
@@ -1363,19 +1381,42 @@ begin
|
|
|
LineHeight := (WizardForm.NoRadio.Top - WizardForm.YesRadio.Top);
|
|
LineHeight := (WizardForm.NoRadio.Top - WizardForm.YesRadio.Top);
|
|
|
|
|
|
|
|
// Are we at the "Restart?" screen
|
|
// Are we at the "Restart?" screen
|
|
|
|
|
+ // Note that it's not possible to get to the "finished" page more than once,
|
|
|
|
|
+ // so the code below does not expect re-entry
|
|
|
if IsRestartPage then
|
|
if IsRestartPage then
|
|
|
begin
|
|
begin
|
|
|
- WizardForm.FinishedLabel.Caption :=
|
|
|
|
|
- CustomMessage('FinishedRestartDragExtLabel') + NewLine;
|
|
|
|
|
|
|
+ if ShellExtNoRestart then
|
|
|
|
|
+ begin
|
|
|
|
|
+ Log('Hiding restart page as it''s not critical to replace the shell extension');
|
|
|
|
|
+ WizardForm.YesRadio.Visible := False;
|
|
|
|
|
+ WizardForm.NoRadio.Visible := False;
|
|
|
|
|
+ WizardForm.NoRadio.Checked := True;
|
|
|
|
|
+
|
|
|
|
|
+ S := SetupMessage(msgFinishedLabel);
|
|
|
|
|
+ StringChange(S, '[name]', 'WinSCP');
|
|
|
|
|
+ WizardForm.FinishedLabel.Caption :=
|
|
|
|
|
+ S + NewLine + NewLine +
|
|
|
|
|
+ // The additional new line is a padding for the "launch check box",
|
|
|
|
|
+ // as the same padding is there for the YesRadio too.
|
|
|
|
|
+ SetupMessage(msgClickFinish) + NewLine;
|
|
|
|
|
+ Log(WizardForm.FinishedLabel.Caption);
|
|
|
|
|
+ Delta := WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
|
|
|
|
|
+ LaunchCheckboxTop := WizardForm.YesRadio.Top + Delta;
|
|
|
|
|
+ end
|
|
|
|
|
+ else
|
|
|
|
|
+ begin
|
|
|
|
|
+ WizardForm.FinishedLabel.Caption :=
|
|
|
|
|
+ CustomMessage('FinishedRestartDragExtLabel') + NewLine;
|
|
|
|
|
|
|
|
- Delta := WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
|
|
|
|
|
- WizardForm.YesRadio.Top := WizardForm.YesRadio.Top + Delta;
|
|
|
|
|
- WizardForm.NoRadio.Top := WizardForm.NoRadio.Top + Delta;
|
|
|
|
|
|
|
+ Delta := WizardForm.AdjustLabelHeight(WizardForm.FinishedLabel);
|
|
|
|
|
+ WizardForm.YesRadio.Top := WizardForm.YesRadio.Top + Delta;
|
|
|
|
|
+ WizardForm.NoRadio.Top := WizardForm.NoRadio.Top + Delta;
|
|
|
|
|
|
|
|
- LaunchCheckboxTop := WizardForm.NoRadio.Top + LineHeight;
|
|
|
|
|
|
|
+ LaunchCheckboxTop := WizardForm.NoRadio.Top + LineHeight;
|
|
|
#ifdef Donations
|
|
#ifdef Donations
|
|
|
- DonationPanel.Visible := False;
|
|
|
|
|
|
|
+ DonationPanel.Visible := False;
|
|
|
#endif
|
|
#endif
|
|
|
|
|
+ end;
|
|
|
end
|
|
end
|
|
|
else
|
|
else
|
|
|
begin
|
|
begin
|
|
@@ -1407,19 +1448,6 @@ begin
|
|
|
begin
|
|
begin
|
|
|
Log('License accepted');
|
|
Log('License accepted');
|
|
|
LicenseAccepted := True;
|
|
LicenseAccepted := True;
|
|
|
- end
|
|
|
|
|
- else
|
|
|
|
|
- if CurPageID = wpPreparing then
|
|
|
|
|
- begin
|
|
|
|
|
- // Are we at the "Restart applications?" screen.
|
|
|
|
|
- // If PreparingMemo is hidden, it's "installation/removal was not completed" screen
|
|
|
|
|
- if IsRestartingApplicationsPage then
|
|
|
|
|
- begin
|
|
|
|
|
- WizardForm.PreparingLabel.Caption :=
|
|
|
|
|
- CustomMessage('ApplicationsFoundDragExt');
|
|
|
|
|
- WizardForm.IncTopDecHeight(WizardForm.PreparingMemo,
|
|
|
|
|
- WizardForm.AdjustLabelHeight(WizardForm.PreparingLabel));
|
|
|
|
|
- end;
|
|
|
|
|
end;
|
|
end;
|
|
|
end;
|
|
end;
|
|
|
|
|
|