Batch-Programmierung: Beispiele

Aus Wikibooks

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

[Bearbeiten] Regedit.exe

Eine kleine Batchdatei, um mit regedit.exe direkt einen bestimmten REG-Zweig anzuspringen:

set LastKey="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix"
 
set Key=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit
reg add %Key% /f /v "LastKey" /d %LastKey%
start regedit.exe

Erläuterung:

  • LastKey ist der Reg-Schlüssel, der als Letztes angezeigt wurde und dieser wird beim Start von regedit direkt angesprungen, diesen Schlüssel kann man nach Belieben anpassen.
  • Key ist der Reg-Schlüssel in dem sich der Wert "LastKey" befindet.

LastKey wird mittels reg add in die Registry eingespielt und danach wird regedit gestartet. Das Ganze funktioniert allerdings nur, wenn regedit.exe noch nicht läuft.

Und hier noch eine kleine Batchdatei, um mit regedit.exe Werte aus der Registry auszulesen:

set Key="HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit"
regedit.exe /e c:\temp\inhalt.reg %Key%

Achtung! Die Datei inhalt.reg ist im Unicode-Format. Ein Tipp dazu: Der type-Befehl kann Unicode lesen.

[Bearbeiten] TaskList-Abfrage

Eine Routine um das Laufen eines Prozesses mittels tasklist.exe festzustellen. In diesem Beispiel wird geprüft, ob Prozess.exe läuft.

 @echo off
 set ProgEXE=Prozess.exe
 set tempdatei=%temp%\TempDatei.txt
 
 tasklist /FI "IMAGENAME eq %ProgEXE%" /FO CSV>%tempdatei%
 
 for /F "skip=2 tokens=1 delims=," %%f in (%tempdatei%) do (
    echo gefiltert: [%%f]
    if "%%f"==""%ProgEXE%"" echo Prozess %ProgEXE% läuft
    goto ende
 )
 echo Prozess %ProgEXE% läuft nicht!
 goto ende
 
 :ende
    del %tempdatei%


Alternativ, ohne obige temporäre Datei 'tempdatei' zu benötigen, kann man beispielsweise unter Windows XP folgendes verwenden:

TaskList /FI "IMAGENAME eq %ProgEXE%" 2>NUL | Find "%ProgEXE%" >NUL
IF ERRORLEVEL == 1 (
  ECHO NOT Running.
  GOTO Ende
  ) ELSE (
    ECHO Running.
    GOTO Ende
    )

[Bearbeiten] Dienste einrichten

@echo off
prompt -$G
echo.
echo ### Manuelle Dienste ###
echo.
call:M helpsvc		"Hilfe und Support"
call:M ImapiService	"IMAPI-CD-Brenn-COM-Dienste"
 
echo.
echo ### nicht benötigte Dienste Deaktivieren ###
echo.
call:D cisvc		"Indexdienst"
call:D ERSvc		"Fehlerberichterstattungsdienst"
 
 
echo.
echo ### Automatische Dienste ###
echo.
call:A CryptSvc     "Kryptografiedienste
call:A MSIServer	"Windows Installer"
 
 
echo.
echo.
echo Fertig!
echo.
pause
goto:eof
 
 
:A
echo %2 auf Automatisch
set Parameter=auto
net start %1
goto machen
 
:M
echo %2 auf Manuell
set Parameter=demand
net stop %1
goto machen
 
:D
echo %2 auf Deaktiviert
set Parameter=disabled
net stop %1
goto machen

 
rem Systemstart		Gerätetreiber, der vom Startladeprogramm geladen wird.
rem system		Gerätetreiber start während der Kernelinitialisierung.
rem auto		automatischer start, nach systemstart, vor Benutzeranmeldung.
rem demand		Dienst, der manuell gestartet werden muss.
rem disabled		Dienst deaktivieren
 
 
:machen
	echo on
	sc config %1 start= %Parameter%
	@echo off
	echo.
	echo.
goto:eof

[Bearbeiten] Windows XP SP2: installierte Patches/Updates auflisten

Zeigt unter Windows XP mit Service Pack 2 alle zusätzlich installierten Patches/Updates an.

@echo off
 
set RegHotfixListe=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Hotfix
 
set RegHotfixInfo=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Updates\Windows XP\SP3
 
for /F "delims=\ tokens=7" %%f in ('reg query "%RegHotfixListe%"') do (
    set HotFixNr=%%f
    CALL :Anzeigen
)
 
echo.
echo.
pause
goto:eof
 
 
 
 
:Anzeigen
    reg query "%RegHotfixListe%\%HotFixNr%" /v Installed | FIND "0x1">NUL
    if "%errorlevel%"=="0" (
            set installiert=ja
            call:KB_Info
        ) ELSE (
            set installiert=nein
        )
 
    echo %HotFixNr% - Ist Installiert: %installiert%
    if not "%InstalledBy%"==""   echo %HotFixNr% installiert von %InstalledBy%
    if not "%InstalledDate%"=="" echo %HotFixNr% am %InstalledDate%
    echo.
goto:eof
 
 
 
 
 
:KB_Info
    set InstalledBy=
    for /F "tokens=3" %%c in ('reg query "%RegHotfixInfo%\%HotFixNr%" /v InstalledBy 2^>NUL ^| FIND "InstalledBy"') do (
        set InstalledBy=%%c
        )
    set InstalledDate=
    for /F "tokens=3" %%c in ('reg query "%RegHotfixInfo%\%HotFixNr%" /v InstalledDate 2^>NUL ^| FIND "InstalledDate"') do (
        set InstalledDate=%%c
        )
goto:eof

[Bearbeiten] Printdateien direkt an den Drucker senden

Sendet einzelne Druckdateien an im Netzwerk freigegebene Drucker. Eignet sich besonders bei Standard Drucksprachen wie Postscript und HPGL/2.

@echo off
rem "pl.bat" sendet einzelne Druckdateien an bel. Drucker direkt.
rem eignet sich besonders bei Standard Drucksprachen wie Postscript und HPGL/2.
rem Laesst sich in Windows bequem einbinden, z.B rechte Maustaste - Senden an Plotter
 
:voreingestellt
    set server=192.168.0.5
    rem server --- IP von Printserver/oder Name von Freigaberechner ---
    set druckerbeschreibung=192.168.0.5 Freigabename EPSON
    rem druckerbeschreibung --- damit der Drucker leichter identifiziert werden kann ---
    set drucker=EPSONNT
    rem drucker --- das muss der Freigabename im Netzwerk/auf dem Freigaberechner sein ---
 
    if '%1' == 'drucker01' goto drucker01
    if '%1' == 'drucker02' goto drucker02
    if '%1' == 'canon' goto canon
goto datei
 
:drucker01
    shift
goto datei
 
:drucker02
    set server=42.1.1.240
    set druckerbeschreibung=HP DJ 755CM im Sekretariat
    set drucker=hpdj755-tcp
    shift
goto datei
 
:canon
    set server=192.168.0.1
    set druckerbeschreibung=Canon s/w Laser im EG
    set drucker=CanonLBP
    shift
goto datei
 
:datei
    if '%~1' == '' goto aufruf
goto plot
 
:plot
    echo.
    echo Dateiname   : %1
    echo Druckserver : %server%
    echo Freigabename: %drucker%
    echo Beschreibung: %druckerbeschreibung%
    echo.
    print /d:\\%server%\%drucker% '%~1'
goto:eof
 
:aufruf
echo.
echo    aufruf  : pl [plotter] Datei
echo    plotter : drucker01, drucker02, canon, (voreingestellt ist drucker01)
echo.

Anmerkung zur Nutzung dieses Scriptes:

  • Der Printbefehl schickt die Datei OHNE Interpretation direkt an den Drucker. Eine Bilddatei im JPEG-Format würde statt der Grafik also lediglich einen haufen wirrer Zeichen ergeben.
  • Der Drucker muß in der Lage sein, selbst ASCII-Zeichen zu verarbeiten und aus zu geben. Dies ist bei älteren Druckern (vor ca. 1996 sicher) immer der Fall. Heute beherrschen meist nur noch PostScript-fähige Drucker diese Fähigkeit. "Billigen" GDI-Druckern muß man etwas auf die Sprünge helfen mit dem verwendeten "Druckprozessor" im Windows-Druckertreiber.


  • Zum Umschalten zunächst die Druckerübersicht öffnen - Zu finden unter Start|Drucker und Faxgeräte
  • Dann die Eigenschaften des gewünschten Druckers ausrufen (Rechtsklick|Eigenschaften)
  • Auf dem Reiter "Erweitert" den Button "Druckprozessor..." klicken
  • In dem erscheinenden Dialogfeld gibt es 2 Felder mit Einträgen. Im rechten Feld (Standartdatentypen) findet sich neben verschiedenen anderen auch der Eintrag "Text". Diesen markieren und dann alles mit OK wieder schließen.


Der Druckprozessor von Windows ist nun in der Lage, Ausgaben entsprechend zu Interpretieren und dem GDI-Drucker als Grafik zu liefern. Es können aber nur stur 80 Zeichen (maximal) auf ca. 60 Zeilen verteil werden. Manchmal sind es bis zu 66 Zeilen.

[Bearbeiten] Copy

Kopieren von Dateien.

Der Befehl
 copy test.txt c:\temp
kopiert die Datei test.txt aus dem aktuellen Ordner in den Ordner c:\temp.
Der Befehl
 copy c:\test.txt c:\temp
kopiert die Datei test.txt aus dem Ordner c:\ in den Ordner c:\temp

Batch-Dateien kennen beim Kopieren nur Ordner mit max. 8+3 Buchstaben desshalb muss man statt z.B.:

copy test.txt c:\programme

die kurzen Ordner- bzw. Dateinamen

copy test.txt c:\progra~1 

verwenden (ist nicht bei jedem Betriebssystem erforderlich. Im Zweifelsfall ausprobieren.).

copy test1.txt + test2.txt test.txt

Kombiniert in der gegebenen Reihenfolge zwei oder mehrere durch "+" verbundene Textdateien in einer neuen Gesamtdatei.

In diesem Zusammenhang muss auf die Bedeutung der Parameter "/A" (für ASCII-Format, der Standardwert) und "/B" (für Binär-Format ) eingegangen werden, die jedem Dateinamen in obigem Beispiel mit einem Leerzeichen Abstand vorangehen können. DOS-Textdateien enthalten ein Dateiendezeichen (Dezimal 26, Hexadezimal 1A). Beim Kopiervorgang darf in der Gesamtdatei nur als letztes Zeichen ein Dateiendezeichen erscheinen, sonst würde der Text nach der ersten Endmarkierung nicht mehr angezeigt. "copy" kopiert ohne das abschließende Zeichen und fügt als letztes wieder eines zur Gesamtdatei hinzu.

Möchte man Dateien mit binären Inhalten zusammenfügen (z.B. PostScript-Dateien, die auch binäre Abschnitte enthalten können), so würde ohne Parameter "/B" ebenfalls nur bis zu einem zufällig vorkommenden Dateiendezeichen kopiert und damit das Ergebnis unbrauchbar.

[Bearbeiten] Message-Ping

Mit Hilfe des folgenden Scripts kann man Windows um eine nützliche Funktionalität erweitern. Mit Hilfe von mping erhält man eine Nachricht, sobald der gepingte Computer wieder erreichbar ist.

Um das Script global zu verwenden, muss es z.B. als "mping.cmd" in "Windows-Installationsordner\System32" gespeichert werden und kann von nun an z.B. mit "mping google.com" aufgerufen werden.

Außerdem muß beim ausführenden und beim benachrichtigen Rechner der Nachrichtendienst aktiviert sein, was wegen der inzwischen üblichen Spam-belästigung aus dem Internet seit dem Servicepack 2 bei WinXP standardmäßig abgeschaltet wird.

@echo off
 
:: wenn kein remote Host angegeben ist, dann gehe zu :Syntax
IF [%1]==[] GOTO Syntax
IF [%1]==[/?] GOTO Syntax
IF [%1]==[/h] GOTO Syntax
IF [%1]==[/help] GOTO Syntax
 
:mainloop
:: pinge den Host 1 mal und leite die Ausgabe nach 'nul' um (keine sichtbare Ausgabe)
ping %1 -n 1 >nul
 
:: speichere den Errorlevel in die Variable 'status'
set status=%errorlevel% 
 
:: sende eine Nachricht an den lokalen Computer falls der remote Host online ist 
if %status%==0 (net send %computername% %1 online && exit 0)
 
:: minimalistische Fortschrittsanzeige
(Set /P i=.) < NUL
 
:: sleep workaround   (wer eine bessere, einfachere, genauere & universellere Möglichkeit kennt bitte korrigieren)
:: pinge den lokalen Computer 10 mal
ping localhost -n 10 >nul
 
:: gehe zurück zum anfang
goto mainloop
 
:Syntax
echo.
echo Syntax:  %~n0 [Hostname oder IP]
echo.
echo mping
echo.
echo Pingt einen offline Host und gibt eine Meldung 
echo aus, sobald er wieder online ist
echo.

[Bearbeiten] Defrag mit Endlos-Schleife

Das eingebaute Defrag-Tool erlaubt ja immer nur die gleichzeitige Defragmentierung eines Laufwerks. Außerdem sind oftmals mehrere Durchgänge nötig, bis das Laufwerk wirklich vollständig defragmentiert ist. Mit dieser kleinen Batch Datei werden alle Partitionen immer wieder hintereinander defragmentiert. Ich starte dieses Skript hin und wieder, wenn ich gerade den Rechner nicht brauche. Wenn man wieder arbeiten will, kann man einfach das Eingabefenster schließen. Auch bei laufendem defrag passiert dabei nichts, weil defrag im Hintergrund die aktuelle Arbeit sauber beendet.

Damit aber nicht defekte Laufwerke einfach blind defragmentiert werden, habe ich eine etwas aufwendige Prozedur eingebaut, die die Laufwerke mit chkdsk erst überprüft. Wenn dabei ein Fehler auftritt, wird mit fsutil das dirty Bit gesetzt. Das bewirkt, dass beim nächsten Systemstart die Fehler behoben werden. Außerdem werden die Partitionen in dem loop ausgelassen, welche schon als dirty markiert sind.

Eine kleine Routine war auch nötig, damit Netzwerklaufwerke ausgelassen werden.

@echo off
cd /d C:\
 
:loop
    for %%i in (c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) do (
        if exist %%i:\NUL call:defrag %%i
    )
    echo.
    echo pause...
    ping localhost -n 10 >NUL
goto loop
 
:defrag
    call:check %1
    if "%ok%"=="nein" (
        echo Laufwerk %1: wird ausgelassen
        echo.
        goto:eof
    )
    echo.
    echo.
    echo chkdsk %1: /v
    chkdsk %1:
    if %errorlevel% NEQ 0 (
        if %errorlevel% NEQ 2 (
            echo %1: chkdsk Fehler!!!
            echo Errorlevel: %errorlevel%
            echo.
            echo setzte dirty-Bit:
            fsutil dirty set %1:
            echo.
            echo Versuche Reparatur
            chkdsk %1: /v /x
            if %errorlevel% EQU 2 (
                echo Fehler bereinigt!
            ) else (
                echo Errorlevel: %errorlevel%
                echo.
                goto:eof
              )
        )
    )
    echo defrag %1: -f
    defrag %1: -f
    if %errorlevel% NEQ 0 (
        pause
        exit
    )
    rem pause...
    ping localhost -n 1 >NUL
goto:eof
 
:check
    set ok=nein
    net use | find /i "%1:" >NUL
    if not errorlevel 1 (
        echo %1: ist ein Netzlaufwerk
        goto:eof
    )
    fsutil dirty query %1:
    for /F "tokens=5" %%f in ('fsutil dirty query %1:') do (
        if not "%%f"=="NICHT" (
            rem Laufwerk ist als fehlerhaft markiert
            goto:eof
        )
    )
    set ok=ja
goto:eof

Als Alternative gibt es das Open Source Program JkDefrag, welches auch alle Laufwerke nacheinander defragmentiert.

[Bearbeiten] Dateiinformationen anzeigen

Dieses Batch-Skript zeigt Informationen über die Datei, die als Parameter übergeben wird, an. (so ist das Starten des Skript per Drag&Drop möglich)

@echo off
echo Attribute...................: %~a1
echo Laufwerk....................: %~d1
echo kompletter Pfad.............: %~f1
echo Dateiname...................: %~n1
echo Ordnerpfad..................: %~p1
echo kompletter Pfad (kurze Form): %~s1
echo Aenderungsdatum.............: %~t1
echo Dateierweiterung............: %~x1
echo Dateigroesse................: %~z1
pause

Hinweis: Falls die Attribute des eigenen Batch-Skripts ausgelesen werden sollen, so muss der Parameter Null verwendet werden (Beispielsweise %~p0). Eine Kombination ist auch möglich, z.B: %~dp0 (Laufwerk + Pfad)

[Bearbeiten] Alle verfügbaren PCs im aktuellen Netzwerk suchen

Dieses Batch-Skript pingt alle IP-Adressen eines IP-Bereichs an und zeigt dann die PCs an, die verfügbar sind.

@echo off
 
if exist ips.txt del ips.txt > nul
 
echo Bitte geben Sie den ersten Teil der IP ein:
set /p ip=
 
for /L %%N IN (1, 1, 255) DO (
	echo Die IP: %ip%%%N wird nun angepingt
	ping %ip%%%N -n 1 -w 1 | find "TTL" && echo %ip%%%N >> ips.txt
)
 
cls
type ips.txt
pause >nul

Hinweis: Die Datei ips.txt wird nicht gelöscht, damit man sie für weitere Zwecke benutzen kann.

[Bearbeiten] Hosts Datei mit einem Aliasnamen und der aktuellen IP-Adresse aktualisieren

Häufig werden Webserver oder ähnliche Programme unter Angabe eines Aliasnamens installiert, damit sie leicht auf einen anderen Rechner verschoben werden können, falls der ursprüngliche Rechner defekt ist. Oder die Aplikationläuft unter VM-Ware auf einen Laptop bei dem sich die IP-Adressen häufig ändern. Dann kann mit dem Skript der Hostnamenalias mit der aktuellen IP-Adresse aktualisiert werden. Idealerweise wird das Script automatisch beim Start von Windows oder beim Anmelden des Anwenders ausgeführt.

@echo off
set HOST_ALIAS=myserver myserver.mydomain.org
set HOST_FILE=%SystemRoot%\System32\drivers\etc\hosts
set TEMP_FILE=%TEMP%\hosts.tmp

REM vorhandenen Eintrag entfernen und den Rest in TEMP-Datei schreiben
type %HOST_FILE% | find /v "myserver" > %TEMP_FILE%

REM Neuen Eintrag wieder hinzufügen
for /F "tokens=15" %%i in ('ipconfig ^| find "IP Ad"') do set IP=%%i
echo %IP% %HOST_ALIAS%>>%TEMP_FILE%
echo ## Added %IP% %HOST_ALIAS% to the hostsfile

REM Temp-File nach %SystemRoot%\System32\drivers\etc\hosts kopieren
REM Die Datei Hosts darf nicht mit "move" verschoben werde, sondern muss kopiert werden, da sonst der Hostname nicht gefunden werden kann.
copy /y %TEMP_FILE% %HOST_FILE%
del /F /Q %TEMP_FILE%

[Bearbeiten] Windowsversion herausfinden

Mit dieser Batchdatei findet man heraus, welche Windowsversion verwendet wird. Das ist nützlich, wenn man mit bestimmten Pfaden arbeitet, die je nach Betriebsystem verschieden sind. Hier wird das Ergebnis mithilfe einer VBScript MsgBox ausgegeben.

@echo off
 
VER |find /i "Windows 95" >NUL
IF NOT ERRORLEVEL 1 GOTO 9598ME
VER |find /i "Windows 98" >NUL
IF NOT ERRORLEVEL 1 GOTO 9598ME
VER |find /i "Windows Millennium" >NUL
IF NOT ERRORLEVEL 1 GOTO 9598ME
VER | find "XP" > nul
IF %errorlevel% EQU 0 GOTO XP
VER | find "2000" > nul
IF %errorlevel% EQU 0 GOTO 2000
VER | find "NT" > nul
IF %errorlevel% EQU 0 GOTO NT
VER | find "Microsoft Windows [Version 6" > nul
IF %errorlevel% EQU 0 GOTO Vista
VER | find "Microsoft Windows [Version 5" > nul
IF %errorlevel% EQU 0 GOTO 2003
goto unknown
goto end
 
:unknown
echo MsgBox "Betriebsystem unbekannt", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:9598ME
echo MsgBox "Sie haben 95, 98 oder ME", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:NT
echo MsgBox "Sie haben Windows NT", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:2003
echo MsgBox "Sie haben Windows 2003", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:2000
echo MsgBox "Sie haben Windows 2000", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:XP
echo MsgBox "Sie haben Windows XP", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:Vista
echo MsgBox "Sie haben Windows Vista oder Windows 7 RC", VbInformation + VbOKOnly, "Ihr Betriebsystem" >%TEMP%\os.vbs
goto end
 
:end
START %TEMP%\os.vbs
Persönliche Werkzeuge