Einzelnen Beitrag anzeigen

Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
445 Beiträge
 
Delphi 10.3 Rio
 
#2

Re: Umstieg von InstallShield auf InnoSetup und der Upgrade

  Alt 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!
  Mit Zitat antworten Zitat