Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  util_uninst.isi  Sprache: unbekannt

 
Spracherkennung für: .isi vermutete Sprache: Lisp {Lisp[51] Masm[51] Delphi[42]} [Methode: maximale Elemente, drei Dimensionen]

#if 0
[Code]
#endif

var
 asUninstInf: TArrayOfString; //uninst.inf contents (loaded at start of uninstall, executed at the end)

function SplitRegParams(const pInf: String; var oRootKey: Integer; var oKey,oValue: String): Boolean;
var sRootKey: String;
 d: Integer;
begin
 Result := False;

 d := Pos('/',pInf);
 if d = 0 then
 begin
  DebugMsg('SplitRegParams','Malformed line (missing /): ' + pInf);
  exit;
 end;

 sRootKey := Copy(pInf,1,d - 1);
 oKey := Copy(pInf,d + 1,Length(pInf));

 if oValue <> 'nil' then
 begin
  d := RevPos('\',oKey);
  if d = 0 then
  begin
   DebugMsg('SplitRegParams','Malformed line (missing \): ' + pInf);
   exit;
  end;

  oValue := Decode(Copy(oKey,d+1,Length(oKey)));
  oKey := Copy(oKey,1,d-1);
 end;

 DebugMsg('SplitRegParams','Root: '+sRootKey+', Key:'+oKey + ', Value:'+oValue);

 case sRootKey of
 'HKCR': oRootKey := HKCR;
 'HKLM': oRootKey := HKLM;
 'HKU': oRootKey := HKU;
 'HKCU': oRootKey := HKCU;
 else
  begin
   DebugMsg('SplitRegParams','Unrecognised root key: ' + sRootKey);
   exit;
  end;
 end;

 Result := True;
end;


procedure UninstInfRegKey(const pInf: String; const pIfEmpty: Boolean);
var sKey,sVal: String;
 iRootKey: Integer;
begin
 sVal := 'nil';
 if not SplitRegParams(pInf,iRootKey,sKey,sVal) then
  exit;

 if pIfEmpty then
 begin
  if not RegDeleteKeyIfEmpty(iRootKey,sKey) then
   DebugMsg('UninstInfRegKey','RegDeleteKeyIfEmpty failed');
 end
 else
 begin
  if not RegDeleteKeyIncludingSubkeys(iRootKey,sKey) then
   DebugMsg('UninstInfRegKey','RegDeleteKeyIncludingSubkeys failed');
 end;
end;


procedure UninstInfRegVal(const pInf: String);
var sKey,sVal: String;
 iRootKey: Integer;
begin
 if not SplitRegParams(pInf,iRootKey,sKey,sVal) then
  exit;

 if not RegDeleteValue(iRootKey,sKey,sVal) then
  DebugMsg('UninstInfREG','RegDeleteKeyIncludingSubkeys failed');
end;


procedure UninstInfFile(const pFile: String);
begin
 DebugMsg('UninstInfFile','File: '+pFile);

 if not DeleteFile(pFile) then
  DebugMsg('UninstInfFile','DeleteFile failed');
end;


procedure UninstInfDir(const pDir: String);
begin
 DebugMsg('UninstInfDir','Dir: '+pDir);

 if not RemoveDir(pDir) then
  DebugMsg('UninstInfDir','RemoveDir failed');
end;


procedure CreateMessageForm(var frmMessage: TForm; const pMessage: String);
var lblMessage: TNewStaticText;
begin
 frmMessage := CreateCustomForm(ScaleX(256), ScaleY(128), False, True);
 with frmMessage do
 begin
  BorderStyle := bsDialog;

  ClientWidth := ScaleX(300);
  ClientHeight := ScaleY(48);

  Caption := CustomMessage('UninstallingAddOnCaption');

  Position := poScreenCenter;

  BorderIcons := [];
 end;

 lblMessage := TNewStaticText.Create(frmMessage);
 with lblMessage do
 begin
  Parent := frmMessage;
  AutoSize := True;
  Caption := pMessage;
  Top := (frmMessage.ClientHeight - Height) div 2;
  Left := (frmMessage.ClientWidth - Width) div 2;
  Visible := True;
 end;

 frmMessage.Show();

    frmMessage.Refresh();
end;


procedure UninstInfRun(const pInf: String);
var Description,Prog,Params: String;
 Split, ResultCode, Ctr: Integer;
 frmMessage: TForm;
begin
 DebugMsg('UninstInfRun',pInf);

 Split := Pos('/',pInf);
 if Split <> 0 then
 begin
  Description := Copy(pInf, 1, Split - 1);
  Prog := Copy(pInf, Split + 1, Length(pInf));
 end else
 begin
  Prog := pInf;
  Description := '';
 end;

 Split := Pos('/',Prog);
 if Split <> 0 then
 begin
  Params := Copy(Prog, Split + 1, Length(Prog));
  Prog := Copy(Prog, 1, Split - 1);
 end else
 begin
  Params := '';
 end;

 if not UninstallSilent then //can't manipulate uninstaller messages, so create a form instead
  CreateMessageForm(frmMessage,Description);

 DebugMsg('UninstInfRun','Running: ' + Prog + '; Params: ' + Params);

 if Exec(Prog,Params,'',SW_SHOW,ewWaitUntilTerminated,ResultCode) then
 begin
  DebugMsg('UninstInfRun','Exec result: ' + IntToStr(ResultCode));

  Ctr := 0;
  while FileExists(Prog) do //wait a few seconds for the uninstaller to be deleted - since this is done by a program
  begin                     //running from a temporary directory, the uninstaller we ran above will exit some time before
   Sleep(UNINSTALL_CHECK_TIME);           //it's removed from disk
   Inc(Ctr);
   if Ctr = (UNINSTALL_MAX_WAIT_TIME/UNINSTALL_CHECK_TIME) then //don't wait more than 5 seconds
    break;
  end;

 end else
  DebugMsg('UninstInfRun','Exec failed: ' + IntToStr(ResultCode) + ' (' + SysErrorMessage(ResultCode) + ')');

 if not UninstallSilent then
  frmMessage.Free();
end;

(*
uninst.inf documentation:

- Delete Registry keys (with all subkeys):
  RegKey:<RootKey>/<SubKey>
    RootKey = HKCR, HKLM, HKCU, HKU
    SubKey = subkey to delete (warning: this will delete all keys under subkey, so be very careful with it)

- Delete empty registry keys:
  RegKeyEmpty:<RootKey>/<SubKey>
    RootKey = HKCR, HKLM, HKCU, HKU
    SubKey = subkey to delete if empty

- Delete values from registry:
  RegVal:<RootKey>/<SubKey>/Value
    RootKey = HKCR, HKLM, HKCU, HKU
    SubKey = subkey to delete Value from
    Value = value to delete; \ and % must be escaped as %5c and %25

- Delete files:
  File:<Path>
    Path = full path to file

- Delete empty directories:
  Dir:<Path>

- Run program with parameters:
  Run:<description>/<path>/<params>

Directives are parsed from the end of the file backwards as the first step of uninstall.

IMPORTANT: From GIMP 2.10.12 onwards (Inno Setup 6 with support for per-user install), Registry keys referring to HKCR will be
processed by the installer as the first step of install (and the entries will be removed from uninst.inf), since file associations
code was rewritten.

*)
procedure ParseUninstInf();
var i,d: Integer;
 sWhat: String;
begin
 for i := GetArrayLength(asUninstInf) - 1 downto 0 do
 begin

  DebugMsg('ParseUninstInf',asUninstInf[i]);

  if (Length(asUninstInf[i]) = 0) or (asUninstInf[i][1] = '#') then //skip comments and empty lines
   continue;

  d := Pos(':',asUninstInf[i]);
  if d = 0 then
  begin
   DebugMsg('ParseUninstInf','Malformed line: ' + asUninstInf[i]);
   continue;
  end;

  sWhat := Copy(asUninstInf[i],d+1,Length(asUninstInf[i]));

  case Copy(asUninstInf[i],1,d) of
  'RegKey:': UninstInfRegKey(sWhat,False);
  'RegKeyEmpty:': UninstInfRegKey(sWhat,True);
  'RegVal:': UninstInfRegVal(sWhat);
  'File:': UninstInfFile(sWhat);
  'Dir:': UninstInfDir(sWhat);
  'Run:': UninstInfRun(sWhat);
  end;

 end;

end;

procedure RestorePointU();
var
  ResultCode: Integer;
begin
  UninstallProgressForm.StatusLabel.Caption := CustomMessage('CreatingRestorePoint');
  if not ShellExec('RunAs', 'powershell', '-Command "$job = Start-Job -ScriptBlock { Checkpoint-Computer -Description "GIMP_' + ExpandConstant('{#CUSTOM_GIMP_VERSION}') + '_uninstall" -RestorePointType APPLICATION_UNINSTALL }; Wait-Job $job -Timeout 24; if ($job.State -eq \"Running\") { Stop-Job $job -Confirm:$false }; Receive-Job $job"',
                   '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
  begin
    DebugMsg('RestorePointU','Failed to create restore point. Error code: ' + IntToStr(ResultCode));
  end;
end;

#define API_MAJOR=Copy(GIMP_PKGCONFIG_VERSION,1,Pos(".",GIMP_PKGCONFIG_VERSION)-1)

//Taken from https://github.com/GrayWorldFinex/InnoSetupScripts/blob/main/Src%20Code/cdx-gridberd.iss
Procedure MoveFile(SourceFile, DestFile: {#defined UNICODE ? "Ansi" : ""}String);
  Begin
   FileCopy(SourceFile, DestFile, False);
  End;

Function ProcessFiles(S: {#defined UNICODE ? "Ansi" : ""}String): array of {#defined UNICODE ? "Ansi" : ""}String;
  var
   i, k: Integer;
  Begin
   repeat
    i := Pos(',', S);
    k := GetArrayLength(Result);
    SetArrayLength(Result, k + 1);
    If (i > 0) then begin
     Result[k] := Copy(S, 1, i - 1);
     Delete(S, 1, i); end
    else begin
     Result[k] := S;
     SetLength(S, 0);
    end;
   until (Length(S) = 0);
  End;

Procedure CopyFiles(SourceDir, DestDir, ExcludeFiles: {#defined UNICODE ? "Ansi" : ""}String);
  var
   FSR, DSR: TFindRec;
   FindResult, Exclude: Boolean;
   SourceFile, DestFile:{#defined UNICODE ? "Ansi" : ""}String;
   i, k: Integer;
   SS: Array of {#defined UNICODE ? "Ansi" : ""}String;
  Begin
   SetArrayLength(SS, 0);
   SS := ProcessFiles(ExcludeFiles);
   k := GetArrayLength(SS);
   If not DirExists(DestDir) Then Begin
    CreateDir(DestDir);
   End;
   FindResult := FindFirst(AddBackslash(SourceDir) + '*.*', FSR);
   Try
    While FindResult Do Begin
     If FSR.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 Then Begin
      Exclude := False;
      For i := 0 To k - 1 Do Begin
       If AnsiLowercase(SS[i]) = AnsiLowercase(FSR.Name) Then Begin
        Exclude := True;
        Break;
       End;
      End;
      If not Exclude Then Begin
       SourceFile := AddBackslash(SourceDir) + FSR.Name;
       DestFile := AddBackslash(DestDir) + FSR.Name;
       MoveFile(SourceFile, DestFile);
      End;
     End;
     FindResult := FindNext(FSR);
    End;
    FindResult := FindFirst(AddBackslash(SourceDir) + '*.*', DSR);
    While FindResult Do Begin
     If ((DSR.Attributes and FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY) and not ((DSR.Name = '.') or (DSR.Name = '..')) Then Begin
      CopyFiles(AddBackslash(SourceDir) + DSR.Name, AddBackslash(DestDir) + DSR.Name, ExcludeFiles);
     End;
     FindResult := FindNext(DSR);
    End;
   Finally
    FindClose(FSR);
    FindClose(DSR);
   End;
  End;

function Time(ATimerPtr: integer): integer; external '_time32@ucrtbase.dll cdecl';

procedure CurUninstallStepChanged(CurStep: TUninstallStep);
var
 gimp_directory: String;
begin
 DebugMsg('CurUninstallStepChanged','');
 case CurStep of
 usUninstall:
 begin
  //Try to make restore point before unninstalling (like before installing, see RestorePoint() on *gimp3264.iss)
  if IsAdminInstallMode() then begin
      RestorePointU();
   UninstallProgressForm.StatusLabel.Caption := FmtMessage(SetupMessage(msgStatusUninstalling),['GIMP']);
  end;

  LoadStringsFromFile(ExpandConstant('{app}\uninst\uninst.inf'),asUninstInf);
  ParseUninstInf();
 end;
 usPostUninstall:
 begin
  //Offer option to remove %AppData%/GIMP/GIMP_APP_VERSION dir so have a future clean install
  if not IsAdminInstallMode() then begin
            gimp_directory := GetEnv('GIMP{#API_MAJOR}_DIRECTORY');
   if gimp_directory = '' then begin
    gimp_directory := ExpandConstant('{userappdata}\GIMP\{#GIMP_APP_VERSION}');
   end;
   if DirExists(gimp_directory + '\') then begin
    if SuppressibleMsgBox(CustomMessage('UninstallConfig'), mbError, MB_YESNO or MB_DEFBUTTON2, IDNO) = IDYES then begin
     CopyFiles(gimp_directory, ExpandConstant('{userdesktop}\gimp_{#GIMP_APP_VERSION}_backup_' + Format('%d', [Time(0)])), '');
     DelTree(gimp_directory, True, True, True);
    end;
   end;
     end;
 end;
 end;
end;


procedure AssociationsCleanUp();
var i, d, countNew,countUI: Integer;
 asTemp, asNew: TArrayOfString;
 sKey,sVal: String;
 iRootKey: Integer;
begin
 if FileExists(ExpandConstant('{app}\uninst\uninst.inf')) then
 begin
  DebugMsg('AssociationsCleanUp','Parsing old uninst.inf');
  LoadStringsFromFile(ExpandConstant('{app}\uninst\uninst.inf'),asTemp);

  countNew := 0;
  countUI := 0;
  SetArrayLength(asNew, GetArrayLength(asTemp));
  SetArrayLength(asUninstInf, GetArrayLength(asTemp));

  for i := 0 to GetArrayLength(asTemp) - 1 do //extract associations-related entries from uninst.inf
  begin

   if (Length(asTemp[i]) = 0) or (asTemp[i][1] = '#') then //comment/empty line
   begin
    asNew[countNew] := asTemp[i];
    Inc(countNew);
    continue;
   end;

   d := Pos(':',asTemp[i]);
   if d = 0 then //something wrong, ignore
    continue;

   if Copy(asTemp[i],1,3) = 'Reg' then
   begin

    sVal := 'nil';
    if not SplitRegParams(Copy(asTemp[i], d + 1, Length(asTemp[i])),iRootKey,sKey,sVal) then
     continue; //malformed line, ignore

    if iRootKey = HKCR then //old association, prepare for cleanup
    begin
     DebugMsg('AssociationsCleanUp','Preparing for cleanup: '+asTemp[i]);
     asUninstInf[countUI] := asTemp[i];
     Inc(countUI);
     continue;
    end;

   end;

   //something else, keep for new uninst.inf
   asNew[countNew] := asTemp[i];
   Inc(countNew);

  end;

  SetArrayLength(asNew, countNew);
  SetArrayLength(asUninstInf, countUI);

  SaveStringsToUTF8File(ExpandConstant('{app}\uninst\uninst.inf'), asNew, False); //replace uninst.inf with a cleaned one

  ParseUninstInf(); //remove old associations
 end;
end;

[Dauer der Verarbeitung: 0.3 Sekunden, vorverarbeitet 2026-10-27]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104852
#Domains=417166