[Code] var HasLegacyVersion: Boolean; LegacyStartMenuFolder: string; LegacyInstallFolder: string; LegacyVersionNumber: string; function OldStartMenuFolder(Param: string): string; begin if HasLegacyVersion then Result := LegacyStartMenuFolder else Result := ExpandConstant('{group}'); end; function OldInstallFolder(Param: string): string; begin if HasLegacyVersion then Result := LegacyInstallFolder else Result := ExpandConstant('{app}'); end; function BoolToStr(x: Boolean): string; begin if x then Result := 'Yes' else Result := 'No'; end; function InitializeSetupMigration: Boolean; begin LegacyStartMenuFolder := 'Aegisub'; LegacyInstallFolder := ExpandConstant('{pf}\Aegisub'); LegacyVersionNumber := '1.x'; try HasLegacyVersion := RegValueExists(HKLM, 'SOFTWARE\Aegisub\info', 'InstVer'); Log(Format('Legacy version found: %s', [BoolToStr(HasLegacyVersion)])); if RegQueryStringValue(HKLM, 'SOFTWARE\Aegisub\info', 'StartMenuDir', LegacyStartMenuFolder) then LegacyStartMenuFolder := ExpandConstant('{userprograms}\') + LegacyStartMenuFolder; Log(Format('Legacy version Start menu folder: %s', [LegacyStartMenuFolder])); RegQueryStringValue(HKLM, 'SOFTWARE\Aegisub\info', 'InstallDir', LegacyInstallFolder); Log(Format('Legacy version install folder: %s', [LegacyInstallFolder])); RegQueryStringValue(HKLM, 'SOFTWARE\Aegisub\info', 'InstVer', LegacyVersionNumber); except Log('An exception occurred while trying to detect a legacy installation of Aegisub. Assuming there isn''t one.'); HasLegacyVersion := False; end; Result := True; if HasLegacyVersion then Result := SuppressibleMsgBox(Format('A previous installation of Aegisub %s has been detected and will be removed along with its configuration.'#13#10#13#10'Continue installing and remove old version?', [LegacyVersionNumber]), mbConfirmation, MB_YESNO, IDYES) = IDYES; end; procedure MigrateStyleCatalogs; var OldCatalogDir: string; NewCatalogDir: string; search: TFindRec; begin try // Upgrade an 1.x style-catalog by moving it to {appdata} OldCatalogDir := OldInstallFolder('') + '\Catalog\'; Log('-- Migrate style catalogs --'); if DirExists(OldCatalogDir) then begin NewCatalogDir := ExpandConstant('{userappdata}\Aegisub\catalog\'); ForceDirectories(NewCatalogDir); Log('Old style catalog dir: ' + OldCatalogDir); Log('New catalog dir: ' + NewCatalogDir); if FindFirst(OldCatalogDir + '*', search) then try repeat Log('Found style catalog: ' + OldCatalogDir + search.Name); if FileCopy(OldCatalogDir+search.Name, NewCatalogDir+search.Name, True) then begin Log('Copied catalog to: ' + NewCatalogDir+search.Name); DeleteFile(OldCatalogDir+search.Name); end; until not FindNext(search); finally FindClose(search); Log('Done migrating styles'); end; RemoveDir(OldCatalogDir); end else Log('No existing style catalog collection found'); except Log('An exception occurred while trying to migrate style catalogues.'); end; end; procedure UninstallLegacyVersion; var page: TOutputProgressWizardPage; file_list: TStringList; dir_list: TStringList; shortcut_list: TStringList; locale_list: TStringList; itemsdone, totalitems, i: Integer; curname: string; begin // Uninstall Aegisub 1.x Log('-- Uninstall legacy version --'); page := CreateOutputProgressPage('Uninstalling old version', 'Your old installation of Aegisub is being removed'); try page.SetText('Preparing list of files', ''); page.Show; Log('Load file lists'); ExtractTemporaryFile('legacy_shortcutlist.txt'); ExtractTemporaryFile('legacy_filelist.txt'); ExtractTemporaryFile('legacy_locales.txt'); ExtractTemporaryFile('legacy_dirlist.txt'); shortcut_list := TStringList.Create; shortcut_list.LoadFromFile(ExpandConstant('{tmp}\legacy_shortcutlist.txt')); file_list := TStringList.Create; file_list.LoadFromFile(ExpandConstant('{tmp}\legacy_filelist.txt')); locale_list := TStringList.Create; locale_list.LoadFromFile(ExpandConstant('{tmp}\legacy_locales.txt')); dir_list := TStringList.Create; dir_list.LoadFromFile(ExpandConstant('{tmp}\legacy_dirlist.txt')); itemsdone := 0; totalitems := file_list.Count + dir_list.Count + shortcut_list.Count + locale_list.Count + 3; // Two extra for the registry keys and one for Start menu folder for i := 0 to shortcut_list.Count-1 do begin try curname := LegacyStartMenuFolder + '\' + shortcut_list.Strings[i]; // Check that the link points to somewhere in the dir we're installing to so we don't // delete a shortcut to something else page.SetText('Removing shortcuts', curname); if Pos(LegacyInstallFolder, RemoveQuotes(ReadShellLink(curname))) = 1 then begin page.SetProgress(itemsdone, totalitems); Log('Remove shortcut: ' + curname); if not DeleteFile(curname) then Log('* Deletion failed'); itemsdone := itemsdone + 1; end else Log('Not deleting shortcut, not to old installation: ' + curname); except Log('Exception removing shortcut: ' + curname); end; end; page.SetText('Removing Start menu folder', LegacyStartMenuFolder); page.SetProgress(itemsdone, totalitems); Log('Remove directory: ' + LegacyStartMenuFolder); if not RemoveDir(LegacyStartMenuFolder) then Log('* Directory deletion failed'); itemsdone := itemsdone + 1; for i := 0 to file_list.Count-1 do begin curname := LegacyInstallFolder + '\' + file_list.Strings[i]; page.SetText('Removing files', curname); page.SetProgress(itemsdone, totalitems); Log('Remove file: ' + curname); if not DeleteFile(curname) then Log('* Deletion failed'); itemsdone := itemsdone + 1; end; for i := 0 to locale_list.Count-1 do begin curname := LegacyInstallFolder + '\' + locale_list.Strings[i]; page.SetText('Removing folders', curname); page.SetProgress(itemsdone, totalitems); Log('Remove directory recursively: ' + curname); if not DelTree(curname, True, True, True) then Log('* Tree deletion failed'); itemsdone := itemsdone + 1; end; for i := 0 to dir_list.Count-1 do begin curname := LegacyInstallFolder + '\' + dir_list.Strings[i]; page.SetText('Removing folders', curname); page.SetProgress(itemsdone, totalitems); Log('Remove directory: ' + curname); if not RemoveDir(curname) then Log('* Directory deletion failed'); itemsdone := itemsdone + 1; end; page.SetText('Removing registry entries', 'Installation data'); page.SetProgress(itemsdone, totalitems); curname := 'SOFTWARE\Aegisub'; Log('Remove reg key: HKLM\' + curname); if not RegDeleteKeyIncludingSubkeys(HKLM, curname) then Log('* Failed recursively deleting key'); page.SetText('Removing registry entries', 'Uninstaller entry'); page.SetProgress(itemsdone+1, totalitems); curname := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Aegisub ' + LegacyVersionNumber; Log('Remove reg key: HKLM\' + curname); if not RegDeleteKeyIncludingSubkeys(HKLM, curname) then Log('* Failed recursively deleting key'); page.SetText('Uninstallation complete', ''); page.SetProgress(totalitems, totalitems); except Log('An exception occurred while trying to uninstall a legacy version'); finally shortcut_list.Free; file_list.Free; locale_list.Free; dir_list.Free; page.Hide; end; end; function SetFileAttributes(lpFileName: WideString; dwFileAttributes: Longint): Boolean; external 'SetFileAttributesW@kernel32.dll stdcall'; procedure CleanUpOldVersion; var StartMenuFolder, InstallFolder: string; page: TOutputProgressWizardPage; file_list: TStringList; dir_list: TStringList; shortcut_list: TStringList; locale_list: TStringList; itemsdone, totalitems, i: Integer; curname, linktarget: string; begin // Clean up from previous Aegisub 2.x installs Log('-- Clean up old versions --'); page := CreateOutputProgressPage('Cleaning old versions', 'Cleaning up from older versions of Aegisub 2'); try page.SetText('Preparing list of files', ''); page.Show; Log('Load file lists'); ExtractTemporaryFile('old_shortcutlist.txt'); ExtractTemporaryFile('old_filelist.txt'); ExtractTemporaryFile('old_locales.txt'); ExtractTemporaryFile('old_dirlist.txt'); shortcut_list := TStringList.Create; shortcut_list.LoadFromFile(ExpandConstant('{tmp}\old_shortcutlist.txt')); file_list := TStringList.Create; file_list.LoadFromFile(ExpandConstant('{tmp}\old_filelist.txt')); locale_list := TStringList.Create; locale_list.LoadFromFile(ExpandConstant('{tmp}\old_locales.txt')); dir_list := TStringList.Create; dir_list.LoadFromFile(ExpandConstant('{tmp}\old_dirlist.txt')); itemsdone := 0; totalitems := file_list.Count + dir_list.Count + shortcut_list.Count + locale_list.Count + 2; // Two extra: // - Start menu folder // - Renaming Aegisub.exe to aegiub32.exe StartMenuFolder := ExpandConstant('{commonprograms}\Aegisub\'); InstallFolder := ExpandConstant('{app}\'); for i := 0 to shortcut_list.Count-1 do begin try curname := StartMenuFolder + '\' + shortcut_list.Strings[i]; // Check that the link points to somewhere in the dir we're installing to so we don't // delete a shortcut to something else page.SetText('Removing shortcuts', curname); linktarget := ReadShellLink(curname); if Pos(InstallFolder, RemoveQuotes(linktarget)) = 1 then begin page.SetProgress(itemsdone, totalitems); Log('Remove shortcut: ' + curname); if not DeleteFile(curname) then Log('* Deletion failed'); itemsdone := itemsdone + 1; end else begin Log('Not deleting shortcut, not to old installation: ' + curname); Log('Link target: "' + linktarget + '"; Install folder: "' + InstallFolder + '"'); end; except Log('Exception removing shortcut: ' + curname); end; end; page.SetText('Removing Start menu folder', StartMenuFolder); page.SetProgress(itemsdone, totalitems); Log('Remove directory: ' + StartMenuFolder); if not RemoveDir(StartMenuFolder) then Log('* Directory deletion failed'); itemsdone := itemsdone + 1; for i := 0 to file_list.Count-1 do begin curname := InstallFolder + file_list.Strings[i]; page.SetText('Removing files', curname); page.SetProgress(itemsdone, totalitems); Log('Remove file: ' + curname); SetFileAttributes(curname, 128); // 128 = FILE_ATTRIBUTE_NORMAL if not DeleteFile(curname) then Log('* Deletion failed'); itemsdone := itemsdone + 1; end; // This moving is done to help Windows' link tracking code be able to fix shortcuts page.SetText('Moving EXE file to new name', 'Aegisub.exe'); page.SetProgress(itemsdone, totalitems); Log('Rename Aegisub.exe to aegisub32.exe'); RenameFile(InstallFolder+'Aegisub.exe', InstallFolder+'aegisub32.exe'); itemsdone := itemsdone + 1; for i := 0 to locale_list.Count-1 do begin curname := InstallFolder + locale_list.Strings[i]; page.SetText('Removing folders', curname); page.SetProgress(itemsdone, totalitems); Log('Remove directory recursively: ' + curname); if not DelTree(curname, True, True, True) then Log('* Tree deletion failed'); itemsdone := itemsdone + 1; end; for i := 0 to dir_list.Count-1 do begin curname := InstallFolder + dir_list.Strings[i]; page.SetText('Removing folders', curname); page.SetProgress(itemsdone, totalitems); Log('Remove directory: ' + curname); if not RemoveDir(curname) then Log('* Directory deletion failed'); itemsdone := itemsdone + 1; end; page.SetText('Uninstallation complete', ''); page.SetProgress(totalitems, totalitems); except Log('An exception occurred while trying to clean up an older version'); finally shortcut_list.Free; file_list.Free; locale_list.Free; dir_list.Free; page.Hide; end; end; procedure CurStepChangedMigration(CurStep: TSetupStep); begin if CurStep = ssInstall then begin if HasLegacyVersion then begin MigrateStyleCatalogs; UninstallLegacyVersion; end; CleanUpOldVersion; end; end;