Преглед изворни кода

Cleanup application data dialog shown only data what exists + Uninstaller does not offer to delete application data, where are not any

Source commit: 5d1f4b8a6e495105e0c877b4854b497cb219ac26
Martin Prikryl пре 6 година
родитељ
комит
15ce8199da

+ 50 - 9
source/core/Configuration.cpp

@@ -747,28 +747,69 @@ void __fastcall TConfiguration::CleanupConfiguration()
   }
 }
 //---------------------------------------------------------------------------
-void __fastcall TConfiguration::CleanupRegistry(const UnicodeString & CleanupSubKey, const UnicodeString & ParentKey)
+bool TConfiguration::RegistryPathExists(const UnicodeString & RegistryPath)
 {
   std::unique_ptr<TRegistryStorage> Registry(new TRegistryStorage(RegistryStorageKey));
 
+  UnicodeString ParentKey = ExtractFileDir(RegistryPath);
+  UnicodeString SubKey = ExtractFileName(RegistryPath);
+  return
+    Registry->OpenRootKey(false) &&
+    (ParentKey.IsEmpty() ||
+     Registry->OpenSubKeyPath(ParentKey, false)) &&
+    Registry->KeyExists(SubKey);
+}
+//---------------------------------------------------------------------------
+void __fastcall TConfiguration::CleanupRegistry(const UnicodeString & RegistryPath)
+{
+  std::unique_ptr<TRegistryStorage> Registry(new TRegistryStorage(RegistryStorageKey));
+
+  UnicodeString ParentKey = ExtractFileDir(RegistryPath);
   if (ParentKey.IsEmpty() ||
       Registry->OpenSubKeyPath(ParentKey, false))
   {
-    Registry->RecursiveDeleteSubKey(CleanupSubKey);
+    UnicodeString SubKey = ExtractFileName(RegistryPath);
+    Registry->RecursiveDeleteSubKey(SubKey);
   }
 }
 //---------------------------------------------------------------------------
+TStrings * TConfiguration::GetCaches()
+{
+  std::unique_ptr<TStrings> Result(new TStringList());
+  Result->Add(SshHostKeysSubKey);
+  Result->Add(FtpsCertificateStorageKey);
+  Result->Add(HttpsCertificateStorageKey);
+  Result->Add(DirectoryStatisticsCacheKey);
+  Result->Add(TPath::Combine(ConfigurationSubKey, CDCacheKey));
+  Result->Add(TPath::Combine(ConfigurationSubKey, BannersKey));
+  Result->Add(TPath::Combine(ConfigurationSubKey, LastFingerprintsStorageKey));
+  return Result.release();
+}
+//---------------------------------------------------------------------------
+bool __fastcall TConfiguration::HasAnyCache()
+{
+  bool Result = false;
+  std::unique_ptr<TStrings> Caches(GetCaches());
+  for (int Index = 0; Index < Caches->Count; Index++)
+  {
+    if (RegistryPathExists(Caches->Strings[Index]))
+    {
+      Result = true;
+      break;
+    }
+  }
+  return Result;
+}
+//---------------------------------------------------------------------------
 void __fastcall TConfiguration::CleanupCaches()
 {
   try
   {
-    CleanupRegistry(SshHostKeysSubKey);
-    CleanupRegistry(FtpsCertificateStorageKey);
-    CleanupRegistry(HttpsCertificateStorageKey);
-    CleanupRegistry(DirectoryStatisticsCacheKey);
-    CleanupRegistry(CDCacheKey, ConfigurationSubKey);
-    CleanupRegistry(BannersKey, ConfigurationSubKey);
-    CleanupRegistry(LastFingerprintsStorageKey, ConfigurationSubKey);
+    std::unique_ptr<TStrings> Caches(GetCaches());
+    for (int Index = 0; Index < Caches->Count; Index++)
+    {
+      CleanupRegistry(Caches->Strings[Index]);
+    }
   }
   catch (Exception & E)
   {

+ 4 - 1
source/core/Configuration.h

@@ -161,7 +161,7 @@ protected:
   virtual void __fastcall LoadAdmin(THierarchicalStorage * Storage);
   virtual UnicodeString __fastcall GetDefaultKeyFile();
   virtual void __fastcall Saved();
-  void __fastcall CleanupRegistry(const UnicodeString & CleanupSubKey, const UnicodeString & ParentKey = UnicodeString());
+  void __fastcall CleanupRegistry(const UnicodeString & RegistryPath);
   void __fastcall CopyAllStringsInSubKey(
     THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name);
   bool __fastcall CopySubKey(THierarchicalStorage * Source, THierarchicalStorage * Target, const UnicodeString & Name);
@@ -186,6 +186,7 @@ protected:
   UnicodeString __fastcall LoadCustomIniFileStorageName();
   void __fastcall SaveCustomIniFileStorageName();
   UnicodeString __fastcall GetRegistryStorageOverrideKey();
+  TStrings * GetCaches();
 
   virtual UnicodeString __fastcall ModuleFileName();
 
@@ -224,6 +225,7 @@ public:
   void __fastcall CleanupConfiguration();
   void __fastcall CleanupIniFile();
   void __fastcall CleanupCaches();
+  bool __fastcall HasAnyCache();
   void __fastcall CleanupRandomSeedFile();
   void __fastcall BeginUpdate();
   void __fastcall EndUpdate();
@@ -255,6 +257,7 @@ public:
   UnicodeString __fastcall GetFileDescription(const UnicodeString & FileName);
   UnicodeString __fastcall GetFileVersion(const UnicodeString & FileName);
   UnicodeString __fastcall GetFileMimeType(const UnicodeString & FileName);
+  bool RegistryPathExists(const UnicodeString & RegistryPath);
 
   TStoredSessionList * __fastcall SelectFilezillaSessionsForImport(
     TStoredSessionList * Sessions, UnicodeString & Error);

+ 13 - 1
source/core/PuttyIntf.cpp

@@ -56,6 +56,11 @@ void __fastcall PuttyInitialize()
   strcpy(appname_, AppName.c_str());
 }
 //---------------------------------------------------------------------------
+static bool DeleteRandomSeedOnExit()
+{
+  return !HadRandomSeed && !SaveRandomSeed;
+}
+//---------------------------------------------------------------------------
 void __fastcall PuttyFinalize()
 {
   if (SaveRandomSeed)
@@ -64,7 +69,7 @@ void __fastcall PuttyFinalize()
   }
   random_unref();
   // random_ref in PuttyInitialize creates the seed file. Delete it, if didn't want to create it.
-  if (!HadRandomSeed && !SaveRandomSeed)
+  if (DeleteRandomSeedOnExit())
   {
     DeleteFile(ApiPath(Configuration->RandomSeedFileName));
   }
@@ -81,6 +86,13 @@ void __fastcall DontSaveRandomSeed()
   SaveRandomSeed = false;
 }
 //---------------------------------------------------------------------------
+bool RandomSeedExists()
+{
+  return
+    !DeleteRandomSeedOnExit() &&
+    FileExists(ApiPath(Configuration->RandomSeedFileName));
+}
+//---------------------------------------------------------------------------
 TSecureShell * GetSecureShell(Plug * plug, bool & pfwd)
 {
   if (!is_ssh(plug) && !is_pfwd(plug))

+ 2 - 0
source/core/PuttyTools.h

@@ -51,4 +51,6 @@ class THierarchicalStorage;
 void WritePuttySettings(THierarchicalStorage * Storage, const UnicodeString & Settings);
 void SavePuttyDefaults(const UnicodeString & Name);
 //---------------------------------------------------------------------------
+bool RandomSeedExists();
+//---------------------------------------------------------------------------
 #endif

+ 96 - 111
source/forms/Cleanup.cpp

@@ -4,139 +4,104 @@
 
 #include <Common.h>
 #include <VCLCommon.h>
+#include <CoreMain.h>
 #include <WinConfiguration.h>
 #include <TextsWin.h>
+#include <HelpWin.h>
+#include <PuttyTools.h>
 #include "Cleanup.h"
 //---------------------------------------------------------------------
 #ifndef NO_RESOURCES
 #pragma resource "*.dfm"
 #endif
 //---------------------------------------------------------------------
-Boolean __fastcall DoCleanupDialog(TStoredSessionList *SessionList,
-  TConfiguration *Configuration)
+bool __fastcall DoCleanupDialog()
 {
-  Boolean Result;
-  TCleanupDialog *CleanupDialog;
-  try {
-    CleanupDialog = SafeFormCreate<TCleanupDialog>();
-
-    CleanupDialog->SessionList = SessionList;
-    CleanupDialog->Configuration = Configuration;
-
-    Result = (CleanupDialog->ShowModal() == DefaultResult(CleanupDialog));
-    if (Result)
-    {
-      Configuration->Usage->Inc(L"Cleanups");
-
-      for (int i = wdConfiguration; i <= wdTemporaryFolders; i++)
-      {
-        if (CleanupDialog->CleanupData[(TWinSCPData)i])
-        {
-          try
-          {
-            switch (i)
-            {
-              case wdConfiguration:
-                Configuration->CleanupConfiguration();
-                break;
-
-              case wdStoredSessions:
-                SessionList->Cleanup();
-                break;
-
-              case wdCaches:
-                Configuration->CleanupCaches();
-                break;
-
-              case wdConfigurationIniFile:
-                Configuration->CleanupIniFile();
-                break;
-
-              case wdRandomSeedFile:
-                Configuration->CleanupRandomSeedFile();
-                break;
-
-              case wdTemporaryFolders:
-                WinConfiguration->CleanupTemporaryFolders();
-                break;
-            }
-          }
-          catch(Exception & E)
-          {
-            ShowExtendedException(&E);
-          }
-        }
-      }
-    }
-  } __finally {
-    delete CleanupDialog;
+  std::unique_ptr<TCleanupDialog> CleanupDialog(SafeFormCreate<TCleanupDialog>());
+  return CleanupDialog->Execute();
+}
+//---------------------------------------------------------------------
+void __fastcall DoCleanupDialogIfAnyDataAndWanted()
+{
+  std::unique_ptr<TCleanupDialog> CleanupDialog(SafeFormCreate<TCleanupDialog>());
+  if (CleanupDialog->AnyData() &&
+      (MessageDialog(LoadStr(UNINSTALL_CLEANUP), qtConfirmation, qaYes | qaNo, HELP_UNINSTALL_CLEANUP) == qaYes))
+  {
+    CleanupDialog->Execute();
   }
-  return Result;
 }
 //---------------------------------------------------------------------
 __fastcall TCleanupDialog::TCleanupDialog(TComponent* AOwner)
   : TForm(AOwner)
 {
+  FAnyData = false;
+  FindData();
   UseSystemSettings(this);
 }
 //---------------------------------------------------------------------
-void __fastcall TCleanupDialog::InitControls()
+void __fastcall TCleanupDialog::AddLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event)
 {
-  // Particularly in response to WM_DPICHANGED, the form may re-show
-  DataListView->Items->Clear();
+  FCaptions.push_back(LoadStr(CaptionId));
+  FLocations.push_back(Location);
+  FCleanupEvents.push_back(Event);
+  FAnyData = true;
+}
+//---------------------------------------------------------------------
+void __fastcall TCleanupDialog::AddRegistryLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event)
+{
+  AddLocation(CaptionId, Configuration->RootKeyStr + L'\\' + Configuration->RegistryStorageKey + L'\\' + Location, Event);
+}
+//---------------------------------------------------------------------
+bool __fastcall TCleanupDialog::AnyData()
+{
+  return FAnyData;
+}
+//---------------------------------------------------------------------
+void __fastcall TCleanupDialog::FindData()
+{
+  // Add unconditionally (as it has a side effect of not saving the configuration)
+  AddRegistryLocation(CLEANUP_CONFIG, Configuration->ConfigurationSubKey, Configuration->CleanupConfiguration);
+  // But count as real data, only if it really exists
+  FAnyData = Configuration->RegistryPathExists(Configuration->ConfigurationSubKey);
 
-  for (int i = wdConfiguration; i <= wdTemporaryFolders; i++)
+  if (Configuration->RegistryPathExists(Configuration->StoredSessionsSubKey))
   {
-    UnicodeString Caption;
-    UnicodeString Location;
-
-    switch (i)
-    {
-      case wdConfiguration:
-        Caption = LoadStr(CLEANUP_CONFIG);
-        Location = Configuration->ConfigurationSubKey;
-        break;
-
-      case wdStoredSessions:
-        Caption = LoadStr(CLEANUP_SESSIONS);
-        Location = Configuration->StoredSessionsSubKey;
-        break;
-
-      case wdCaches:
-        Caption = LoadStr(CLEANUP_HOSTKEYS);
-        Location = L"...";
-        break;
-
-      case wdConfigurationIniFile:
-        Caption = LoadStr(CLEANUP_INIFILE);
-        Location = ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading);
-        break;
+    AddRegistryLocation(CLEANUP_SESSIONS, Configuration->StoredSessionsSubKey, StoredSessions->Cleanup);
+  }
 
-      case wdRandomSeedFile:
-        Caption = LoadStr(CLEANUP_SEEDFILE);
-        Location = ExpandEnvironmentVariables(Configuration->RandomSeedFile);
-        break;
+  if (Configuration->HasAnyCache())
+  {
+    AddRegistryLocation(CLEANUP_HOSTKEYS, L"...", Configuration->CleanupCaches);
+  }
 
-      case wdTemporaryFolders:
-        Caption = LoadStr(CLEANUP_TEMP_FOLDERS);
-        Location = WinConfiguration->TemporaryDir(true);
-        break;
+  UnicodeString IniFilePath = ExpandEnvironmentVariables(Configuration->IniFileStorageNameForReading);
+  if (FileExists(IniFilePath))
+  {
+    AddLocation(CLEANUP_INIFILE, IniFilePath, Configuration->CleanupIniFile);
+  }
 
-      default:
-        DebugFail();
-        break;
-    }
+  if (RandomSeedExists())
+  {
+    AddLocation(CLEANUP_SEEDFILE, Configuration->RandomSeedFileName, Configuration->CleanupRandomSeedFile);
+  }
 
+  if (WinConfiguration->AnyTemporaryFolders())
+  {
+    AddLocation(CLEANUP_TEMP_FOLDERS, WinConfiguration->TemporaryDir(true), WinConfiguration->CleanupTemporaryFolders);
+  }
+}
+//---------------------------------------------------------------------
+void __fastcall TCleanupDialog::InitControls()
+{
+  DebugAssert(FCaptions.size() == FLocations.size());
+  DebugAssert(FCaptions.size() == FCleanupEvents.size());
+  // Particularly in response to WM_DPICHANGED, the form may re-show
+  DataListView->Items->Clear();
+  for (size_t Index = 0; Index < FCaptions.size(); Index++)
+  {
     TListItem * Item = DataListView->Items->Add();
-    Item->Caption = Caption;
-    if (i < wdConfigurationIniFile)
-    {
-      Location = Configuration->RootKeyStr + L'\\' +
-        Configuration->RegistryStorageKey + L'\\' + Location;
-    }
-
-    Item->SubItems->Add(Location);
-    DebugAssert(Item->Index == i - 1);
+    Item->Caption = FCaptions[Index];
+    Item->SubItems->Add(FLocations[Index]);
   }
 
   AutoSizeListColumnsWidth(DataListView);
@@ -179,13 +144,33 @@ void __fastcall TCleanupDialog::DataListViewInfoTip(TObject * /*Sender*/,
     ARRAYOFCONST((Item->Caption, Item->SubItems->Strings[0])));
 }
 //---------------------------------------------------------------------------
-bool __fastcall TCleanupDialog::GetCleanupData(TWinSCPData Data)
+void __fastcall TCleanupDialog::HelpButtonClick(TObject * /*Sender*/)
 {
-  return DataListView->Items->Item[Data - 1]->Checked;
+  FormHelp(this);
 }
 //---------------------------------------------------------------------------
-void __fastcall TCleanupDialog::HelpButtonClick(TObject * /*Sender*/)
+bool __fastcall TCleanupDialog::Execute()
 {
-  FormHelp(this);
+  bool Result = (ShowModal() == DefaultResult(this));
+  if (Result)
+  {
+    Configuration->Usage->Inc(L"Cleanups");
+
+    for (int Index = 0; Index < DataListView->Items->Count; Index++)
+    {
+      if (DataListView->Items->Item[Index]->Checked)
+      {
+        try
+        {
+          FCleanupEvents[Index]();
+        }
+        catch (Exception & E)
+        {
+          ShowExtendedException(&E);
+        }
+      }
+    }
+  }
+  return Result;
 }
 //---------------------------------------------------------------------------

+ 11 - 10
source/forms/Cleanup.h

@@ -12,9 +12,6 @@
 #include <WinInterface.h>
 #include <GUITools.h>
 //---------------------------------------------------------------------
-enum TWinSCPData {wdConfiguration = 1, wdStoredSessions, wdCaches,
-  wdConfigurationIniFile, wdRandomSeedFile, wdTemporaryFolders };
-//---------------------------------------------------------------------
 class TCleanupDialog : public TForm
 {
 __published:
@@ -34,19 +31,23 @@ __published:
     TListItem *Item, UnicodeString &InfoTip);
   void __fastcall HelpButtonClick(TObject *Sender);
 private:
-  TStoredSessionList *FSessionList;
-  TConfiguration * FConfiguration;
+  std::vector<UnicodeString> FCaptions;
+  std::vector<UnicodeString> FLocations;
+  typedef void __fastcall (__closure *TCleanupEvent)();
+  std::vector<TCleanupEvent> FCleanupEvents;
+  bool FAnyData;
   void __fastcall InitControls();
   void __fastcall UpdateControls();
-  bool __fastcall GetCleanupData(TWinSCPData Data);
+  void __fastcall FindData();
+  void __fastcall AddLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event);
+  void __fastcall AddRegistryLocation(int CaptionId, const UnicodeString & Location, TCleanupEvent Event);
 
   INTERFACE_HOOK;
 
 public:
-  virtual __fastcall TCleanupDialog(TComponent* AOwner);
-  __property TStoredSessionList *SessionList  = { read=FSessionList, write=FSessionList };
-  __property TConfiguration * Configuration  = { read=FConfiguration, write=FConfiguration };
-  __property Boolean CleanupData[TWinSCPData Data]  = { read=GetCleanupData };
+  virtual __fastcall TCleanupDialog(TComponent * AOwner);
+  bool __fastcall Execute();
+  bool __fastcall AnyData();
 };
 //----------------------------------------------------------------------------
 #endif

+ 1 - 1
source/forms/Login.cpp

@@ -1113,7 +1113,7 @@ void __fastcall TLoginDialog::ImportSessionsActionExecute(TObject * /*Sender*/)
 //---------------------------------------------------------------------------
 void __fastcall TLoginDialog::CleanUpActionExecute(TObject * /*Sender*/)
 {
-  if (DoCleanupDialog(StoredSessions, Configuration))
+  if (DoCleanupDialog())
   {
     SaveState();
     LoadSessions();

+ 48 - 58
source/windows/WinConfiguration.cpp

@@ -2480,87 +2480,75 @@ UnicodeString __fastcall TWinConfiguration::TemporaryDir(bool Mask)
   return UniqTempDir(ExpandedTemporaryDirectory(), L"scp", Mask);
 }
 //---------------------------------------------------------------------------
-TStrings * __fastcall TWinConfiguration::FindTemporaryFolders()
+TStrings * __fastcall TWinConfiguration::DoFindTemporaryFolders(bool OnlyFirst)
 {
-  TStrings * Result = new TStringList();
-  try
+  std::unique_ptr<TStrings> Result(new TStringList());
+  TSearchRecOwned SRec;
+  UnicodeString Mask = TemporaryDir(true);
+  UnicodeString Directory = ExtractFilePath(Mask);
+  if (FindFirstUnchecked(Mask, faDirectory | faHidden, SRec) == 0)
   {
-    TSearchRecOwned SRec;
-    UnicodeString Mask = TemporaryDir(true);
-    UnicodeString Directory = ExtractFilePath(Mask);
-    if (FindFirstUnchecked(Mask, faDirectory | faHidden, SRec) == 0)
+    do
     {
-      do
+      if (SRec.IsDirectory())
       {
-        if (SRec.IsDirectory())
-        {
-          Result->Add(Directory + SRec.Name);
-        }
+        Result->Add(Directory + SRec.Name);
       }
-      while (FindNextChecked(SRec) == 0);
-    }
-
-    if (Result->Count == 0)
-    {
-      delete Result;
-      Result = NULL;
     }
+    while ((FindNextChecked(SRec) == 0) && (!OnlyFirst || Result->Count == 0));
   }
-  catch(...)
+
+  if (Result->Count == 0)
   {
-    delete Result;
-    throw;
+    Result.reset(NULL);
   }
 
-  return Result;
+  return Result.release();
 }
 //---------------------------------------------------------------------------
-void __fastcall TWinConfiguration::CleanupTemporaryFolders(TStrings * Folders)
+TStrings * __fastcall TWinConfiguration::FindTemporaryFolders()
 {
-  UnicodeString ErrorList;
-  TStrings * F;
-  if (Folders == NULL)
+  return DoFindTemporaryFolders(false);
+}
+//---------------------------------------------------------------------------
+bool __fastcall TWinConfiguration::AnyTemporaryFolders()
+{
+  std::unique_ptr<TStrings> Folders(DoFindTemporaryFolders(true));
+  return (Folders.get() != NULL);
+}
+//---------------------------------------------------------------------------
+void __fastcall TWinConfiguration::CleanupTemporaryFolders()
+{
+  std::unique_ptr<TStrings> Folders(FindTemporaryFolders());
+  if (Folders.get() != NULL)
   {
-    F = FindTemporaryFolders();
+    CleanupTemporaryFolders(Folders.get());
   }
-  else
+}
+//---------------------------------------------------------------------------
+void __fastcall TWinConfiguration::CleanupTemporaryFolders(TStrings * Folders)
+{
+  if (DebugAlwaysTrue(Folders->Count > 0))
   {
-    F = Folders;
+    Usage->Inc(L"TemporaryDirectoryCleanups");
   }
 
-  if (F != NULL)
+  UnicodeString ErrorList;
+  for (int i = 0; i < Folders->Count; i++)
   {
-    try
+    if (!DeleteDirectory(Folders->Strings[i]))
     {
-      if (DebugAlwaysTrue(F->Count > 0))
+      if (!ErrorList.IsEmpty())
       {
-        Usage->Inc(L"TemporaryDirectoryCleanups");
-      }
-
-      for (int i = 0; i < F->Count; i++)
-      {
-        if (!DeleteDirectory(F->Strings[i]))
-        {
-          if (!ErrorList.IsEmpty())
-          {
-            ErrorList += L"\n";
-          }
-          ErrorList += F->Strings[i];
-        }
-      }
-    }
-    __finally
-    {
-      if (Folders == NULL)
-      {
-        delete F;
+        ErrorList += L"\n";
       }
+      ErrorList += Folders->Strings[i];
     }
+  }
 
-    if (!ErrorList.IsEmpty())
-    {
-      throw ExtException(LoadStr(CLEANUP_TEMP_ERROR), ErrorList);
-    }
+  if (!ErrorList.IsEmpty())
+  {
+    throw ExtException(LoadStr(CLEANUP_TEMP_ERROR), ErrorList);
   }
 }
 //---------------------------------------------------------------------------
@@ -2737,7 +2725,9 @@ void __fastcall TWinConfiguration::UpdateEntryInJumpList(
     FDontDecryptPasswords++;
     Storage->AccessMode = smReadWrite;
 
-    if (Storage->OpenSubKey(ConfigurationSubKey, true))
+    // For initial call from UpdateJumpList, do not create the key if it does ot exist yet.
+    // To avoid creating the key if we are being started just for a maintenance task.
+    if (Storage->OpenSubKey(ConfigurationSubKey, !Name.IsEmpty()))
     {
       std::unique_ptr<TStringList> ListSessions(LoadJumpList(Storage, L"JumpList"));
       std::unique_ptr<TStringList> ListWorkspaces(LoadJumpList(Storage, L"JumpListWorkspaces"));

+ 3 - 0
source/windows/WinConfiguration.h

@@ -609,6 +609,7 @@ protected:
   void __fastcall LoadExtensionList();
   void __fastcall ReleaseExtensionTranslations();
   void __fastcall LoadExtensionTranslations();
+  TStrings * __fastcall DoFindTemporaryFolders(bool OnlyFirst);
 
 public:
   __fastcall TWinConfiguration();
@@ -618,6 +619,8 @@ public:
   virtual THierarchicalStorage * CreateScpStorage(bool & SessionList);
   UnicodeString __fastcall TemporaryDir(bool Mask = false);
   TStrings * __fastcall FindTemporaryFolders();
+  bool __fastcall AnyTemporaryFolders();
+  void __fastcall CleanupTemporaryFolders();
   void __fastcall CleanupTemporaryFolders(TStrings * Folders = NULL);
   UnicodeString __fastcall ExpandedTemporaryDirectory();
   void __fastcall CheckDefaultTranslation();

+ 2 - 2
source/windows/WinInterface.h

@@ -193,8 +193,8 @@ void __fastcall DoAboutDialog(TConfiguration * Configuration,
 void __fastcall DoAboutDialog(TConfiguration *Configuration);
 
 // forms\Cleanup.cpp
-bool __fastcall DoCleanupDialog(TStoredSessionList *SessionList,
-    TConfiguration *Configuration);
+bool __fastcall DoCleanupDialog();
+void __fastcall DoCleanupDialogIfAnyDataAndWanted();
 
 // forms\Console.cpp
 void __fastcall DoConsoleDialog(TTerminal * Terminal,

+ 3 - 4
source/windows/WinMain.cpp

@@ -865,14 +865,13 @@ int __fastcall Execute()
     if (Params->FindSwitch(L"UninstallCleanup"))
     {
       MaintenanceTask();
+      Configuration->DontSave();
       // The innosetup cannot skip UninstallCleanup run task for silent uninstalls,
       // workaround is that we create mutex in uninstaller, if it runs silent, and
       // ignore the UninstallCleanup, when the mutex exists.
-      if ((OpenMutex(SYNCHRONIZE, false, L"WinSCPSilentUninstall") == NULL) &&
-          (MessageDialog(LoadStr(UNINSTALL_CLEANUP), qtConfirmation,
-            qaYes | qaNo, HELP_UNINSTALL_CLEANUP) == qaYes))
+      if (OpenMutex(SYNCHRONIZE, false, L"WinSCPSilentUninstall") == NULL)
       {
-        DoCleanupDialog(StoredSessions, Configuration);
+        DoCleanupDialogIfAnyDataAndWanted();
       }
     }
     else if (Params->FindSwitch(L"RegisterForDefaultProtocols") ||