mirror of
https://github.com/winscp/winscp.git
synced 2026-10-24 02:28:55 +03:00
Issue 2381 – Restoring ability to restart Explorer to allow upgrade of drag&drop shell extension, when installing for current user, as after-restart replacement is not possible without Administrator privileges
https://winscp.net/tracker/2381 Source commit: 3e98116f9be92901679cd0424c4b4822d5560e68
This commit is contained in:
@@ -61,6 +61,8 @@ ImportSites=Looking for sites to import...
|
||||
AcceptButton=&Accept
|
||||
IncompleteTranslation=You are about to use an incomplete translation. It is completed by %1%% only.%n%nUntranslated parts of the user interface will be shown in their original English version.%n%nVisit WinSCP website at winscp.net to check, if newer version of the translation is available.
|
||||
MsiInstallation=WinSCP is already installed on this system using an MSI installer. Please uninstall that before running this standalone executable installer.
|
||||
ApplicationsFoundDragExt=The following applications have loaded WinSCP Drag & drop shell extension that needs to be updated by Setup. It is recommended that you allow Setup to automatically close these applications. After the installation has completed, Setup will attempt to restart the applications.
|
||||
ApplicationsFoundRestart=You can restart your computer later instead, if you do not need to use the extension.
|
||||
|
||||
; MSI (sic)
|
||||
InnoSetupInstallation=WinSCP is already installed on this system using a standalone executable installer. Please uninstall that before running this MSI installer.
|
||||
|
||||
@@ -127,7 +127,7 @@ SetupIconFile=winscpsetup.ico
|
||||
DisableDirPage=no
|
||||
WizardStyle=modern
|
||||
; We do not want the Explorer restarts as that is not pleasant to the user
|
||||
CloseApplications=no
|
||||
CloseApplications=yes
|
||||
UsedUserAreasWarning=no
|
||||
#ifdef Sign
|
||||
SignTool=sign $f "WinSCP Installer" https://winscp.net/eng/docs/installation
|
||||
@@ -428,6 +428,21 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function CmdLineParamExists(const Value: string): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
for I := 1 to ParamCount do
|
||||
begin
|
||||
if CompareText(ParamStr(I), Value) = 0 then
|
||||
begin
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function ShouldInstallShellExt(FileName: string; InstalledVersion: string): Boolean;
|
||||
var
|
||||
ExistingMS, ExistingLS: Cardinal;
|
||||
@@ -464,50 +479,66 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
ExistingMajor := ExistingMS shr 16;
|
||||
ExistingMinor := ExistingMS and $FFFF;
|
||||
ExistingRev := ExistingLS shr 16;
|
||||
ExistingBuild := ExistingLS and $FFFF;
|
||||
Log(Format('Existing shell extension %s version: %d.%d.%d[.%d]', [FileName, ExistingMajor, ExistingMinor, ExistingRev, ExistingBuild]));
|
||||
|
||||
Log(Format('Installed extension version string: %s', [InstalledVersion]));
|
||||
CutVersionPart(InstalledVersion, InstalledMajor);
|
||||
CutVersionPart(InstalledVersion, InstalledMinor);
|
||||
CutVersionPart(InstalledVersion, InstalledRev);
|
||||
CutVersionPart(InstalledVersion, InstalledBuild);
|
||||
Log(Format('Installed extension version: %d.%d.%d[.%d]', [InstalledMajor, InstalledMinor, InstalledRev, InstalledBuild]));
|
||||
|
||||
if (InstalledMajor <> ExistingMajor) or
|
||||
((ExistingMajor = 1) and (ExistingMinor <= 1)) then
|
||||
if CmdLineParamExists('/InstallShellExt') then
|
||||
begin
|
||||
// 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('Existing 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('Existing extension is 1.1 or older, allowing installation, and will require restart, if it is locked.');
|
||||
end;
|
||||
|
||||
Log('Installing shell extension and will require restart as explicitly requested using command-line parameter.');
|
||||
Result := True;
|
||||
ShellExtNoRestart := False;
|
||||
end
|
||||
else
|
||||
if (InstalledMinor > ExistingMinor) or
|
||||
((InstalledMinor = ExistingMinor) and (InstalledRev > ExistingRev)) then
|
||||
if CmdLineParamExists('/InstallShellExtNoRestart') then
|
||||
begin
|
||||
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.');
|
||||
Log('Installing shell extension and will delay replacing as explicitly requested using command-line parameter.');
|
||||
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;
|
||||
ExistingMajor := ExistingMS shr 16;
|
||||
ExistingMinor := ExistingMS and $FFFF;
|
||||
ExistingRev := ExistingLS shr 16;
|
||||
ExistingBuild := ExistingLS and $FFFF;
|
||||
Log(Format('Existing shell extension %s version: %d.%d.%d[.%d]', [FileName, ExistingMajor, ExistingMinor, ExistingRev, ExistingBuild]));
|
||||
|
||||
Log(Format('Installed extension version string: %s', [InstalledVersion]));
|
||||
CutVersionPart(InstalledVersion, InstalledMajor);
|
||||
CutVersionPart(InstalledVersion, InstalledMinor);
|
||||
CutVersionPart(InstalledVersion, InstalledRev);
|
||||
CutVersionPart(InstalledVersion, InstalledBuild);
|
||||
Log(Format('Installed extension version: %d.%d.%d[.%d]', [InstalledMajor, InstalledMinor, InstalledRev, InstalledBuild]));
|
||||
|
||||
if (InstalledMajor <> ExistingMajor) or
|
||||
((ExistingMajor = 1) and (ExistingMinor <= 1)) then
|
||||
begin
|
||||
// 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('Existing 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('Existing extension is 1.1 or older, allowing installation, and will require restart, if it is locked.');
|
||||
end;
|
||||
|
||||
Result := True;
|
||||
ShellExtNoRestart := False;
|
||||
end
|
||||
else
|
||||
if (InstalledMinor > ExistingMinor) or
|
||||
((InstalledMinor = ExistingMinor) and (InstalledRev > ExistingRev)) then
|
||||
begin
|
||||
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;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -551,6 +582,12 @@ begin
|
||||
ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
|
||||
end;
|
||||
|
||||
|
||||
function IsRestartingApplicationsPage: Boolean;
|
||||
begin
|
||||
Result := WizardForm.PreparingMemo.Visible;
|
||||
end;
|
||||
|
||||
function IsRestartPage: Boolean;
|
||||
begin
|
||||
Result := WizardForm.YesRadio.Visible;
|
||||
@@ -589,6 +626,10 @@ begin
|
||||
wpReady:
|
||||
HelpKeyword := 'ui_installer_ready';
|
||||
|
||||
wpPreparing:
|
||||
if IsRestartingApplicationsPage then
|
||||
HelpKeyword := 'ui_installer_restartingapplications';
|
||||
|
||||
wpFinished:
|
||||
HelpKeyword := 'ui_installer_finished';
|
||||
|
||||
@@ -746,21 +787,6 @@ begin
|
||||
Result := Control.Left + Control.Width;
|
||||
end;
|
||||
|
||||
function CmdLineParamExists(const Value: string): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
begin
|
||||
Result := False;
|
||||
for I := 1 to ParamCount do
|
||||
begin
|
||||
if CompareText(ParamStr(I), Value) = 0 then
|
||||
begin
|
||||
Result := True;
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function MsiEnumRelatedProducts(
|
||||
lpUpgradeCode: string; dwReserved, iProductIndex: DWORD; lpProductBuf: string): UINT;
|
||||
external 'MsiEnumRelatedProductsW@msi.dll stdcall delayload setuponly';
|
||||
@@ -1395,6 +1421,38 @@ begin
|
||||
end;
|
||||
end;
|
||||
#endif
|
||||
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
|
||||
S := CustomMessage('ApplicationsFoundDragExt');
|
||||
if IsAdminInstallMode then
|
||||
S := S + NewLine + CustomMessage('ApplicationsFoundRestart');
|
||||
WizardForm.PreparingLabel.Caption := S;
|
||||
|
||||
WizardForm.IncTopDecHeight(
|
||||
WizardForm.PreparingMemo, WizardForm.AdjustLabelHeight(WizardForm.PreparingLabel));
|
||||
|
||||
if not IsAdminInstallMode then
|
||||
begin
|
||||
Log('Not automatically choosing not to restart applications as installer is not running in admin mode, so delaying replacement after Windows restart is not possible');
|
||||
end
|
||||
else
|
||||
if not ShellExtNoRestart then
|
||||
begin
|
||||
Log('Not automatically choosing not to restart applications as shell extension upgrade is critical');
|
||||
end
|
||||
else
|
||||
begin
|
||||
Log('Automatically choosing not to restart applications as shell extension upgrade is not critical (or there''s even other reason the restart is needed) and installer is running in admin mode, so replacement after Windows restart should be possible and enough');
|
||||
WizardForm.PreparingNoRadio.Checked := True;
|
||||
WizardForm.NextButton.OnClick(WizardForm.NextButton);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user