132749
Goto Top

Registry per Batch abfragen und INI Einträge hinzufügen bzw. ändern

Hallo,
ich benötige Eure Hilfe da mir die Kenntnisse für das Schreiben einer so anspruchsvollen Aufgabe fehlen!

Die Batch soll zuerst den Registryeintrag abfragen und dann an die INI übergeben werden!
Als Beispiel:

HKEY_LOCAL_MACHINE\SOFTWARE\myProgramm "Country" "DEU"


Der Pfad zur INI die geändert werden soll wäre dann:
C:\myProgramm\DATA\DATA-1.INI
C:\myProgramm\DATA\DATA-2.INI

Anschliessend sollen dann die länderspezifischen Einstellungen hinzugefügt/geändert werden!

Hinweis:
Die INI`S beinhalten weitere Einträge die erhalten bleiben müssen!!!!!!!



Auszug aus einer Standard INI die entsprechend geändert werden soll:

[VARIABLE]
SERVER=C:
DRV1=C:
DRVPROG=C:

COUNTRY_PRS=
COUNTRY_UPD=

[COUNTRY]
COUNTRY=

[KONFIGURATION]
#-------- Sprache --------------
language=
langid=
#--------Update---------------
upd_nation=
p_update=1
#--------Sonstiges---------------
waehrung=
komma=1
awst=1
mwst_name=
mwst_saetze=A
mwst_values=


Anschliessend sollen dann die länderspezifischen Einstellungen hinzugefügt/geändert werden!

Wenn HKEY_LOCAL_MACHINE\SOFTWARE\myProgramm "Country" "DEU" dann:

[VARIABLE]

COUNTRY_PRS=DEU
COUNTRY_UPD=d

[COUNTRY]
COUNTRY=DEU

[KONFIGURATION]
#-------- Sprache --------------
language=d
langid=1
#--------Update---------------
upd_nation=d
p_update=1
#--------Sonstiges---------------
waehrung=EUR
komma=1
awst=1
mwst_name=Mwst
mwst_saetze=A
mwst_values=19.0


Wenn HKEY_LOCAL_MACHINE\SOFTWARE\myProgramm "Country" "AUS" dann:

[VARIABLE]

COUNTRY_PRS=AUS
COUNTRY_UPD=0

[COUNTRY]
COUNTRY=AUS


[KONFIGURATION]
#-------- Sprache --------------
language=u
langid=3
#--------Update---------------
upd_nation=0
p_update=2
#--------Sonstiges---------------
waehrung=AUD
komma=1
awst=1
mwst_name=VAT
mwst_saetze=A
mwst_values=10.0


fortlaufend für weitere Länder ............!


Für Eure Hilfe bedanke ich mich im Voraus

Gruss
kampen

Content-Key: 332640

Url: https://administrator.de/contentid/332640

Ausgedruckt am: 19.03.2024 um 03:03 Uhr

Mitglied: rubberman
rubberman 19.03.2017 aktualisiert um 13:48:33 Uhr
Goto Top
Hallo kampen.

Mal abgesehen davon, dass Batch wohl eine der am schlechtesten geeigneten Sprachen ist, um INI Dateien zu bearbeiten ...

Der Pfad zur INI die geändert werden soll wäre dann:
C:\myProgramm\DATA\DATA-1.INI
C:\myProgramm\DATA\DATA-2.INI
Das sind bereits 2 Dateien. Existieren die bereits? Welche davon enthält welche Daten und woher weiß das das Batchscript?

Wenn HKEY_LOCAL_MACHINE\SOFTWARE\myProgramm "Country" "DEU" dann:
OK, das DEU kann aus der Registry gelesen werden, verstanden. Aber woher kommen die anderen Werte? Auch aus der Registry? Wenn ja, wie heißen die Werte dort und wo sind sie zu finden?

Grüße
rubberman
Mitglied: 132749
132749 19.03.2017 um 14:37:59 Uhr
Goto Top
Hallo rubberman,
die beiden Dateien bestehen bereits und sollen um die Einträge der Batch ergänzt werden!
Ich möchte die länderspezifischen Einstellungen in der Batch einpflegen und nach dem ausführen an die INI`S übergeben!

Teil 1 = ist ein Auszug der INI die geändert werden soll
(Inhalt der INI`S die geändert werden sollen sind identisch)

Teil 2 = ist ein Beispiel für 2 Länder und soll entsprechend erweitert werden
Wenn Registry "DEU" dann ....
Wenn Registry "AUS" dann ....
Wenn Registry "...." dann ....

Hmm, wie oder mit was kann man sonst Einträge an eine INI übergeben?
Mitglied: rubberman
rubberman 19.03.2017 aktualisiert um 17:19:03 Uhr
Goto Top
Ich werde aus deinen Erklärungen noch nicht schlauer.

Fangen wir mal damit an:
Teil 2 = ist ein Beispiel für 2 Länder und soll entsprechend erweitert werden
Sektionen (das was in eckigen Klammern steht) können weder verschachtelt werden, noch dürfen sie mehrmals in einer INI Datei auftauchen. Das was du dort vorhast, ergibt kein gültiges INI Format.

Ich möchte die länderspezifischen Einstellungen in der Batch einpflegen und nach dem ausführen an die INI`S übergeben!
OK, aber woher kommen diese? Hart im Batchcode hinterlegt?

wie oder mit was kann man sonst Einträge an eine INI übergeben?
Mir sind dort nur Windows API Funktionen bekannt, wie WritePrivateProfileString. Kannst du bspw. in ein C Programm einbinden, aber nicht in ein Batchscript.
Wie auch immer. Nehmen wir an du hast eine INI Datei "test.ini", in der die zu verändernden Schlüssel bereits enthalten sind, dann könnte eine Subroutine etwa so aussehen:
@echo off &setlocal
set "inifile=test.ini"  
set "section=VARIABLE"  
set "key=COUNTRY_PRS"  
set "value=DEU"  

call :write_ini "inifile" "section" "key" "value"  
pause
exit /b


:write_ini
setlocal EnableDelayedExpansion
set "insec="  
>"!%~1!.tmp~" <"!%~1!" (  
  for /f %%i in ('type "!%~1!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "ln=" &set /p "ln="  
    if not defined ln (
      echo(
    ) else if "!ln:~0,1!"=="[" (  
      if defined insec (
        set "insec="  
      ) else if /i "!ln!"=="[!%~2!]" (  
        set "insec=1"  
      )
      echo(!ln!
    ) else if not defined insec (
      echo(!ln!
    ) else (
      for /f "delims==" %%k in ("!ln!") do (  
        if /i "%%k"=="!%~3!" (  
          echo(%%k=!%~4!
        ) else (
          echo(!ln!
        )
      )
    )
  )
)
>nul move /y "!%~1!.tmp~" "!%~1!"  
endlocal
exit /b
Mitglied: 132692
Lösung 132692 20.03.2017 aktualisiert um 17:57:11 Uhr
Goto Top
Und hier das ganze in Powershell:
$inipath = 'C:\myProgramm\DATA\DATA-1.INI'   
$inicontent = gc $inipath
$langset = @{
    'DEU' = @{COUNTRY_PRS = 'DEU';COUNTRY_UPD = 'd';COUNTRY = 'DEU';language = 'd';langid = '1';upd_nation = 'd';waehrung = 'EUR';mwst_name = 'MwSt';mwst_values = '19.0'}  
    'AUS' = @{COUNTRY_PRS = 'AUS';COUNTRY_UPD = '0';COUNTRY = 'AUS';language = 'u';langid = '3';upd_nation = '0';waehrung = 'AUD';mwst_name = 'VAT';mwst_values = '10.0'}  
}
$regvalue = Get-ItemProperty "HKLM:\SOFTWARE\myProgramm" -Name 'Country' | Select -Expand 'Country'  
($langset.$regvalue).GetEnumerator() | %{$inicontent = $inicontent -replace ('^' + [regex]::Escape($_.Key) + '\s*=\s*.*'),($_.Key + '=' + $_.Value)}  
$inicontent | set-content $inipath
Gruß p.
Mitglied: rubberman
rubberman 20.03.2017 um 18:20:21 Uhr
Goto Top
Hallo pattern.

Soll heißen, auch PS (.NET) bietet keine vernünftige Möglichkeit INI Strukturen zu editieren? Hmm, erstaunlich...

Grüße
rubberman
Mitglied: 132692
132692 20.03.2017 aktualisiert um 18:35:07 Uhr
Goto Top
Zitat von @rubberman:
Hallo pattern.
Hi @rubberman
Soll heißen, auch PS (.NET) bietet keine vernünftige Möglichkeit INI Strukturen zu editieren? Hmm, erstaunlich...
Von Haus aus nicht direkt, mit Funktionen aber natürlich leicht nachrüstbar mit dem Einlesen in eine geschachtelte Hashtable:
https://gallery.technet.microsoft.com/scriptcenter/ea40c1ef-c856-434b-b8 ...
https://www.powershellgallery.com/packages/PsIni/1.2.0/Content/Functions ...
Ich persönlich mach das aber eh nur noch über XML-Strukturen da lässt sich viel mehr mit abbilden. INIs sind ja aus dem letzten Jahrhundert face-wink
Mitglied: rubberman
rubberman 20.03.2017 aktualisiert um 18:39:02 Uhr
Goto Top
Interessant face-smile Hatte mich nur gewundert, dass du ohne Rücksicht auf Sektionen mit Regex ran gegangen bist. Schlüssel mit gleichem Namen in unterschiedlichen Sektionen wären ja immerhin völlig valide.

Naja egal. Wenn's nach MS ginge, würden INI Dateien seit Einführung der Registry der Vergangenheit angehören. Von daher war es nur konsequent die Unterstützung in .NET gar nicht erst zu implementieren ...

Persönlich nutze ich auch XML. Ziemlich jede Sprache unterstützt das mittlerweile (wenn's nicht gerade Batch ist).
Mitglied: 132692
132692 20.03.2017 aktualisiert um 18:41:44 Uhr
Goto Top
Zitat von @rubberman:
Interessant face-smile Hatte mich nur gewundert, dass du ohne Rücksicht auf Sektionen mit Regex ran gegangen bist. Schlüssel mit gleichem Namen in unterschiedlichen Sektionen wären ja immerhin völlig valide.
Ja da muss ich gestehen bin ich hier der Einfachheit nur von eindeutigen Bezeichnern ausgegangen, wollte den TO nicht mit den etwas längeren Funktionen überfordern. Aber das lässt sich ja dann bei Bedarf mit Einfügen der Funktionen nachholen.
Naja egal. Wenn's nach MS ginge, würden INI Dateien seit Einführung der Registry der Vergangenheit angehören. Von daher war es nur konsequent die Unterstützung in .NET gar nicht erst zu implementieren ...
Absolut. XML ist in dieser Hinsicht ja sowieso die eierlegende Wollmilchsau und Industriestandard.
Mitglied: 132749
132749 20.03.2017 um 21:15:22 Uhr
Goto Top
@ pattern,
vielen Dank für deine Unterstützung aber leider kenne ich mich mit Powershell überhaupt nicht aus obwohl dein Powershellbefehl einfacher aussieht als bei einer Batch!

  • Wie funktioniert Powershell bzw. welche Voraussetungen müssen erfüllt werden!?
  • Unter welchen Betriebssystem läuft bzw. kann Powershell ausgeführt werden?

  • In welchen Format kann ich den Befehl speichern und ausführen? BAT?
  • Kann ich den Powershellbefehl auch in eine EXE umwandeln?

myProgramm läuft ab Windows XP (32/64-Bit) und somit sollte sichergestellt sein das Powershell auch auf diesem Betriebssystem ausgeführt werden kann!

Gruß
kampen
Mitglied: rubberman
rubberman 20.03.2017 aktualisiert um 21:42:15 Uhr
Goto Top
Hallo kampen.

myProgramm läuft ab Windows XP (32/64-Bit) und somit sollte sichergestellt sein das Powershell auch auf diesem Betriebssystem ausgeführt werden kann!
Hehe, du weißt schon dass die Unterstützung von Zombies, wie XP, in einem Administratorforum vielleicht nicht besonders gut ankommt face-wink

Auch wenn ich oben kein Feedback bekommen habe, spielen wir noch 'ne Runde Batch ...
@echo off &setlocal
set DEU="VARIABLE;COUNTRY_PRS;DEU" "VARIABLE;COUNTRY_UPD;d" "COUNTRY;COUNTRY;DEU" "KONFIGURATION;language;d" "KONFIGURATION;langid;1" "KONFIGURATION;upd_nation;d" "KONFIGURATION;p_update;1" "KONFIGURATION;waehrung;EUR" "KONFIGURATION;mwst_name;Mwst" "KONFIGURATION;mwst_values;19.0"  
set AUS="VARIABLE;COUNTRY_PRS;AUS" "VARIABLE;COUNTRY_UPD;0" "COUNTRY;COUNTRY;AUS" "KONFIGURATION;language;u" "KONFIGURATION;langid;3" "KONFIGURATION;upd_nation;u" "KONFIGURATION;p_update;2" "KONFIGURATION;waehrung;AUD" "KONFIGURATION;mwst_name;VAT"  "KONFIGURATION;mwst_values;10.0"  

set "inifile1=DATA-1.INI"  
set "inifile2=DATA-2.INI"  

set "alpha3=nicht gefunden" &set "settings="  
for /f "tokens=2*" %%i in ('reg query "HKLM\Software\myProgramm" /v "Country"') do (set "alpha3=%%~j" &call set "settings=%%%%~j%%")  
if not defined settings (
  echo Keine Einstellungen fuer "%alpha3%" definiert.  
  pause
  exit /b
)

for %%i in (%settings%) do for /f "tokens=1,2* delims=;" %%j in (%%i) do (  
  set "section=%%j"  
  set "key=%%k"  
  set "value=%%l"  
  call :write_ini "inifile1" "section" "key" "value"  
)

REM if not exist "%inifile2%" >"%inifile2%" type nul  
REM findstr /ic:"COUNTRY=%alpha3%" "%inifile2%" >nul || copy /b "%inifile2%" /b + "%inifile1%" /b >nul  

exit /b


:write_ini
setlocal EnableDelayedExpansion
set "insec="  
>"!%~1!.tmp~" <"!%~1!" (  
  for /f %%i in ('type "!%~1!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "ln=" &set /p "ln="  
    if not defined ln (
      echo(
    ) else if "!ln:~0,1!"=="[" (  
      if defined insec (
        set "insec="  
      ) else if /i "!ln!"=="[!%~2!]" (  
        set "insec=1"  
      )
      echo(!ln!
    ) else if not defined insec (
      echo(!ln!
    ) else (
      for /f "delims==" %%k in ("!ln!") do (  
        if /i "%%k"=="!%~3!" (  
          echo(%%k=!%~4!
        ) else (
          echo(!ln!
        )
      )
    )
  )
)
>nul move "!%~1!.tmp~" "!%~1!"  
endlocal
exit /b

Die beiden auskommentierten Zeilen 23 und 24 könnten das tun, was du als Punkt 2 beschrieben hast (zumindest wie ich es verstanden habe). Aber nochmal - das ist dann kein valides INI Format.

Grüße
rubberman
Mitglied: 132749
132749 21.03.2017 um 19:41:54 Uhr
Goto Top
@ rubberman,
erst einmal möchte ich mich für meine Unhöflichkeit entschuldigen!

Vielen Dank für deine Batchanpassung die noch nicht ganz funktioniert!
Zeile 4 & 5 habe ich angepasst aber leider wird nur die DATA-1 vollständig ausgefüllt!

  • set "inifile1=DATA-1.INI" >>> set "inifile1=C:\myProgramm\DATA\DATA-1.INI" >>> TOP
  • set "inifile2=DATA-2.INI" >>> set "inifile1=C:\myProgramm\DATA\DATA-2.INI"

Des Weiteren habe ich soeben erfahren, dass ich noch 2 weitere INI`S aufgrund eines Updates anpassen muss!
Ich gehe mal davon aus, dass ich die Anpassung in Zeile 6 & 7 einfach zwischenschieben kann!?

  • set "inifile3=DATA-3.INI" >>> set "inifile1=C:\myProgramm\DATA\DATA-3.INI"
  • set "inifile4=DATA-4.INI" >>> set "inifile1=C:\myProgramm\DATA\DATA-4.INI"

Kann ich ohne Probleme weitere länderspezifische Einstellungen hinter der Zeile 3 hinzufügen?

Gruß
kampen
Mitglied: rubberman
rubberman 21.03.2017 um 19:55:01 Uhr
Goto Top
Hallo kampen.

aber leider wird nur die DATA-1 vollständig ausgefüllt!
Natürlich. Siehe:
Die beiden auskommentierten Zeilen 23 und 24
Ergo, entferne das REM am Anfang der Zeilen und sie werden ausgeführt.

Ich gehe mal davon aus, dass ich die Anpassung in Zeile 6 & 7 einfach zwischenschieben kann!?
Kannst du. Heißt aber nicht dass sie auch verarbeitet werden. Zeile 20 und ggf. 23 und 24 müssen ebenso dupliziert und angepasst werden. Hast du den Code eigentlich gelesen oder einfach nur stumpf kopiert?

Kann ich ohne Probleme weitere länderspezifische Einstellungen hinter der Zeile 3 hinzufügen?
Natürlich.

Grüße
rubberman
Mitglied: 132749
132749 21.03.2017 um 21:24:53 Uhr
Goto Top
@ rubberman,
wenn ich die Befehle so schreiben könnte wie Du dann würde ich kaum hier meine Anfrage stellen!
Meine Kenntnisse mit Batchbefehlen sind halt die ganz einfachen! face-sad

REM hatte ich zuvor schon entfernt aber dann wird die DATA-2.ini nicht dort abgelegt wo sie hingehört
(myProgramm\DATA) und zum anderen falsch gefüllt!

Dein Script mit der Änderung des Pfades (C:\myProgramm\DATA\DATA-1.ini) ist genau das was ich brauche!
Die Option DEU / AUS als länderspezifische Kennung funktioniert auch!

Wenn jetzt noch die DATA-2, DATA-3 & DATA-4.ini genauso funktionieren würden dann wäre ich glücklich vorausgesetzt die
länderspezifischen Angaben (Zeile 2 & 3) können problemlos erweitert werden!
Mitglied: rubberman
rubberman 21.03.2017 aktualisiert um 22:20:56 Uhr
Goto Top
REM hatte ich zuvor schon entfernt aber dann wird die DATA-2.ini nicht dort abgelegt wo sie hingehört
Wo wird sie denn bei dir abgelegt? Wenn ich den Pfad ändere, landet sie auch dort.
Zur Not wechsle mit pushd in das Verzeichnis und mit popd wieder zurück.

und zum anderen falsch gefüllt!
Was wäre denn richtig?
Die Datei 2 kann nicht wie Datei 1 bearbeitet werden, da es (wie mehrfach erwähnt) kein gültiges INI Format ergibt. Das einzige was möglich ist, ist zu prüfen ob der länderspezifische Code schon darin existiert und falls nicht, anhängen.

Wenn jetzt noch die DATA-2, DATA-3 & DATA-4.ini genauso funktionieren würden dann wäre ich glücklich vorausgesetzt die
länderspezifischen Angaben (Zeile 2 & 3) können problemlos erweitert werden!
Hatte ich oben bereits geschrieben.
Mitglied: 132749
132749 21.03.2017 um 22:55:48 Uhr
Goto Top
DATA-2 wird auf C:\ abgelegt
Richtig wäre es wie DATA-1, diese funktioniert genauso wie ich sie brauche! Wenn DEU dann, Wenn AUS dann!

Ich habe mir ein Notebook von meinem Nachbarn ausgeliehen der Windows 7 als Betriebssystem hat um das Powershellscript zu testen! Das Ergebnis ist PERFEKT wenn ich die Zeile 1-9 ein zweites mal einfüge und den Pfad zur DATA-2.ini ändere!

Besteht denn die Möglichkeit dein Batchbefehl um die gleiche Zeilenzahl zu erweitern und den Pfad zu DATA-2 anzupassen?

DATA-1 + DATA-2 + DATA-3 + DATA-4 benötigen alle die gleichen Vorgaben zu den länderspezifischen Angaben!
(DEU / AUS / .... / ....)
Mitglied: rubberman
Lösung rubberman 21.03.2017 aktualisiert um 23:03:51 Uhr
Goto Top
@echo off &setlocal
set DEU="VARIABLE;COUNTRY_PRS;DEU" "VARIABLE;COUNTRY_UPD;d" "COUNTRY;COUNTRY;DEU" "KONFIGURATION;language;d" "KONFIGURATION;langid;1" "KONFIGURATION;upd_nation;d" "KONFIGURATION;p_update;1" "KONFIGURATION;waehrung;EUR" "KONFIGURATION;mwst_name;Mwst" "KONFIGURATION;mwst_values;19.0"  
set AUS="VARIABLE;COUNTRY_PRS;AUS" "VARIABLE;COUNTRY_UPD;0" "COUNTRY;COUNTRY;AUS" "KONFIGURATION;language;u" "KONFIGURATION;langid;3" "KONFIGURATION;upd_nation;u" "KONFIGURATION;p_update;2" "KONFIGURATION;waehrung;AUD" "KONFIGURATION;mwst_name;VAT"  "KONFIGURATION;mwst_values;10.0"  

set "inifile1=C:\myProgramm\DATA-1.INI"  
set "inifile2=C:\myProgramm\DATA-2.INI"  
set "inifile3=C:\myProgramm\DATA-3.INI"  
set "inifile4=C:\myProgramm\DATA-4.INI"  

set "alpha3=nicht gefunden" &set "settings="  
for /f "tokens=2*" %%i in ('reg query "HKLM\Software\myProgramm" /v "Country"') do (set "alpha3=%%~j" &call set "settings=%%%%~j%%")  
if not defined settings (
  echo Keine Einstellungen fuer "%alpha3%" definiert.  
  pause
  exit /b
)

for %%i in (%settings%) do for /f "tokens=1,2* delims=;" %%j in (%%i) do (  
  set "section=%%j"  
  set "key=%%k"  
  set "value=%%l"  
  call :write_ini "inifile1" "section" "key" "value"  
  call :write_ini "inifile3" "section" "key" "value"  
)

if not exist "%inifile2%" >"%inifile2%" type nul  
for %%i in ("%inifile2%") do pushd "%%~dpi"  
findstr /ic:"COUNTRY=%alpha3%" "%inifile2%" >nul || copy /b "%inifile2%" /b + "%inifile1%" /b >nul  
popd

if not exist "%inifile4%" >"%inifile4%" type nul  
for %%i in ("%inifile4%") do pushd "%%~dpi"  
findstr /ic:"COUNTRY=%alpha3%" "%inifile4%" >nul || copy /b "%inifile4%" /b + "%inifile3%" /b >nul  
popd

pause
exit /b


:write_ini
setlocal EnableDelayedExpansion
set "insec="  
>"!%~1!.tmp~" <"!%~1!" (  
  for /f %%i in ('type "!%~1!"^|find /c /v ""') do for /l %%j in (1 1 %%i) do (  
    set "ln=" &set /p "ln="  
    if not defined ln (
      echo(
    ) else if "!ln:~0,1!"=="[" (  
      if defined insec (
        set "insec="  
      ) else if /i "!ln!"=="[!%~2!]" (  
        set "insec=1"  
      )
      echo(!ln!
    ) else if not defined insec (
      echo(!ln!
    ) else (
      for /f "delims==" %%k in ("!ln!") do (  
        if /i "%%k"=="!%~3!" (  
          echo(%%k=!%~4!
        ) else (
          echo(!ln!
        )
      )
    )
  )
)
>nul move "!%~1!.tmp~" "!%~1!"  
endlocal
exit /b
Mehr kann ich nicht tun.
Mitglied: 132749
132749 22.03.2017 um 07:10:52 Uhr
Goto Top
Guten Morgen rubberman,

Vielen Dank für das letzte Script was leider nicht 100% so ausgeführt wird wie gewünscht aber mit einer kleinen Abwandlung funktioniert es!

Nachfolgende Änderung habe ich vorgenommen und würde mich freuen wenn Du da noch einmal drüberschauen könntest!

Hinzugefügt habe ich:

      • call :write_ini "inifile2" "section" "key" "value"
      • call :write_ini "inifile4" "section" "key" "value"

Entfernt habe ich:

  • die Zeilen 26 - 34
Mitglied: rubberman
rubberman 22.03.2017 um 19:08:20 Uhr
Goto Top
Hallo kampen.

Kann durchaus sein, dass ich dich nicht richtig verstanden habe. Wenn's so funktioniert, bitte. Sobald du in den Dateien 2 und 4 mehrere Sektionen mit gleichem Name hast, wird es fehlschlagen. Das ist allerdings das, was ich aus deiner Beschreibung entnommen hatte.