Bir yükleyici oluşturmak için Inno Setup kullanıyorum.
Yükleyicinin, üzerine yazmak yerine önceki yüklü sürümü otomatik olarak kaldırmasını istiyorum. Bunu nasıl yapabilirim?
Bir yükleyici oluşturmak için Inno Setup kullanıyorum.
Yükleyicinin, üzerine yazmak yerine önceki yüklü sürümü otomatik olarak kaldırmasını istiyorum. Bunu nasıl yapabilirim?
Yanıtlar:
Sen AppId (eğer kullanılan yani değer verilen, kayıt defterinden kaldırma dize okumak mümkün olmalıdır AppID
içinde [Setup]
-bölümü). Altında bulunabilir Software\Microsoft\Windows\CurrentVersion\Uninstall\{AppId}\
(biri HKLM
veya olabilir HKCU
, bu nedenle en iyisi her ikisini de kontrol edin), nerede {AppId}
kullandığınız gerçek değerle değiştirilmelidir. UninstallString
Veya QuietUninstallString
değerlerini arayın ve olay işlevinizden Exec
çalıştırmak için işlevi kullanın InitializeSetup()
.
Güncelleme: çalışmayan alternatif çözüm ile bir [Run]
bölüm girişi kullanılarak kaldırıldı {uninstallexe}
- buna dikkat çeken tüm yorumcular sayesinde!
[Run]
Kurulum sürecinde çok geç çalıştığı için bölüm çözümünün işe yarayacağını düşünmüyorum . Inno Kurulum kılavuzundan: [Çalıştır] bölümü isteğe bağlıdır ve program başarıyla yüklendikten sonra, ancak Kurulum programı son iletişim kutusunu görüntülemeden önce yürütülecek herhangi bir sayıda programı belirtir.
Aşağıdakileri kullandım. Bunu yapmanın en basit yolu olduğundan emin değilim ama işe yarıyor.
Bu {#emit SetupSetting("AppId")}
, Inno Kurulum Ön İşlemcisine dayanan kullanır . Bunu kullanmazsanız, Uygulama Kimliğinizi doğrudan kesip yapıştırın.
[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;
Alternatifler
Ayrıca , bir adım daha ileri giden ve önceden yüklenmiş herhangi bir sürümün sürüm numarasını okuyan ve bu sürüm numarasını mevcut yükleme paketinin sürüm numarasıyla karşılaştıran "Sürüm Karşılaştırması için Inno Kurulum Komut Dosyası Örneği" blog gönderisine bakın .
... 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;
"Yalnızca eski simgeleri kaldırmak istiyorsanız" (sizinki değiştiği / güncellendiği için) şunu kullanabilirsiniz:
; attempt to remove previous versions' icons
[InstallDelete]
Type: filesandordirs; Name: {group}\*;
Bu, "kurulumun başında" çalıştırılır, bu nedenle temelde eski simgeleri kaldırır ve yenileriniz, bu tamamen yapıldıktan sonra da oraya kurulur.
Bunu her kurulumda "herhangi bir şeyin değişmesi durumunda" ikon bilge olarak yapıyorum (yine de hepsi yeniden yüklenir).
Inno Setup'ı kullanırken, bu sürüm farklı bir yükleme programı tarafından yüklenmedikçe önceki bir sürümü kaldırmanız için hiçbir neden yoktur. Aksi takdirde yükseltmeler otomatik olarak yapılır.
[InstallDelete]
Eski dosyaları / dizinleri kaldırmak için bir bölüm kullanabilirsiniz . Yeni dosyalar daha sonra kurulum sırasında doğru yerlere yerleştirilecektir.
Craig McQueen tarafından sağlanan cevap tamamen geçerli. Yine de şu yorumları eklerdim:
{#emit SetupSetting("AppId")}
Sadece benim Uygulama Kimliğini ekleyin böylece kod benim için çalışmaz.Yani, Craig McQueen'in koduyla ilgili değişiklikler şunlardır:
InstallLocation
yerine anahtarını UninstallString
tuşu.DelTree
işlevi kullanınExec(sUnInstallString, ...)
GetUninstallString()
Kaldırma işlemini zorlamak için yukarıda önerilenleri kullanan CurStepChanged()
ve disk önbelleğe alma sorunları yaşayan herkes için kaldırıcı exe'nin silinmesi için kaldırıldıktan sonra gerçekten bir süre bekleyen ilgili bir çözüm için aşağıya bakın!
[Kod] bölümünde bir kaldırıcı çalıştırabilirsiniz. Mevcut kaldırıcıya giden yolu nasıl bulacağınızı bulmanız gerekir. Basit olması için, uygulamalarımı yüklediğimde, kaldırıcıyı içeren klasöre işaret eden bir kayıt defteri dizesi değeri ekliyorum ve kaldırıcıyı yalnızca InitializeWizard geri aramasında çalıştırıyorum.
Inno kurulum kaldırıcı adlarının tümünün uninsnnn.exe biçiminde olduğunu unutmayın, bunu kodunuzda hesaba katmanız gerekir.
@ Crain Mc-Queen kodunu düzenledim, bu kodun daha iyi olduğunu düşünüyorum çünkü farklı bir projede değiştirilmeye gerek yok:
[Code]
function GetNumber(var temp: String): Integer;
var
part: String;
pos1: Integer;
begin
if Length(temp) = 0 then
begin
Result := -1;
Exit;
end;
pos1 := Pos('.', temp);
if (pos1 = 0) then
begin
Result := StrToInt(temp);
temp := '';
end
else
begin
part := Copy(temp, 1, pos1 - 1);
temp := Copy(temp, pos1 + 1, Length(temp));
Result := StrToInt(part);
end;
end;
function CompareInner(var temp1, temp2: String): Integer;
var
num1, num2: Integer;
begin
num1 := GetNumber(temp1);
num2 := GetNumber(temp2);
if (num1 = -1) or (num2 = -1) then
begin
Result := 0;
Exit;
end;
if (num1 > num2) then
begin
Result := 1;
end
else if (num1 < num2) then
begin
Result := -1;
end
else
begin
Result := CompareInner(temp1, temp2);
end;
end;
function CompareVersion(str1, str2: String): Integer;
var
temp1, temp2: String;
begin
temp1 := str1;
temp2 := str2;
Result := CompareInner(temp1, temp2);
end;
function InitializeSetup(): Boolean;
var
oldVersion: String;
uninstaller: String;
ErrorCode: Integer;
vCurID :String;
vCurAppName :String;
begin
vCurID:= '{#SetupSetting("AppId")}';
vCurAppName:= '{#SetupSetting("AppName")}';
//remove first "{" of ID
vCurID:= Copy(vCurID, 2, Length(vCurID) - 1);
//
if RegKeyExists(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1') then
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1',
'DisplayVersion', oldVersion);
if (CompareVersion(oldVersion, '{#SetupSetting("AppVersion")}') < 0) then
begin
if MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. Continue to use this old version?',
mbConfirmation, MB_YESNO) = IDYES then
begin
Result := False;
end
else
begin
RegQueryStringValue(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' + vCurID + '_is1',
'UninstallString', uninstaller);
ShellExec('runas', uninstaller, '/SILENT', '', SW_HIDE, ewWaitUntilTerminated, ErrorCode);
Result := True;
end;
end
else
begin
MsgBox('Version ' + oldVersion + ' of ' + vCurAppName + ' is already installed. This installer will exit.',
mbInformation, MB_OK);
Result := False;
end;
end
else
begin
Result := True;
end;
end;
Bir şey kaçırıyor olmalıyım. Yeni eski tesisatın kaldırılması oluşmadan önce dosyaları hedef dizine kopyalanır. Ardından kaldırıcı gelir onları siler ve dizini kaldırır.
[Çalıştır] bölümünü değil, [UninstallRun] bölümünü kullanın. Aslında, [Çalıştır] altındaki program kurulumdan sonra yürütülür ve programınızın kurulumdan hemen sonra kaldırılmasına neden olur: - | Bunun yerine, kurulumdan önce [UninstallRun] bölümü değerlendirilir .
[UninstallRun]
soru için bir çözüm değil.
Bu bağlantıyı izleyin: http://news.jrsoftware.org/news/innosetup/msg55323.html
InitializeSetup () işlevinde, eski sürümü kaldırmak için kullanıcı isteminden sonra "MSIEXEC / x {program kimliğiniz}" çağırabilirsiniz.