Registriert seit: 3. Mai 2006
Ort: Graz
445 Beiträge
Delphi 10.3 Rio
|
Re: Umstieg von InstallShield auf InnoSetup und der Upgrade
20. Apr 2010, 23:25
So, hier mal meine Lösung. Sie geht davon aus, dass die Applikation mit einem Namen und ihrer Version installiert wurde (siehe Format von CUninstallDisplayName unten). DeleteInstallShieldStrings() kann z.B.: in NextButtonClick (CurPageID = wpReady) aufgerufen werden. Natürlich wird nur ein kleiner Teil der Registry-Einträge entfernt aber für meine Zwecke reicht es, ich ersetze damit auch nur den Installer der selben Applikation.
[code=delphi]
Code:
Const
CUninstallDisplayName = 'MyApplication v1.10.2010.1';
procedure ExtractData(DisplayName: String; Var AppName: String; Var Major, Minor: Integer);
var
iIdx: Integer;
iStart: Integer;
s: String;
begin
// Annahme: alles geht schief :D
AppName := '';
Major := 9999;
Minor := 9999;
//
if DisplayName <> '' then
begin
iIdx := Length(DisplayName);
while (iIdx > 1) And (DisplayName[iIdx] <> ' ') do
iIdx := iIdx - 1;
//
if DisplayName[iIdx] = ' ' then
begin
AppName := Copy(DisplayName, 1, iIdx-1); // Wir haben den DisplayName ohne Version
//
Delete(DisplayName, 1, iIdx);
iIdx := Pos('.', DisplayName);
if iIdx > 0 then
begin
s := Copy(DisplayName, 1, iIdx-1); // s = MajorVersion (eventuell noch mit an "v" vorne
Delete(DisplayName, 1, iIdx);
while (s <> '') And ((s[1] < '0') Or (s[1] > '9')) do
Delete(s, 1, 1);
try
Major := StrToInt(s);
except
end;
//
iIdx := Pos('.', DisplayName); // MinorVersion....
if iIdx > 0 then
begin
s := Copy(DisplayName,1,iIdx-1);
try
Minor := StrToInt(s);
except
end;
end;
end; // Else Error kein "."
end;
end;
end;
procedure DeleteInstallShieldStrings();
var
iKeys: TArrayOfString;
i: Integer;
sUPath, s: String;
iValue: String;
iMajor, iMinor: Integer;
iCurrMajor, iCurrMinor: Integer;
iAppName: String;
iDNLen: Integer;
begin
ExtractData(CUninstallDisplayName, iAppName, iMajor, iMinor);
iDNLen := Length(iAppName);
sUPath := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
if RegGetSubKeyNames(HKEY_LOCAL_MACHINE, sUPath, iKeys) Then
begin
for i := 0 to GetArrayLength(iKeys)-1 do
begin
If RegValueExists(HKEY_LOCAL_MACHINE, sUPath + '\' + iKeys[i], 'DisplayName') Then
begin
If RegQueryStringValue(HKEY_LOCAL_MACHINE, sUPath + '\' + iKeys[i], 'DisplayName', iValue) Then
begin
s := Copy(iValue, 1, iDNLen);
If CompareText(s, iAppName)=0 Then
begin
ExtractData(iValue, s, iCurrMajor, iCurrMinor);
If (iCurrMajor < iMajor) Or ((iCurrMajor = iMajor) And (iCurrMinor <= iMinor)) Then
begin
// raus damit ....
RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, sUPath + '\' + iKeys[i]);
end;
end;
end;
End;
end;
end;
//
// nächste runde (ISX und M$ sind ein "nasty beast")
//
sUPath := 'Installer\Products';
if RegGetSubKeyNames(HKEY_CLASSES_ROOT, sUPath, iKeys) Then
begin
for i := 0 to GetArrayLength(iKeys)-1 do
begin
If RegValueExists(HKEY_CLASSES_ROOT, sUPath + '\' + iKeys[i], 'ProductName') Then
begin
If RegQueryStringValue(HKEY_CLASSES_ROOT, sUPath + '\' + iKeys[i], 'ProductName', iValue) Then
begin
s := Copy(iValue, 1, iDNLen);
If CompareText(s, iAppName)=0 Then
begin
// Da sich hier nur InstallShield einträgt killen wir den Key ohne weitere tests
RegDeleteKeyIncludingSubkeys(HKEY_CLASSES_ROOT, sUPath + '\' + iKeys[i]);
end;
End;
End;
End;
End;
// Das ist noch nicht alles ... aber es reicht :D (hoffentlich)
end;
Whookie
Software isn't released ... it is allowed to escape!
|