|
@@ -2,13 +2,11 @@ unit Uninstall;
|
|
|
|
|
|
{
|
|
{
|
|
Inno Setup
|
|
Inno Setup
|
|
- Copyright (C) 1997-2012 Jordan Russell
|
|
|
|
|
|
+ Copyright (C) 1997-2020 Jordan Russell
|
|
Portions by Martijn Laan
|
|
Portions by Martijn Laan
|
|
For conditions of distribution and use, see LICENSE.TXT.
|
|
For conditions of distribution and use, see LICENSE.TXT.
|
|
|
|
|
|
Uninstaller
|
|
Uninstaller
|
|
-
|
|
|
|
- NOTE: This unit was derived from Uninst.dpr rev 1.38.
|
|
|
|
}
|
|
}
|
|
|
|
|
|
interface
|
|
interface
|
|
@@ -41,8 +39,8 @@ const
|
|
|
|
|
|
var
|
|
var
|
|
UninstallExitCode: DWORD = 1;
|
|
UninstallExitCode: DWORD = 1;
|
|
- UninstExeFile, UninstDataFile, UninstMsgFile: String;
|
|
|
|
- UninstLogFile: TFile;
|
|
|
|
|
|
+ UninstExeFilename, UninstDataFilename, UninstMsgFilename: String;
|
|
|
|
+ UninstDataFile: TFile;
|
|
UninstLog: TExtUninstallLog = nil;
|
|
UninstLog: TExtUninstallLog = nil;
|
|
Title: String;
|
|
Title: String;
|
|
DidRespawn, SecondPhase: Boolean;
|
|
DidRespawn, SecondPhase: Boolean;
|
|
@@ -205,16 +203,16 @@ begin
|
|
{ Truncate the .dat file to zero bytes just before relinquishing exclusive
|
|
{ Truncate the .dat file to zero bytes just before relinquishing exclusive
|
|
access to it }
|
|
access to it }
|
|
try
|
|
try
|
|
- UninstLogFile.Seek(0);
|
|
|
|
- UninstLogFile.Truncate;
|
|
|
|
|
|
+ UninstDataFile.Seek(0);
|
|
|
|
+ UninstDataFile.Truncate;
|
|
except
|
|
except
|
|
{ ignore any exceptions, just in case }
|
|
{ ignore any exceptions, just in case }
|
|
end;
|
|
end;
|
|
- FreeAndNil(UninstLogFile);
|
|
|
|
|
|
+ FreeAndNil(UninstDataFile);
|
|
|
|
|
|
{ Delete the .dat and .msg files }
|
|
{ Delete the .dat and .msg files }
|
|
- DeleteFile(UninstDataFile);
|
|
|
|
- DeleteFile(UninstMsgFile);
|
|
|
|
|
|
+ DeleteFile(UninstDataFilename);
|
|
|
|
+ DeleteFile(UninstMsgFilename);
|
|
|
|
|
|
{ Tell the first phase to terminate, then delete its .exe }
|
|
{ Tell the first phase to terminate, then delete its .exe }
|
|
if FirstPhaseWnd <> 0 then begin
|
|
if FirstPhaseWnd <> 0 then begin
|
|
@@ -240,7 +238,7 @@ begin
|
|
Sleep(500);
|
|
Sleep(500);
|
|
end;
|
|
end;
|
|
UninstallExitCode := 0;
|
|
UninstallExitCode := 0;
|
|
- DelayDeleteFile(False, UninstExeFile, 13, 50, 250);
|
|
|
|
|
|
+ DelayDeleteFile(False, UninstExeFilename, 13, 50, 250);
|
|
if Debugging then
|
|
if Debugging then
|
|
DebugNotifyUninstExe('');
|
|
DebugNotifyUninstExe('');
|
|
{ Pre-Windows 2000 Add/Remove Programs will try to bring itself to the
|
|
{ Pre-Windows 2000 Add/Remove Programs will try to bring itself to the
|
|
@@ -275,7 +273,7 @@ begin
|
|
else
|
|
else
|
|
if CompareText(ParamName, '/SECONDPHASE=') = 0 then begin
|
|
if CompareText(ParamName, '/SECONDPHASE=') = 0 then begin
|
|
SecondPhase := True;
|
|
SecondPhase := True;
|
|
- UninstExeFile := ParamValue;
|
|
|
|
|
|
+ UninstExeFilename := ParamValue;
|
|
end
|
|
end
|
|
else if CompareText(ParamName, '/FIRSTPHASEWND=') = 0 then
|
|
else if CompareText(ParamName, '/FIRSTPHASEWND=') = 0 then
|
|
FirstPhaseWnd := StrToInt(ParamValue)
|
|
FirstPhaseWnd := StrToInt(ParamValue)
|
|
@@ -317,12 +315,12 @@ function OpenUninstDataFile(const AAccess: TFileAccess): TFile;
|
|
begin
|
|
begin
|
|
Result := nil; { avoid warning }
|
|
Result := nil; { avoid warning }
|
|
try
|
|
try
|
|
- Result := TFile.Create(UninstDataFile, fdOpenExisting, AAccess, fsNone);
|
|
|
|
|
|
+ Result := TFile.Create(UninstDataFilename, fdOpenExisting, AAccess, fsNone);
|
|
except
|
|
except
|
|
on E: EFileError do begin
|
|
on E: EFileError do begin
|
|
SetLastError(E.ErrorCode);
|
|
SetLastError(E.ErrorCode);
|
|
RaiseLastError(FmtSetupMessage1(msgUninstallOpenError,
|
|
RaiseLastError(FmtSetupMessage1(msgUninstallOpenError,
|
|
- UninstDataFile));
|
|
|
|
|
|
+ UninstDataFilename));
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -339,7 +337,7 @@ begin
|
|
|
|
|
|
F := OpenUninstDataFile(faRead);
|
|
F := OpenUninstDataFile(faRead);
|
|
try
|
|
try
|
|
- Flags := ReadUninstallLogFlags(F, UninstDataFile);
|
|
|
|
|
|
+ Flags := ReadUninstallLogFlags(F, UninstDataFilename);
|
|
finally
|
|
finally
|
|
F.Free;
|
|
F.Free;
|
|
end;
|
|
end;
|
|
@@ -350,7 +348,7 @@ begin
|
|
SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
|
|
SetWindowPos(Application.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE or
|
|
SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
|
|
SWP_NOMOVE or SWP_NOZORDER or SWP_NOACTIVATE or SWP_HIDEWINDOW);
|
|
try
|
|
try
|
|
- RespawnSelfElevated(UninstExeFile,
|
|
|
|
|
|
+ RespawnSelfElevated(UninstExeFilename,
|
|
Format('/INITPROCWND=$%x ', [Application.Handle]) + GetCmdTail,
|
|
Format('/INITPROCWND=$%x ', [Application.Handle]) + GetCmdTail,
|
|
UninstallExitCode);
|
|
UninstallExitCode);
|
|
except
|
|
except
|
|
@@ -379,7 +377,7 @@ begin
|
|
except
|
|
except
|
|
{ ignore exceptions }
|
|
{ ignore exceptions }
|
|
end;
|
|
end;
|
|
- if not CopyFile(PChar(UninstExeFile), PChar(TempFile), False) then
|
|
|
|
|
|
+ if not CopyFile(PChar(UninstExeFilename), PChar(TempFile), False) then
|
|
RaiseLastError(SetupMessages[msgLdrCannotCreateTemp]);
|
|
RaiseLastError(SetupMessages[msgLdrCannotCreateTemp]);
|
|
{ Don't want any attribute like read-only transferred }
|
|
{ Don't want any attribute like read-only transferred }
|
|
SetFileAttributes(PChar(TempFile), FILE_ATTRIBUTE_NORMAL);
|
|
SetFileAttributes(PChar(TempFile), FILE_ATTRIBUTE_NORMAL);
|
|
@@ -506,17 +504,17 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
Log('Setup version: ' + SetupTitle + ' version ' + SetupVersion);
|
|
Log('Setup version: ' + SetupTitle + ' version ' + SetupVersion);
|
|
- Log('Original Uninstall EXE: ' + UninstExeFile);
|
|
|
|
- Log('Uninstall DAT: ' + UninstDataFile);
|
|
|
|
|
|
+ Log('Original Uninstall EXE: ' + UninstExeFilename);
|
|
|
|
+ Log('Uninstall DAT: ' + UninstDataFilename);
|
|
Log('Uninstall command line: ' + GetCmdTail);
|
|
Log('Uninstall command line: ' + GetCmdTail);
|
|
LogWindowsVersion;
|
|
LogWindowsVersion;
|
|
|
|
|
|
{ Open the .dat file for read access }
|
|
{ Open the .dat file for read access }
|
|
- UninstLogFile := OpenUninstDataFile(faRead);
|
|
|
|
|
|
+ UninstDataFile := OpenUninstDataFile(faRead);
|
|
|
|
|
|
{ Load contents of the .dat file }
|
|
{ Load contents of the .dat file }
|
|
UninstLog := TExtUninstallLog.Create;
|
|
UninstLog := TExtUninstallLog.Create;
|
|
- UninstLog.Load(UninstLogFile, UninstDataFile);
|
|
|
|
|
|
+ UninstLog.Load(UninstDataFile, UninstDataFilename);
|
|
|
|
|
|
Title := FmtSetupMessage1(msgUninstallAppFullTitle, UninstLog.AppName);
|
|
Title := FmtSetupMessage1(msgUninstallAppFullTitle, UninstLog.AppName);
|
|
|
|
|
|
@@ -540,8 +538,8 @@ begin
|
|
{ Reopen the .dat file for exclusive, read/write access and keep it
|
|
{ Reopen the .dat file for exclusive, read/write access and keep it
|
|
open for the duration of the uninstall process to prevent a second
|
|
open for the duration of the uninstall process to prevent a second
|
|
instance of the same uninstaller from running. }
|
|
instance of the same uninstaller from running. }
|
|
- FreeAndNil(UninstLogFile);
|
|
|
|
- UninstLogFile := OpenUninstDataFile(faReadWrite);
|
|
|
|
|
|
+ FreeAndNil(UninstDataFile);
|
|
|
|
+ UninstDataFile := OpenUninstDataFile(faReadWrite);
|
|
|
|
|
|
if not UninstLog.ExtractLatestRecData(utCompiledCode,
|
|
if not UninstLog.ExtractLatestRecData(utCompiledCode,
|
|
SetupBinVersion {$IFDEF UNICODE} or Longint($80000000) {$ENDIF}, CompiledCodeData) then
|
|
SetupBinVersion {$IFDEF UNICODE} or Longint($80000000) {$ENDIF}, CompiledCodeData) then
|
|
@@ -580,7 +578,7 @@ begin
|
|
InitMainNonSHFolderConsts;
|
|
InitMainNonSHFolderConsts;
|
|
LoadSHFolderDLL;
|
|
LoadSHFolderDLL;
|
|
|
|
|
|
- UninstallExeFilename := UninstExeFile;
|
|
|
|
|
|
+ UninstallExeFilename := UninstExeFilename;
|
|
UninstallExpandedAppId := UninstLog.AppId;
|
|
UninstallExpandedAppId := UninstLog.AppId;
|
|
UninstallSilent := Silent or VerySilent;
|
|
UninstallSilent := Silent or VerySilent;
|
|
|
|
|
|
@@ -733,7 +731,7 @@ begin
|
|
UnloadSHFolderDLL;
|
|
UnloadSHFolderDLL;
|
|
RemoveTempInstallDir;
|
|
RemoveTempInstallDir;
|
|
UninstLog.Free;
|
|
UninstLog.Free;
|
|
- FreeAndNil(UninstLogFile);
|
|
|
|
|
|
+ FreeAndNil(UninstDataFile);
|
|
end;
|
|
end;
|
|
|
|
|
|
if RestartSystem then begin
|
|
if RestartSystem then begin
|
|
@@ -772,23 +770,23 @@ begin
|
|
|
|
|
|
SetCurrentDir(GetSystemDir);
|
|
SetCurrentDir(GetSystemDir);
|
|
|
|
|
|
- UninstExeFile := NewParamStr(0);
|
|
|
|
|
|
+ UninstExeFilename := NewParamStr(0);
|
|
ProcessCommandLine; { note: may change UninstExeFile }
|
|
ProcessCommandLine; { note: may change UninstExeFile }
|
|
- UninstDataFile := PathChangeExt(UninstExeFile, '.dat');
|
|
|
|
- UninstMsgFile := PathChangeExt(UninstExeFile, '.msg');
|
|
|
|
|
|
+ UninstDataFilename := PathChangeExt(UninstExeFilename, '.dat');
|
|
|
|
+ UninstMsgFilename := PathChangeExt(UninstExeFilename, '.msg');
|
|
|
|
|
|
{ Initialize messages }
|
|
{ Initialize messages }
|
|
- F := TFile.Create(UninstExeFile, fdOpenExisting, faRead, fsRead);
|
|
|
|
|
|
+ F := TFile.Create(UninstExeFilename, fdOpenExisting, faRead, fsRead);
|
|
try
|
|
try
|
|
F.Seek(F.Size.Lo - SizeOf(UninstallerMsgTail));
|
|
F.Seek(F.Size.Lo - SizeOf(UninstallerMsgTail));
|
|
F.ReadBuffer(UninstallerMsgTail, SizeOf(UninstallerMsgTail));
|
|
F.ReadBuffer(UninstallerMsgTail, SizeOf(UninstallerMsgTail));
|
|
if UninstallerMsgTail.ID <> UninstallerMsgTailID then begin
|
|
if UninstallerMsgTail.ID <> UninstallerMsgTailID then begin
|
|
{ No valid UninstallerMsgTail record found at the end of the EXE;
|
|
{ No valid UninstallerMsgTail record found at the end of the EXE;
|
|
load messages from an external .msg file. }
|
|
load messages from an external .msg file. }
|
|
- LoadSetupMessages(UninstMsgFile, 0, True);
|
|
|
|
|
|
+ LoadSetupMessages(UninstMsgFilename, 0, True);
|
|
end
|
|
end
|
|
else
|
|
else
|
|
- LoadSetupMessages(UninstExeFile, UninstallerMsgTail.Offset, True);
|
|
|
|
|
|
+ LoadSetupMessages(UninstExeFilename, UninstallerMsgTail.Offset, True);
|
|
finally
|
|
finally
|
|
F.Free;
|
|
F.Free;
|
|
end;
|
|
end;
|
|
@@ -803,8 +801,8 @@ begin
|
|
Application.Title := SetupMessages[msgUninstallAppTitle];
|
|
Application.Title := SetupMessages[msgUninstallAppTitle];
|
|
|
|
|
|
{ Verify that uninstall data file exists }
|
|
{ Verify that uninstall data file exists }
|
|
- if not NewFileExists(UninstDataFile) then begin
|
|
|
|
- LoggedMessageBoxFmt1(msgUninstallNotFound, UninstDataFile,
|
|
|
|
|
|
+ if not NewFileExists(UninstDataFilename) then begin
|
|
|
|
+ LoggedMessageBoxFmt1(msgUninstallNotFound, UninstDataFilename,
|
|
SetupMessages[msgUninstallAppTitle], MB_ICONSTOP or MB_OK, True, IDOK);
|
|
SetupMessages[msgUninstallAppTitle], MB_ICONSTOP or MB_OK, True, IDOK);
|
|
Abort;
|
|
Abort;
|
|
end;
|
|
end;
|