Gemischte Ini-Datei updaten - Ideen gesucht

  • Es geht darum, eine Ini-Datei zu aktualisieren, ohne deren Einstellungen zu verlieren.


    In Pau3 gibt es eine Main-Ini, mit der Einstellungen verwaltet werden. Wenn nun ein User ein Update über seine vorhandene Version kopiert, will er seine Einstellungen natürlich nicht verlieren. In einer reinen Ini wäre das recht einfach, indem man nur die Werte auf Vorhandensein und Gültigkeit prüfen und ergänzen würde.


    Zum einen handelt es sich hierbei aber um eine Ini mit gemischtem Inhalt, nämlich mit Kommentaren, die Infos zu Einstellungen geben. Z.B. zum Schlüssel FarbSchema könnte es einen Kommentar FarbSchema: hell, dunkel, auto geben.


    - Edit: Nach Info von AspirinJunkie sollten Kommentare keine Probleme machen.


    Zum anderen soll eine vorgesehene Reihenfolge in der Ini eingehalten werden.


    Es gibt also eine "Soll"-Ini und eine "Ist"-Ini.


    "Soll"-Ini (Script)
    "Ist"-Ini (User)
    Befindet sich als Code im Script.
    Befindet sich als Datei auf der Festplatte.
    Enthält alle Schlüssel und Kommentare in der gewünschten Reihenfolge und mit der gewünschten Formatierung (z.B. nur 1 Leerzeile vor einer weiteren Sektion, usw.).
    Enthält evtl. nicht alle Schlüssel, Kommentare sind vorhanden oder gelöscht, die Reihenfolge ist evtl. komplett durcheinander, die Formatierung ist Kraut und Rüben.
    Schlüssel enthalten die Standard-Werte.
    Schlüssel enthalten vom User eingefügte Werte, enthalten falsche oder keine Werte.


    Nun sollen die Werte der Schlüssel in der Ist-Ini aktualisiert werden, wobei vorhandene gültige Werte des Users erhalten bleiben. Neue Schlüssel und Kommentare sollen hinzugefügt, gelösche Kommentare und die gewünschte Reihenfolge wieder hergestellt werden. Ich denke, es ist klar wie's gemeint ist. :)


    Der Code wird beim Starten von PSPad geladen und sollte leicht geschwindigkeitsoptimiert sein, das heißt, es kommt zwar nicht auf Millisekunden an, aber wenn der Code flott ist, ist das gut für die Startgeschwindigkeit von PSPad.


    Meine Überlegung schwankt zwischen Arrays und Dictionarys. Auf jeden Fall könnte ich es mir so vorstellen, dass z.B. beide Inis zeilenweise (StringSplit()) in Arrays geladen und verglichen werden.

    • Das Soll-Array wird von Anfang bis Ende durchlaufen und jede einzelne Zeile mit allen Zeilen des Ist-Arrays verglichen.
    • Handelt es sich bei der Soll-Zeile um einen Kommentar, wird er übersprungen, denn die Kommentare werden am Schluss bei Schreiben an die richtige Stelle gesetzt.
    • Handelt es sich bei der Soll-Zeile um einen Schlüssel, werden alle Zeilen des Ist-Arrays durchlaufen, bis der Schlüssel gefunden ist. Ist der Schlüssel im Ist-Array NICHT vorhanden, wird die Soll-Zeile einfach übernommen. Ist der Schlüssel im Ist-Array vorhanden, wird der Wert auf Gültigkeit geprüft und entweder übernommen (wenn gültig) oder ersetzt (wenn UNgültig).
    • Evtl. als Geschwindigkeitsoptimierung die Zeilen aus dem Ist-Array löschen, die schon verarbeitet wurden. Das kann aber in die Hose gehen, denn wahrscheinlich ist das ReDim des Ist-Arrays langsamer, als wenn man nicht löscht.
    • Der Inhalt der Ist-Ini wird gelöscht und das Soll-Array in die Ist-Ini geschrieben.

    Die Main-Ini eines ausgewachsenen Programms, wie z.B. PSPad, kann leicht über 1.500 Zeilen beinhalten. Deshalb würde ich mich freuen, über Ideen und Verbesserungsvorschläge. :)

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    Einmal editiert, zuletzt von Professor Bernd ()

  • Zum einen handelt es sich hierbei aber um eine Ini mit gemischtem Inhalt, nämlich mit Kommentaren, die Infos zu Einstellungen geben. Z.B. zum Schlüssel FarbSchema könnte es einen Kommentar FarbSchema: hell, dunkel, auto geben.

    Mit Kommentaren kommt IniRead und Konsorten doch klar.
    In Ini-Dateien werden Kommentare am Zeilenanfang mit ; eingeleitet.


    Ansonsten tun Beispieldateien gut.

  • Mit Kommentaren kommt IniRead und Konsorten doch klar.

    Das wusste ich nicht, danke für die Info! - Ich gehe aber davon aus, dass IniRead und Konsorten für jede Abfrage die Ini öffnen und schließen, oder? Bei über 1.000 Einträgen wäre das suboptimal.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Hab deine Info im ersten Post eingearbeitet.


    Ansonsten tun Beispieldateien gut.

    Meinst du Ini- oder Script-Dateien? Ein Script gibts noch nicht. Wollte erst Ideen sammeln.


    "Soll"-Ini
    "Ist"-Ini"gewünschtes Resultat"-Ini
    [Paths]
    AutoIt3_Dir=C:\Program Files (x86)\AutoIt3\
    SciTE_Dir=C:\Program Files (x86)\AutoIt3\SciTE\
    PSPad_Dir=

    [General]
    P4A3_FirstStartAfterInstallIsDone=True
    KodaFirstStartIsDone=True
    ProjPanelHiding_Use=1
    ReplaceMnuItmsInAllLangFiles_ToAutoIt3=False

    [Config]
    ; ColorSchemes 2020-07-19: White_Black_Red, Gray_White_Blue, auto
    ColorScheme=auto

    [LogWin]
    ShowAfterCompile=1
    AutoCloseDelay=2
    ; Close the LogWin automatically if no errors occur ...

    AutoCloseIfNoError=1
    ; ... but not if debug messages occur.
    AutoCloseButNotIfDbgMsg=1
    [Paths]
    AutoIt3_Dir=C:\Program Files (x86)\AutoIt3\
    SciTE_Dir=C:\Program Files (x86)\AutoIt3\SciTE\
    PSPad_Dir=

    [Config]
    ColorScheme=auto

    [General]
    KodaFirstStartIsDone=False
    ProjPanelHiding_Use=
    P4A3_FirstStartAfterInstallIsDone=True

    [LogWin]
    AutoCloseDelay=4
    ; Close the LogWin automatically if no errors occur ...

    AutoCloseIfNoError=1
    AutoCloseButNotIfDbgMsg=0
    [Paths]
    AutoIt3_Dir=C:\Program Files (x86)\AutoIt3\
    SciTE_Dir=C:\Program Files (x86)\AutoIt3\SciTE\
    PSPad_Dir=

    [General]
    P4A3_FirstStartAfterInstallIsDone=True
    KodaFirstStartIsDone=False
    ProjPanelHiding_Use=1
    ReplaceMnuItmsInAllLangFiles_ToAutoIt3=False

    [Config]
    ; ColorSchemes 2020-07-19: White_Black_Red, Gray_White_Blue, auto
    ColorScheme=auto

    [LogWin]
    ShowAfterCompile=1
    AutoCloseDelay=4
    ; Close the LogWin automatically if no errors occur ...

    AutoCloseIfNoError=1
    ; ... but not if debug messages occur.
    AutoCloseButNotIfDbgMsg=0



    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    3 Mal editiert, zuletzt von Professor Bernd ()

  • Ich gehe aber davon aus, dass IniRead und Konsorten für jede Abfrage die Ini öffnen und schließen, oder? Bei über 1.000 Einträgen wäre das suboptimal.

    Jepp - wobei es bisschen darauf ankommt. Wenn du mit IniReadSection arbeitest landet eine ganze Sektion in einem Rutsch in einem Array.
    Allerdings werden von der blödsinnigerweise nur die ersten 32767 Zeichen ausgewertet (Hängt mit der zugrunde liegenden Win-API-Funktion zusammen).
    Wenn die Sektionen in deiner Ini entsprechend klein sind könntest du das also verwenden.


    Meinst du Ini- oder Script-Dateien?

    Ich meine ini - und zwar alle drei: "Ist"-Ini, "Soll"-Ini und "gewünschtes Resultat"-Ini

  • Ich meine ini - und zwar alle drei: "Ist"-Ini, "Soll"-Ini und "gewünschtes Resultat"-Ini

    Ein Beispiel für eine "Soll"-Ini habe ich oben gepostet, das auch die "gewünschte Resultat"-Ini. Eine "Ist"-Ini kann ich auch posten, ist einfach eine "Soll"-Ini mit Durcheinander und fehlenden/gelöschten Schlüsseln.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Zum anderen soll eine vorgesehene Reihenfolge in der Ini eingehalten werden.

    Was ist der Nutzen davon?


    Du solltest evtl. das Konzept überdenken. Ich finde die von SciTE gewählte Variante mit Global und User Properties sehr gut.

    Deine *Soll.ini* entspräche den Global Properties und wird zuerst geladen. Dann werden die Werte aus der *Ist.ini*, den User Properties, gelesen, welche Werte aus der Global überschreiben.

    Vorteil:

    Du brauchst die User Datei niemals bearbeiten, das macht ausschließlich der Anwender.

    Macht dieser keine individuellen Einträge, sind die globalen Werte gültig.

  • kann leicht über 1.500 Zeilen beinhalten

    Hab ich jetzt erst gelesen:

    Verabschiede dich von der Ini, da geht ins Auge (Limit).

    Nimm XML oder JSON oder auch eine reine zeilenorientierte Textdatei (config). Dafür findest du hier im Forum Muster.


    Edit - Da fällt mir ein, XML ist wohl auch limitiert, das war das Problem, dass NPP für AutoIt nicht nutzbar machte.

  • Zum anderen soll eine vorgesehene Reihenfolge in der Ini eingehalten werden.

    Was ist der Nutzen davon?

    Ordnung. Schlüssel können aphabetisch sortiert werden und somit können zusammengehörende Schlüssel beisammen stehen und in einer sinnvollen Reihenfolge, wie z.B. im Beispiel oben


    ; Close the LogWin automatically if no errors occur ...

    AutoCloseIfNoError=1

    ; ... but not if debug messages occur.

    AutoCloseButNotIfDbgMsg=1


    BugFix Du postest schneller, als ich antworten kann. Ich schicke hier schonmal eine Teilantwort.


    Verabschiede dich von der Ini, da geht ins Auge (Limit).

    Welches Limit?

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Du solltest evtl. das Konzept überdenken.

    Deshalb frage ich ja hier. 8o

    Ich finde die von SciTE gewählte Variante mit Global und User Properties sehr gut.

    Das hatte ich vor einiger Zeit auch schonmal überlegt. Aber bisher konnte ich das mit meinem Konzept nicht unter einen Hut bringen. Zum Beispiel soll Pau3 einen Settings-Dialog bekommen. Wo sollte der dann hinspeichern? Wahrscheinlich in die User Properties, dann bin ich soweit wie jetzt, oder? Das werde ich nochmal überdenken, ansich ist die Idee nicht schlech, Global... und User... zu trennen.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Die Soll-Ini ist - wie du sagst - dein gewünschtes Resultat und diese hast du ja bereits in deinem Skript.
    Also muss du die Ist-Ini nur mit dieser überschreiben.

    Nicht ganz. Wie geschrieben sollen die Werte der Ist-Ini erhalten bleiben.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Du brauchst die User Datei niemals bearbeiten, das macht ausschließlich der Anwender.

    Hmm, ... sollte es mal irgendwann einen Settings-Dialog geben, wäre das gar nicht so schlecht. Im Settings-Dialog kann man die Infos unterbringen, die ich derzeit als Kommentare in die Ini schreibe.


    32k File Size Limit.

    Witzig, ich habe gerade nachgesehen, die PSPad.ini hat 32KB. Woher kommt das Limit? Ist das noch akutell?

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Also ist es nicht das gewünschte Resultat.
    Bitte also noch eine dazugehörige Beispieldatei.

    Ach bitte, wozu soll das den gut sein? Ist der Sinn nicht klar?


    Aber dir zuliebe poste ich oben noch eine "gewünschtes Resultat"-Ini.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

  • Aus den 16 Bit Windows Zeiten. Mit Einführung der Registry wurden die Ini Dateien durch MS im System selbst nicht mehr verwendet.

    Also kann das Limit in 64 Bit Windows Zeiten durchaus weggefallen sein? Aber selbst wenn das 32KB File Size Limit noch bestehen sollte, wäre das kein Problem. Ich denke nicht, dass Pau3 soviele Einträge erhält, dass das Limit überschritten wird. Und falls doch, gibts eine zweite Ini-Datei. 8o

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.