Używam Inno Setup do tworzenia instalatora.
Chcę, aby instalator automatycznie odinstalował poprzednio zainstalowaną wersję, zamiast ją nadpisywać. Jak mogę to zrobić?
installation
inno-setup
Quan Mai
źródło
źródło
Odpowiedzi:
Powinno być możliwe odczytanie ciągu dezinstalacji z rejestru, biorąc pod uwagę identyfikator AppId (tj. Wartość użytą
AppID
w sekcji[Setup]
). Można go znaleźć podSoftware\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\
(może być alboHKLM
alboHKCU
, więc najlepiej sprawdzić oba), gdzie{AppId}
należy go zastąpić rzeczywistą użytą wartością. Poszukaj wartościUninstallString
lubQuietUninstallString
i użyjExec
funkcji, aby uruchomić ją zInitializeSetup()
funkcji zdarzenia.Aktualizacja: usunięto niedziałające alternatywne rozwiązanie z użyciem
[Run]
wpisu sekcji z{uninstallexe}
- podziękowania dla wszystkich komentujących, którzy zwrócili na to uwagę!źródło
[Run]
rozwiązanie sekcji działało, ponieważ działa zbyt późno w procesie instalacji. Z podręcznika Inno Setup: Sekcja [Run] jest opcjonalna i określa dowolną liczbę programów do wykonania po pomyślnym zainstalowaniu programu, ale zanim program instalacyjny wyświetli ostatnie okno dialogowe.Użyłem następujących. Nie jestem pewien, czy to najprostszy sposób, ale działa.
To używa,
{#emit SetupSetting("AppId")}
który opiera się na Preprocesorze Inno Setup. Jeśli tego nie używasz, wytnij i wklej swój identyfikator aplikacji bezpośrednio.[Code] { ///////////////////////////////////////////////////////////////////// } function GetUninstallString(): String; var sUnInstPath: String; sUnInstallString: String; begin sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#emit SetupSetting("AppId")}_is1'); sUnInstallString := ''; if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); Result := sUnInstallString; end; { ///////////////////////////////////////////////////////////////////// } function IsUpgrade(): Boolean; begin Result := (GetUninstallString() <> ''); end; { ///////////////////////////////////////////////////////////////////// } function UnInstallOldVersion(): Integer; var sUnInstallString: String; iResultCode: Integer; begin { Return Values: } { 1 - uninstall string is empty } { 2 - error executing the UnInstallString } { 3 - successfully executed the UnInstallString } { default return value } Result := 0; { get the uninstall string of the old app } sUnInstallString := GetUninstallString(); if sUnInstallString <> '' then begin sUnInstallString := RemoveQuotes(sUnInstallString); if Exec(sUnInstallString, '/SILENT /NORESTART /SUPPRESSMSGBOXES','', SW_HIDE, ewWaitUntilTerminated, iResultCode) then Result := 3 else Result := 2; end else Result := 1; end; { ///////////////////////////////////////////////////////////////////// } procedure CurStepChanged(CurStep: TSetupStep); begin if (CurStep=ssInstall) then begin if (IsUpgrade()) then begin UnInstallOldVersion(); end; end; end;
Alternatywy
Zobacz także ten wpis na blogu „Inno Setup Script Sample for Version Porównanie”, który idzie o krok dalej i czyta numer każdej poprzednio zainstalowanej wersji i porównuje ten numer z numerem bieżącego pakietu instalacyjnego.
źródło
... UserSIDs: TArrayOfString; I: Integer; ... if not RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString) then if isAdminLoggedOn() and RegGetSubkeyNames( HKEY_USERS, '', UserSIDs ) then for I := 0 to GetArrayLength( UserSIDs ) - 1 do begin if RegQueryStringValue( HKEY_USERS, UserSIDs[I] + '\' + sUnInstPath, 'UninstallString', sUnInstallString ) then break; end;
Jeśli chcesz „tylko usunąć stare ikony” (ponieważ Twoje uległy zmianie / aktualizacji), możesz użyć tego:
Jest to uruchamiane „na początku instalacji”, więc zasadniczo usuwa stare ikony, a nowe będą nadal tam instalowane po zakończeniu instalacji.
Po prostu robię to przy każdej instalacji "na wypadek, gdyby coś się zmieniło" pod względem ikon (wszystko i tak zostanie ponownie zainstalowane).
źródło
Podczas korzystania z Inno Setup nie ma powodu, aby odinstalować poprzednią wersję, chyba że ta wersja została zainstalowana przez inny program instalacyjny. W przeciwnym razie aktualizacje są obsługiwane automatycznie.
źródło
[InstallDelete]
sekcji, aby usunąć stare pliki / katalogi. Nowe pliki zostaną następnie umieszczone we właściwych lokalizacjach podczas instalacji.Odpowiedź udzielona przez Craiga McQueena jest całkowicie realna. Chociaż dodałbym te uwagi:
{#emit SetupSetting("AppId")}
Kod nie działa dla mnie, więc po prostu dodać swój identyfikator aplikacji.Tak więc, jeśli chodzi o kod Craiga McQueena, zmiany są następujące:
InstallLocation
klucz zamiastUninstallString
klucza.DelTree
funkcji zamiastExec(sUnInstallString, ...)
źródło
Dla każdego, kto używa
GetUninstallString()
sugerowanego powyżej, aby wymusić odinstalowanie wewnątrzCurStepChanged()
i ma problemy z buforowaniem dysku, zobacz poniżej powiązane rozwiązanie, które faktycznie czeka chwilę po odinstalowaniu na usunięcie deinstalatora exe!Problem z pamięcią podręczną dysku w przypadku inno-setup?
źródło
Możesz uruchomić deinstalator w sekcji [kod]. Musisz dowiedzieć się, jak uzyskać ścieżkę do istniejącego deinstalatora. Dla uproszczenia podczas instalowania aplikacji dodaję wartość ciągu rejestru wskazującą na folder zawierający dezinstalator i po prostu wykonuję deinstalator w wywołaniu zwrotnym InitializeWizard.
Należy pamiętać, że wszystkie nazwy deinstalatorów instalacji Inno mają postać uninsnnn.exe, należy to uwzględnić w kodzie.
źródło
Mam edytowany kod @Crain Mc-Queen, myślę, że ten kod jest lepszy, ponieważ nie trzeba go modyfikować w innym projekcie:
źródło
Muszę czegoś przegapić. Te nowe pliki zostaną skopiowane do katalogu docelowego, zanim nastąpi usunięcie starej instalacji. Następnie deinstalator usuwa je i usuwa katalog.
źródło
Nie używaj sekcji [Run], ale [UninstallRun]. W rzeczywistości programy w [Run] są uruchamiane po instalacji, powodując odinstalowanie programu natychmiast po instalacji: - | Zamiast tego sekcja [UninstallRun] jest sprawdzana przed instalacją.
źródło
[UninstallRun]
nie jest rozwiązaniem na to pytanie.Skorzystaj z tego łącza: http://news.jrsoftware.org/news/innosetup/msg55323.html
W funkcji InitializeSetup () możesz wywołać „MSIEXEC / x {identyfikator Twojego programu}” po wyświetleniu monitu użytkownika o odinstalowanie starej wersji
źródło