23972
Goto Top

Dateieditierung per Batchdatei (machine.config)

Hallo, ich hab erst nach anderen Möglichkeiten gesucht, aber Batch-Dateien erscheinen mir jetzt als sehr leistungsfähig und vielleicht weiss jemand, wie man folgendes Problem löst:


Unter C:\WINDOWS\Microsoft.NET\Framework\
gibt es einen der Version des verwendeten Framework entsprechden Unterordner, z.B.
v1.1.4322\CONFIG
und dort liegt die Datei: "machine.config"

In der Datei gibt es das Tag: processModel und dort muss das Attribut userName='machine' mit userName='SYSTEM' ausgetauscht werden.
Kann man das per Batch-Datei machen? Wie würde sowas aussehen?
Erstmal muss er ja die richtige machine.config finden (kann auch in v1.0.3705\CONFIG liegen...)

Danke schonmal

H.

Content-Key: 24387

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

Printed on: April 19, 2024 at 06:04 o'clock

Member: Biber
Biber Jan 24, 2006 at 20:46:50 (UTC)
Goto Top
Moin hanswd,

lässt sich machen, aber es gibt drei (mögliche) Schwierigkeiten dabei:

a) Es wäre zu prüfen, ob M$ so dämlich war, einem x-beliebigen dahergelaufenen Batch die Änderung der machine.config zu erlauben. Immerhin stehen da zum Beispiel im Abschnitt &ltprocessModel&gt auch solche Sachen wie Username und Passwort drin. Andererseits... wie ich M$ einschätze, ist das kein Problem...

b) Wie Du auch angesprochen hast - irgendwie muss vorher der gültige (Versions-) Pfad ermittelt werden.
Ich weiß nicht, ob/wo der in der Registry steht oder sonst aus dem aufrufenden Kontext ermittelt werden kann - das müsstest Du klären. Oder es muss fest in den Batch verdrahtet ("hart codiert") werden, was ich auch ungern mache.

c) Da die machine.config ja eine XML-Datei ist, sind im Batch ein paar Maskierungen (für die Größer/Kleiner-Zeichen, die ja auch im Batch Steuerzeichen sind) nötig. Da so etwas aber öfters mal hier nachgefragt wird, fände ich das einen schönen Anlass für einen Beispiel-Batch und helfe gerne mit.

Kannst Du zu Punkt a) und b) etwas recherchieren bitte?

Grüße Biber
Mitglied: 23972
23972 Jan 25, 2006 at 00:02:18 (UTC)
Goto Top
Hi Biber, klingt gut, hier schon mal was zu Deinen Punkten:

Zu a)

Die Datei ist jedenfalls nicht extra geschützt wie es scheint, ich denke mal,das wird kein Problem sein sicherheitstechnisch...Hab ansonsten aber keine Quellen gefunden, die da schonmal per Batchdatei geändert haben

Zu b)

Es gibt sogar mehrere Stellen in der Registry in denen der Pfad zur machine.config steht:
1.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\4AA80E9DBDA37C74BBB132651E9BBF8A]
"DDE7F2BCF1D91C3409CFF425AE1E271A"="C?\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config"  
oder
2.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls]
...
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config"=dword:00000001  
...

Kompletter 2.ter Key: [Edit Biber: wieder ein bisschen gekürzt.... so genau brauchen wir es doch nicht.. [/Edit]

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls]
"C:\\Programme\\Gemeinsame Dateien\\Microsoft Shared\\Triedit\\dhtmled.ocx"=dword:00002710
[...........]
"C:\\WINDOWS\\system32\\rired32e.dll"=dword:00000001
"C:\\WINDOWS\\system32\\SUPPORT.INI"=dword:00000001
......
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.0.3705\\installutil.exe.config"=dword:00000002
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config"=dword:00000001
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\mscorcfg.msc"=dword:00000001
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\mscoree.tlb"=dword:00001000
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\IEExecRemote.dll"=dword:00000001
Member: Biber
Biber Jan 25, 2006 at 07:14:16 (UTC)
Goto Top
Moin hanswd,

danke schon mal für die Recherche.
Der zweite RegKey sieht vertrauenserweckender aus - der lässt sich ja auch auf verschiedenen Rechnern wiederfinden.
Allerdings muss der Batch (bzw. der Batch-aufrufende-User) die Rechte zum Lesen des HKLM-Zweiges haben. Sollten wir schon mal im Hinterkopf behalten als Restriktion.
Dazu bitte noch mal den SubKey unter [..SharedDLLs] posten (bzw. Editieren in Deiner Antwort.)

Wenn Du dann noch schreibst, was Du (ggf. abhängig von...bla..) ändern willst, dann können wir heute abend loslegen.
Vorher hab ich wenig Luft.

Grüße Biber
Mitglied: 23972
23972 Jan 25, 2006 at 11:41:59 (UTC)
Goto Top
So, hab mal den kompletten Key in die Antwort davor gepackt, und in der Frage steht jetzt auch drin, was er machen soll:
=> username='machine' in username='system'

Das wurde in dem Beitrag wohl ausgeblendet, da vor processModel ein Kleinerzeichen stand!!

Gruß
H.
Member: Biber
Biber Jan 29, 2006 at 12:11:59 (UTC)
Goto Top
So, hanswd,

heute nachmittag könnten wir ein wenig weiterbasteln.
Den ersten Teil, die Ermittlung des Pfades zur "aktiven" Datei machine.config kann ich Dir schon posten.
Zum Bearbeiten dieser XML-Datei hätte ich gern noch ein bisschen Input. Ich schick Dir mal eine PN mit meiner Mailadresse und bitte um eine realistische machine.config mit den Angaben, was geändert werden soll.

::--snipp ErmittleMachineConfigPath.bat
@echo off & setlocal
Set "OutOfTheReg=%temp%\MySharedDLLs.reg"  
Set "NeededRegKey=HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\SharedDlls"  
regedit /e %OutOfTheReg% %NeededRegKey%
goto skipProsa
~~~~~~~~~~~
:: In der %OutOfTheReg%-Datei steht jetzt die oben abgedruckte meterlange Liste
:: Von der brauchen wir eine Zeile: die Zeile mit "machine.config" 
:: Die holen wir mit dem FIND-Befehl
:: Ein CMD-Prompt-Befehl "find /i "machine.config" %OutOfTheReg%" 
:: würde als Output sinngemäß liefern:

---------- Z:\TEMP\MYSHAREDDLLS.REG
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config"=dword:00000001</i>  
:: Die ersten beiden Outputzeilen entsorgen wir mit "skip=2" in der nächsten Anweisung, 
:: ebenfalls alles nach dem "="-Zeichen inclusive mit "delims==" 
:skipProsa
for /F "skip=2 delims==" %%i in ('find /i "machine.config" %OutofTheReg%') do Set "MCFile=%%i"  
:: In MCFile steht jetzt folgendes:
:: "C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config" 
::da ersetzen wir die doppelten Backslashes durch einfache.
Set MCFile=%MCFile:\\=\%
::Ergebnis MCFile="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config" 
::--snapp ErmittleMachineConfigPath.bat
Jetzt könnten wir anfangen....

Gruß Biber
Member: Biber
Biber Jan 29, 2006 at 16:01:37 (UTC)
Goto Top
Jo, dann lass uns mal loslegen....
Ich hätte folgende Alternativstrategien für diesen Zweck:

a) Die "saubere"
Wir parsen die machine.config-XML-Datei, das heißt hangeln uns von Node zu Node, um sicherzustellen, dass auch der richtige XML-Tag in dem richtigen Node geändert wird.
Was dagegen spricht, ist meine Abneigung gegen das 12000ste Neu-Erfinden von solchen Rädern.. XML-Parser gibt es schon reichlich - zwar eher als ASP.net oder Java-Code, aber ..was soll's.
Einen kleinen SAX-Parser oder ähnliches hat bestimmt ziemlich jeder Java-Noob schon mal zusammengeschrotet. Das reizt mich also wenig.

b) Denn wenn es hier mit der konkreten machine.config einfacher geht, sehe ich es pragmatisch.
Ansatz:
- Prüfen, ob die machine.config GENAU eine Zeile mit [Username="machine"] enthält.
- wenn ja (ist in unserem Fall gegeben)
- Sicherungskopie anlegen
b1) mit einem Freeware-Konsolen-Utility "StringReplace.exe" den Text [Username="machine"] durch den Text [Username="system"]
ersetzen. Solche Utilities gibt es, ich habe grad keins zur Hand.
b2) eine StringReplace-Funktion in VBS/JS zusammenbraten oder anpassen. Da hat gemini einige hier im Forum gepostet, die relativ universell sind.
b3) die reine Batch-Lösung.
- Zu ändernde Zeilennummer ermitteln.
- Alle Zeilen DAVOR lesen und eins zu eins wieder schreiben.
- die Zeile selbst neu schreiben
- Alle Zeilen DANACH lesen und eins zu eins wieder schreiben.
Lumpig bei dieser Lösung ist das Maskieren der naturgemäß vielen Größer- und Kleinerzeichen beim Lesen und Schreiben dieser XML-Datei.
Kleiner- und Größerzeichen sind ja Steuerzeichen im Batch und werden deshalb nicht als zum Text zugehörig interpretiert.
Zum Thema Maskierung: siehe in meinen Batch-Tutorials in Batch & Shell.

b4) Da ich wie alle Biber stinkefaul bin, spar ich mir die Maskiererei - ich ersetze vorher alle Kleinerzeichen durch ein Paragrafzeichen, alle Größerzeichen durch ein "deutsches SZ" und später wieder zurück.
Für diesen Zweck habe ich nämlich ein Freeware-Utility namems Change.exe irgendwo mal runtergeladen.
Link trag ich nach, falls/sobald ich ihn finde.
[Edit]hanswd hat den Link auf die change-x.zip gefunden:
http://www.daikatana.org/TecSoft/index.php?os=win&produkte=Dateien
[/Edit]

Funktioniert jedenfalls für einzelne Zeichen sauber:
$cmd$change
CHANGE Version 1.1
Programmiert von: tec@Onlinehome.de

Dieses Programm sucht in einer Textdatei nach einem bestimmten
Buchstaben und ersetzt es durch einen anderen.

Das Programm wird folgendermassen aufgerufen:
CHANGE.EXE <Datei> <Char1> <Char2> <x> <y>

<Datei> = Pfad + Dateiname der zu durchforstenden Datei
<Char1> = Nach diesem Buchstabe wird gesucht
<Char2> = Buchstabe wird ersetzt durch diesen Buchstaben
<x>     = wenn x = 1 dann: wird jede Zeile am Bildschirm angezeigt
<x>     = wenn x = 2 dann: wird keine Zeile am Bildschirm angezeigt
<y>     = wenn y = 1 dann: statt <Char1> wird das Pipezeichen "|" genommen  
<y>     = wenn y = 2 dann: statt <Char2> wird das Pipezeichen "|" genommen  
          Die Eingabe von <y> ist optional - muss also nicht unbedingt sein!
          <Char1> oder <Char2> werden dann je nachdem ignoriert. Wurde deshalb
          eingebaut da DOS kein "|" als Parameter erlaubt!  

Beispiel: CHANGE.EXE D:\BEISPIEL.TXT T Z
Es werden in der Datei D:\BEISPIEL.TXT alle Buchstaben T durch Z ersetzt.

Ich verfolge jetzt nur noch Strategie b4) weiter,

Okay, der Batchschnipsel oben hörte auf mit der Ermittling des Pfades der Machine.config.
Nächstes Teilproblem: Gibt es genau EINE Zeile mit [Username="machine"]?
Löse ich mit folgender Zeile:
for /f "skip=1 tokens=3" %%i in ('find /i /c "username=""machine" machine.config') do @set "AnzZeilen=%%i"
... in der Variablen %AnzZeile% sollte jetzt eine "1" stehen, wenn ich sinnvoll weitermachen kann.
Steht eine "0" drin, wurde keine Zeile gefunden (nothing to do).
Werden 2 oder mehr Zeilen gefunden... tja, dann muss mir einer sagen, was ich tun soll. Alle ersetzen? Nur das erste?

Okay, der Rest sollte im weitergeführten Batch nachvollziehbar sein.
::--snipp SetUserToSystemInMachineConfig.bat
@echo off & setlocal
Set "OutOfTheReg=%temp%\MySharedDLLs.reg"  
Set "NeededRegKey=HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\SharedDlls"  
regedit /e %OutOfTheReg% %NeededRegKey%
goto skipProsa
~~~~~~~~~~~
:: In der %OutOfTheReg%-Datei steht jetzt die oben abgedruckte meterlange Liste
:: Von der brauchen wir eine Zeile: die Zeile mit "machine.config"  
:: Die holen wir mit fem FIND-Befehl
:: Ein CMD-Prompt-Befehl <i>$cmd$find /i "machine.config" %OutOfTheReg%</i>  
:: würde als Output sinngemäß liefern:
<i> 
---------- Z:\TEMP\MYSHAREDDLLS.REG
"C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config"=dword:00000001</i>  
:: Die ersten beiden Outputzeilen entsorgen wir mit "skip=2" in der nächsten Anweisung  
:: ebenfalls alles nach dem "="-Zeichen inclusive mit "delims=="  
:skipProsa
for /F "skip=2 delims==" %%i in ('find /i "machine.config" %OutofTheReg%') do Set "MCFile=%%i"  
:: In MCFile steht jetzt folgendes:
:: "C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config"  
::da ersetzen wir die doppelten Backslashes durch einfache.
Set MCFile=%MCFile:\\=\%
::Ergebnis MCFile="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config"  
:: Die Überprüfung IF exist %MCFILE% sollte schon rein...
IF NOT exist %MCFILE% exit /b 3
:: Also raus mit ERRORLEVEL 3
for /f "skip=1 tokens=3" %%i in ('find /i /c "username=""machine" %MCFile%') do @set "AnzZeilen=%%i"  
IF NOT [%AnzZeilen%]==[1] exit /b 2
:: wenn nicht genau EINE Zeile mit [username="machine"]...ist Ende hier.  
Set "MCKopie=%temp%\MCTemp.txt"  
Copy /y %MCFile% %MCKopie% >nul
:: Arbeitskopie der machine.config anlegen.
:: Alle Kleinerzeichen ersetzen durch §, alle Größerzeichen durch "ß"  
change %MCKopie% ^< § 2 >nul
change %MCKopie% ^> ß 2 >nul
:: Die Zeilennummer ermitteln mit dem Text [username="machine"]  
FOR /F "skip=2 tokens=1" %%i IN ('find /i /n "username=""machine" %MCKopie%') DO set "ReplLine=%%i"  
::bei der konkreten Datei machine.config, mit der ich teste, 
:: steht jetzt bei %ReplLine% der Wert [452] für die gefundene Zeile
::noch eben die eckigen Klammern wech...
::[Edit] -------Set ReplLine=%ReplLine:[=%
::[Edit] -------Set ReplLine=%ReplLine:]=%
::[Edit] Hier war ein M$-Bug, den ich übersehen habe. 
::[Edit]   %ReplLine% wurde falsch gesetzt auf "[452]username=""machine"  
::[Edit] **Drex-M$-Stümper *grmpffffffff*
::[Edit] Workaround nächste Zeile: [/Edit]
For /F "delims=" %%i in ("%ReplLine%") do set "ReplLine=%%i"  
:: So, jetzt machine.config lesen und neue schreiben:
Set /a "AktuelleZeile=1"  
Set "MCNew=%temp%\MCNew.txt"  
If exist %MCNew% del %MCNew%
FOR /f "delims=" %%i IN (%MCTemp%) DO call :ReadAndWrite %%i  
change %MCNew% § ^< 2 >nul
change %MCNew% ß ^> 2 >nul
If Exist %MCFile% copy %MCFile% %MCfile%.old >nul
IF EXIST %MCNew% COPY /y %MCNew% %MCFile% >nul
goto :eof

:ReadAndWrite Parameter %1 ist die alte Zeile
IF [%AktuelleZeile%]==[%ReplLine%] echo username="system">>%MCNew%  
IF Not [%AktuelleZeile%]==[%ReplLine%] echo %* >>%MCNew%
Set /A "AktuelleZeile+=1"  
goto :eof
::--snapp SetUserToSystemInMachineConfig.bat

Hope it Helps
Biber

P.S. Ich verkürze mal in Deinem Kommentar oben diese meterlange Liste aus der Registry ein bisschen.
P.P.S. GETESTETE *.bat per Mail an hanswd... warte auf sein Ergebnis.
Member: Biber
Biber Jan 30, 2006 at 10:00:28 (UTC)
Goto Top
Nachtrag:
hanswd und ich haben den Batch getestet..der tut auch, was er soll.
Aber: Durch das zeilenweise Lesen und Schreiben mit der FOR..IN..DO-Anweisung werden
a) alle LeerZEILEN aus der machine.config-XML-Datei entfernt
b) auch alle führenden LeerZEICHEN (also die Einrück-Formatierungen) entfernt.
Macht dem Rechner nichts aus - die XML-Datei ist natürlich gültig und interpretierbar.
Für Menschen ist es allerdings schlechter lesbar.
Deshalb nochmal der Hinweis: Einfacher wäre es mit einen von der Konsole verwendbaren Utility, das die Zeile 'username="machine"' durch 'username="system"' ersetzen kann.
Falls jemand einen Link posten könnte, wäre ich dankbar.
Der eigentliche Lösungsweg bleibt trotzdem bestehen.

Grüße biber
Mitglied: 23972
23972 Jan 30, 2006 at 15:46:20 (UTC)
Goto Top
Ich glaub ich hab da ein passendes Freewaretool gefunden:
String Replace v1.1 - Remove/replace strings from text files
(strep11.zip)

Nr. 1093 auf dieser Liste:
http://www.sac.sk/files.php?d=19&l=

Mfg
Hans
Member: Biber
Biber Jan 30, 2006 at 16:22:50 (UTC)
Goto Top
Jepp, hanswd,
das passt besser. Wie das halt so ist mit geschenkten Gäulen hat dieses Tool zwar auch ein paar Eigenheiten, aber unterm Strich ist es natürlich viel einfacher.

Ich habe es eben mal kurz angetestet:
Das STREP-Utility erwartet im Verzeichnis, aus dem es aufgerufen wird (also nicht in dem Verzeichnis, in dem es die STREP.exe ist) eine Datei namens REPLACE.TXT mit dem Inhalt abwechselnd Suchstring und Ersatztext:
snipp REPLACE.Txt
userName="machine"
userName="system"
snapp REPLACE.Txt

Mit den Anführungszeichen kommt STREP.exe klar; die beiden Zeilen/die REPLACE.TXT lassen sich auch dem Batch per ECHO anlegen.
Auch diese ganze Einzelzeichen-Ersetzungsmimik mit CHANGE.exe im obigen Batch wird hinfällig.
Zu beachten ist nur, dass STREP.exe nicht mit Extensions größer 3 Zeichen klarkommt; Inputdatei muss eine Extension <=3 Zeichen haben; Outputdateiname wird mit Extensionlänge = 3 angelegt.
Ich denke, von obigen Batch bleibt nur die Anfangsmimik übrig (Ermitteln des machine.config-Pfades via Registry; Überprüfung auf genau ein Vorkommen von SUCHTEXT), danach diese Zeile ersetzen mit STREP und gut ist.

Hätten wir also etwas kürzer haben können. *gg

Grüße und vielen Dank für den Link
Biber
Mitglied: 23972
23972 Jan 30, 2006 at 17:33:28 (UTC)
Goto Top
Hier mal der Code für die Batch mit Strep 1.1:

@echo off & setlocal
Set "OutOfTheReg=%temp%\MySharedDLLs.reg"  
Set "NeededRegKey=HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\SharedDlls"  
regedit /e %OutOfTheReg% %NeededRegKey%

for /F "skip=2 delims==" %%i in ('find /i "machine.config" %OutofTheReg%') do Set "MCFile=%%i"  
:: In MCFile steht jetzt folgendes:
:: "C:\\WINDOWS\\Microsoft.NET\\Framework\\v1.1.4322\\CONFIG\\machine.config" 
::da ersetzen wir die doppelten Backslashes durch einfache.
Set MCFile=%MCFile:\\=\%
::Ergebnis MCFile="C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG\machine.config" 
:: Die Ueberpruefung IF exist %MCFILE% sollte schon rein...
IF NOT exist %MCFILE% exit /b 3
:: Also raus mit ERRORLEVEL 3
for /f "skip=1 tokens=3" %%i in ('find /i /c "username=""machine" %MCFile%') do @set "AnzZeilen=%%i"  
IF NOT [%AnzZeilen%]==[1] exit /b 2
:: wenn nicht genau EINE Zeile mit [username="machine"]...Ende hier. 

Set "MCResult=%temp%\MCResult.txt"  
Set "MCKopie=%temp%\MCNew.txt"  
Copy /y %MCFile% %MCKopie% >nul
STREP %temp%\MCNew.txt %temp%\MCResult.txt

If exist %MCKopie% copy /y %MCResult% %MCFile% >nul
goto :eof