TRegistry: Probleme mit DeleteKey



  • Und in einem eigenen Beitrag, damit die Diskussion ggf. abgetrennt werden kann: Was soll eigentlich das if (pReg) delete pReg;? Das ist mir jetzt schon in etlichen Beiträgen verschiedener Leute aufgefallen.
    Dabei ist es a) sinnlos, da AFAIK ein fehlgeschlagenes new ohnehin eine bad_alloc-Exception wirft und b) potentiell gefährlich, wenn man im Verlauf den Programms den Pointer (versehentlich) auf NULL gesetzt hat. Denn das macht ja das delete nicht überflüssig ...



  • zuerstmal (gaaanz böse): wer "versehentlich" einen Pointer auf NULL setzt, sollte vielleicht noch mal überdenken, ob Programmieren das Richtige für ihn ist. 😃

    Ansonsten habe ich mir angewöhnt, so gut wie den gesamten Code in try / __finally und innerhalb dessen in try catch zu setzen (frei nach Murphys Gesetz...):

    bool result = true; // Rückgabewert vorbelegen (damit man nur im Fehlerfall das result auf false setzen muß)
    TIrgendwas* MeinZeiger = NULL; // definierte Ausgangssituation schaffen
    try
    {
      try
      {
         MeinZeiger = new TIrgendwas();
         // und was sonst noch mit MeinZeiger zu geschehen hat. Notfalls in noch mehr try catch geschachtelt
      }
      catch(EIrgendwasError &Err) // erwartete Fehler abfangen und behandeln
      {
         // Fehlerbehandlung und Schadensbegrenzung
         result = false;
      }
      catch (...) // unerwartete Fehler abfangen
      {
         result = false;
         // Hier kann man dann meist nicht mehr viel tun, außer Aufräumen...
      }
    }
    __finally
    {
      if (MeinZeiger) // und dann macht es Sinn, so zu prüfen...
         delete MeinZeiger;
      return result;
    }
    

    Ach ja und ansonsten ist es sehr hilfreich, VOR der Verwendung eines Zeigers grundsätzlich zu prüfen, ob dieser NULL ist. Auch bevor man den Zeiger auf NULL setzt. Je nach Situation lösche ich in einem solchen Fall das bestehende Objekt, oder gebe eine entsprechende Fehlermeldung im Logfile aus, und bitte den Benutzer sich an mich zu wenden.

    Die Verwendung von Zeigern in Arrays oder sich selbst organisierenden Objekten ist natürlich nicht ganz trivial aber es läßt sich damit immer noch äußerst schneller Code schreiben. 🤡

    So und jetzt muß ich mir wahrscheinlich von J. wieder anhören, dass das für RAD viel zu viel Aufwand ist... 😉 Aber da ich meist mit Datenbanken hantiere und es dort so viele potentielle und nicht zu kontrollierende Fehlerquellen gibt, hab' ich mir das im Laufe der Jahre so angewöhnt.



  • Joe_M. schrieb:

    // und dann macht es Sinn, so zu prüfen...

    Aber auch nur dann, in genau diesem Kontext.



  • Auch auf die gefahr hin, dass der Thread abgleitet:

    Joe_M. schrieb:

    bool result = true; // Rückgabewert vorbelegen (damit man nur im Fehlerfall das result auf false setzen muß)
    TIrgendwas* MeinZeiger = NULL; // definierte Ausgangssituation schaffen
    try
    {
      try
      {
         MeinZeiger = new TIrgendwas();
         // und was sonst noch mit MeinZeiger zu geschehen hat. Notfalls in noch mehr try catch geschachtelt
      }
      catch (Exception &E) // erwartete Fehler abfangen und behandeln
      {
         // Fehlerbehandlung und Schadensbegrenzung
         ShowMessage(E.Message);
         result = false;
      }
    }
    __finally
    {
      if (MeinZeiger) // und dann macht es Sinn, so zu prüfen...
         delete MeinZeiger;
      return result;
    }
    

    Das 2. catch erübrigt sich dann meiner Meinung nach.

    So, wieder zum Thema: Screenshot von regedit unter Key. Also entweder habe ich Fett auf der Brille, oder ich bin bescheuert ... Jedenfalls gehts mit Hand (im regedit) rauszulöschen, aber nicht mit dem obigen Code.



  • F98 schrieb:

    Das 2. catch erübrigt sich dann meiner Meinung nach.

    In diesem simplen Beispiel bestimmt. Aber dieses Beispiel sollte als 'Schablone' für Funktionrümpfe verstanden werden, in den Fehler auftreten können, auf die man als Programmierer keinen Einfluß hat. Und es macht durchaus Sinn auf bestimmte Fehler anders zu reagieren. Die Alternative, das in if's auszuwerten gefällt mir nicht. Mit mehreren catch-Blöcken finde ich es lesbarer.



  • F98 schrieb:

    ...Jedenfalls gehts mit Hand (im regedit) rauszulöschen, aber nicht mit dem obigen Code.

    Hast Du es mal ohne die das führende Backslash im String versucht ("SYSTEM\...")?



  • Joe_M. schrieb:

    Hast Du es mal ohne die das führende Backslash im String versucht ("SYSTEM\...")?

    Ja. Erzeugen klappt ja auch ohne Probleme:

    TRegistry *pReg = new TRegistry;
    bool bOk = true;
    try
    {
       pReg->RootKey = HKEY_LOCAL_MACHINE;
       if (pReg->OpenKey("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
       {
          pReg->WriteString("DisplayServer", ParamStr(0));
          pReg->CloseKey();
       }
    }
    catch (...)
    {
          bOk = false;
    }
    
    if (pReg) delete pReg; //  :)
    

    Jedoch funktioniert ebenfalls nicht, trotzdem der Schlüssel existiert:

    TRegistry *pReg = new TRegistry;
    bool bOk = true;
    try
    {
       pReg->RootKey = HKEY_LOCAL_MACHINE;
       if (pReg->OpenKey("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\DisplayServer", false)) // OpenKey ist in dem Falle == false :(
       {
          bOk = pReg->DeleteKey("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\DisplayServer");
       }
    }
    catch (...)
    {
          bOk = false;
    }
    
    if (pReg) delete pReg; //  :)
    


  • Vielleicht weil "DisplayServer" kein Key sondern eine Value ist?

    -junix

    EDIT: Zur Erinnerung: Keys = Ordner in Regedit, Values = "Datei-iconmässig" in Regedit...



  • Hallo,

    Sag mal, ist bei dir "DisplayServer" nicht ein Datenwert innerhalb des Schlüssels "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" ? Den müsstest du doch eigentlich mit DeleteValue löschen und nicht mit DeleteKey.

    Ciao

    [/EDIT] Das war wohl zu spät. Man sollte wohl neben dem Editieren nichts anderes machen 😉 [EDIT]



  • Gott bin ich doof! Da war der Hund begraben (die Hitze ...)

    Richtig muss es sein:

    TRegistry *pReg = new TRegistry;
    bool bOk = true;
    try
    {
       pReg->RootKey = HKEY_LOCAL_MACHINE;
       if (pReg->OpenKey("\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", false))
       {
          bOk = pReg->DeleteValue("DisplayServer"); X)
       }
    }
    catch (...)
    {
          bOk = false;
    }
    
    if (pReg) delete pReg;
    

    Manchmal bin ich irgendwie betriebsblind ... 😉


Anmelden zum Antworten