viewfinder
Goto Top

Laufzeit testen, vergleichen von Laufzeiten verschiedener Skripte mit der Batch RunTimeCalc. Beispielanwendung - Schreibrechte des aktuellen Benutzers testen

Dieser Artikel steht im direktem Zusammenhang zu dem Snippet von bastla im Artikel: "Laufzeit bzw. Dauer einer Batch ermitteln!". Das Skript enstand als Übung zur allgemeinen Einarbeitung in Programiersprachen. Dem nach ist es die Arbeit eines blutigen Anfängers (Programierung) mit der gegebenen Pflicht zur Sorgfalt.

Noch kurz zu mir. Ich stehe bis her nicht nur entfernt zur Fachtermina, sondern auch zu Deutschland. Was meint, das Antworten durchaus etwas mehr Zeit benötigen.

Hallo wertes Forum,
es stand nicht in meiner Absicht einen eigenen Blog zu eröffnen. Wer mehr wissen möchte springt am besten zum oben angegebenen Link und ist schnell im Thema. Ursprünglich wollte ich nicht die vielen Codezeilen in die Menge schmeißen, sondern ein vereinfachtes Ablaufschema und ein paar Zeilen als Antwort posten. Da ich leider keine Möglichkeit gefunden habe, ein Bild in eine Antwort einzubinden, gibt es jetzt alles in einem Rutsch als eigenen Beitrag. Denn ohne eine grafische Darstellung, wird die Einarbeitung in den Code vermutlich etwas anstrengend.


back-to-topUrsprung

Das Thema liegt schon eine Weile auf Eis, doch ich brauchte einen Einstieg in die Thematik Programiersprache. Bei den deutsch sprachigen Recherchen landet man immer wieder bei Administrator.de. Ob die Batchprogramierung hier der richtige Ansatz ist bleibt fraglich. Auf jeden Fall habe ich einen Einblick bekommen und kann mich ausgereifteren Sprachen zuwenden.

Nur was mache ich jetzt mit dem enstandenen Programm (chen)?
Entsprechend meiner generellen Auffassung gibt man zurück, was man bekommen hat. Als Neuling schreibt man andererseits auch keinen Blog. Doch die Technik läßt keinen anderen Weg und so mache ich diese Erfahrung noch neben bei.

back-to-topHistory

Bastlas Antwort auf eine Userfrage war ein kompletter Berechnungsmodus den man unter Laufzeit bzw. Dauer einer Batch ermitteln! einsehen kann. Das Skript, für welches die Laufzeit berechnet werden soll (in Folge Laufzeitskript genannt), muss zwischen die Codezeilen gelegt werden.
Das Laufzeitskript läuft als Subroutine der Laufzeitberechnung.
Da bastla lediglich eine schnelle Antwort geliefert hat, lag das Laufzeitskript an der logischen Position im Code. Also mitten drinn. Nichts für DAU and me.
Die Lage des Laufzeitskriptes ist riskant und nicht ergonomisch.
Damit war schon mal die Aufgabe gefunden.

back-to-topEntwicklung
Gerade als Anfänger tut man sich mit den vielen Begriffen schwer. Bastlas Code brauchte einen Namen RunTimeCalc. Die Ideen häuften sich und so wurde daraus schnell ein Konzept zu einem Tool. Was soll dieses Tool können?
  • Vergleichszeiten verschiedener Skripte aus der Laufzeit ausgeben (erledigt)
  • Zeitmessung und Zeitberechnung als Subroutine ausführen (erledigt)
  • Einfache Bedienung mit Fehlerhandling stellen (erledigt)
  • Bedienungsfehler ausgeben (erledigt)
  • Logsystem integrieren (erledigt)

back-to-topAktualisierung
27.11.2012 Hilfe und Protokollierung verbessert, Pause aus „:EXIT“ entfernt (sorry)

back-to-topAblaufschema.

b1ace16fb2cf5ac9030e46f20a4c878c

back-to-topTool RunTimeCalc (Code)

:Environment
@echo off
pushd %~dp0
setlocal


:VarTranslate
:: Startvariablen
set "ProcessID=%2"  
set "StartParameter=%1"  
:: Handling ProcessID
:: ... bei fehlendem Startparameter
if "%StartParameter:~0,1%" EQU "@" (  
	set "ProcessID=%StartParameter%"  
	set "StartParameter="  
	)
	:: ... Formatierung
if "%ProcessID:~0,1%" EQU "@" (  
	set "ProcessID=%ProcessID:~1%"  
	) else (set "ProcessID=")  

:InputControl
FOR %%i in ( [-C] [-E] [-H] [-S]) do IF [%StartParameter%] EQU %%i goto :Settings
echo.
echo   RuntimeCalc
echo.
echo   --------mistake: [%1]--------------------------------------------------
echo   Startzeit [-S]  Endzeit, Berechnung[-E]  Hilfe [-H]  interne Berechnung 
echo        Kontrolle [-C]                  ProcessID [@Text_ohne_Leerzeichen]
echo.
echo.
echo "%ProgName%" wurde wegen falschem Parameter beendet.  
echo.
echo.
goto :Exit

:Settings
set "ProgName=RunTimeCalc"  
set "RTC_FilePath=%~dp0"  
set "RTC_InfStamp=%date%;%time%;[INFO];[%ProcessID%]"  
set "RTC_ErrStamp=%date%;%time%;[ERROR];[%ProcessID%]"  
if "%log_file%" EQU "" set "log_file=%~dp0%ProgName%.log"  
:: Abhaengikeit zu ":ActiveProcess" und ":MenuSet1" 
set "RTC_ProcFile=%RTC_FilePath%%ProgName%_TEMP_%ProcessID%.cmd"  

:StartParameter
:: Handling StartParameter
:: ... IFs ueberspringen
if "%StartParameter%" EQU "" goto :SetStartTime  
:: ... Startzeit aus Datei abrufen
if "%StartParameter%" EQU "-E" (  
	if not exist "%RTC_ProcFile%" goto :Error-E  
	call :GetTime
	call %RTC_ProcFile% 
	goto :SetEndTime
	)
:: ... Startzeit in Datei speichern
if "%StartParameter%" EQU "-S" (  
	if exist "%RTC_ProcFile%" goto :Error-S  
	call :GetTime
	goto :WriteProcess
	)
:: ... Hilfe des Programms aufrufen
if "%StartParameter%" EQU "-H" goto :Help  
:: ... laufende Prozesse abfragen
if "%StartParameter%" EQU "-C" goto :Control-C  


:SetStartTime
:: Start der Berechnungsroutine
:: ... Startzeit (in Hundertstelsekunden) holen
call :GetTime
:: ... Startzeit in Variablen speichern 
set "Startzeit=%t%"  
set "Start=%TimeInHSec%"  
:: --------------------
:: ... Startet das innenliegende Skript (optional)
call :StartRunTimeSkript
:: --------------------
:SetEndTime
:: Holt die Endzeit und berechnet Differenz zur Startzeit
:: ... Endzeit (in Hundertstelsekunden) holen und in Variablen speichern
call :GetTime
set "Endzeit=%t%"  
set "End=%TimeInHSec%"  
:Calculator
:: ... Ermittlung und Zerlegung/Formatierung der Differenz
set /a Diff=%End%-%Start%
:: ... Tageswechsel beachten
if %Diff% lss 0 set /a Diff+=8640000
set DiffRem=%Diff%
:: ... Hundertstelsekunden holen
call :GetPart 100
set hs=%Part%
:: ... Sekunden holen
call :GetPart 60
set s=%Part%
:: ... Minuten holen
call :GetPart 60
set m=%Part%
:: ... Stunden bleiben als Rest
set h=%DiffRem%
:Output
:: Ausgabe der Daten, End of Batch
if [%ProcessID%] NEQ  (
	if not exist "%RTC_ProcFile%" (  
		echo %RTC_InfStamp%>>%log_file%
		echo [%ProcessID%]  Startzeit       %Startzeit%>>%log_file%
		)
	echo [%ProcessID%]    Endzeit       %EndZeit%>>%log_file%
	echo [%ProcessID%]      Dauer        %h%:%m%:%s%,%hs%>>%log_file%
	)
echo.
if "%StartParameter%" == "" call :Reference  
echo ...............................
echo Laufzeit zum Prozess [%ProcessID%]
echo -------------------------------
echo Startzeit:     %Startzeit%
echo Endzeit:       %EndZeit%
echo Dauer:         %h%:%m%:%s%,%hs%
echo ...............................
echo.
if exist "%RTC_ProcFile%" del %RTC_ProcFile%  
goto :Exit


:GetTime 
:: Subroutine zur Bildung der Variablen von Start- und End- zeit
:: ... Aktuelle Zeit verwenden ...
set t=%time%
:: ... Systemvariable "time" zerlegen, Formatierungszeichen entfernen ... 
for /f "tokens=1-4 delims=:," %%i in ("%t%") do set "h=%%i" & set "m=%%j" & set "s=%%k" & set "hs=%%l"  
:: ... Oktalzahlklippen umschiffen ...
if %m:~0,1%==0 set m=%m:~1%
if %s:~0,1%==0 set s=%s:~1%
if %hs:~0,1%==0 set hs=%hs:~1%
:: ... und in Hundertstelsekunden-Wert umrechnen.
set /a TimeInHSec=((%h%*60+%m%)*60+%s%)*100+%hs%
goto :eof 

:GetPart
:: Subroutine zur Berechnung der Differenz
:: ... Anhand des Aufrufparameters (60 oder 100) aufspalten ...
set /a Part=%DiffRem%%%%1
:: ... und mit fuehrender Null formatieren sowie ...
if %Part% lss 10 set Part=0%Part%
:: ... noch aufzuteilenden Rest der Differenz ermitteln.
set /a DiffRem=%DiffRem%/%1
goto :eof



:WriteProcess
:: Schreibt "RTC_ProcFile" und speichert Startzeit 
echo @echo off>%RTC_ProcFile%
echo TITLE %ProgName% [%ProcessID%]>>%RTC_ProcFile%
:: ... speichern der Variablen als festen Wert
echo set "Startzeit=%t%">>%RTC_ProcFile%  
echo set "Start=%TimeInHSec%">>%RTC_ProcFile%  
:: ... Protokoll unerwuenscht - schneller machen
echo if [%ProcessID%] EQU  ^(goto :eof^)>>%RTC_ProcFile%
:: ... Wertuebergabe an das Protokoll bei Aufruf des "RTC_ProcFile" 
echo echo %%RTC_InfStamp%%^>^>%log_file%>>%RTC_ProcFile%
echo echo [%ProcessID%]  Startzeit       %%Startzeit%%^>^>%log_file%>>%RTC_ProcFile%
echo goto :eof>>%RTC_ProcFile%
echo Startzeit mit "%t%" und ProcessID [%ProcessID%] wurde gespeichert.  
goto :Exit


:Error-E
:: Fehlerhandling wenn Prozess nicht vorhanden
set "MessageID=Err-E"  
echo.
echo.
echo WARNUNG:
echo ProcessID: [%ProcessID%]
echo Eine Laufzeitberechnung mit gleicher ProcessID wurde nicht gefunden.
echo %RTC_ErrStamp%>>%log_file%
echo [%ProcessID%];%MessageID%;Gleichnamiger Prozess wurde nicht gefunden>>%log_file%
echo [%ProcessID%];%MessageID%;Betroffene Startzeiten werden nachfolgend aufgelistet.>>%log_file%
echo.
echo Der aktuelle Vorgang ist relevant fuer ALLE aktiven Laufzeitberechnungen.
echo Er ist nicht ausfuehrbar und wird in jedem Fall abgebrochen.
echo.
echo Liste der aktiven Laufzeitberechnungen
call :ActiveProcess
echo.
goto :MenuOptionen

:Error-S
:: Fehlerhandling wenn Prozess vorhanden
set "MessageID=Err-S"  
echo.
echo.
echo WARNUNG:
echo ProcessID: [%ProcessID%]
echo Eine Laufzeitberechnung mit gleicher ProcessID wurde bereits gestartet
echo und nicht beendet.
echo %RTC_ErrStamp%>>%log_file%
echo [%ProcessID%];%MessageID%;Gleichnamiger Prozess gefunden>>%log_file%
echo [%ProcessID%];%MessageID%;Betroffene Startzeiten werden nachfolgend aufgelistet.>>%log_file%
echo - Jede Laufzeitberechnung die innerhalb einer aktiven Laufzeitberechnung
echo   gestartet wird, benoetigt eine eigene ProcessID.
echo.
echo Der aktuelle Vorgang ist relevant fuer ALLE aktiven Laufzeitberechnungen.
echo.
echo Liste der aktiven Laufzeitberechnungen
call :ActiveProcess
echo.
echo Bei Fortsetzung des aktuellen Prozesses wird eine neue Startzeit
echo gespeichert. In der Logdatei erfolgt ein Hinweis auf diesen Vorgang.
echo.
goto :MenuOptionen

:Control-C
:: Zugang zum Menue
set "MessageID=Ctrl-C"  
echo.
echo.
echo HINWEIS:
echo ProcessID: [%ProcessID%]
echo Es werden alle gestarteten Prozesse Prozesse angezeigt. Dieser Vorgang
echo wird grundsaetzlich geloggt.
echo %RTC_InfStamp%>>%log_file%
echo [%ProcessID%];%MessageID%;Gleichnamiger Prozess gefunden>>%log_file%
echo [%ProcessID%];%MessageID%;Betroffene Startzeiten werden nachfolgend aufgelistet.>>%log_file%
echo.
echo Liste der aktiven Laufzeitberechnungen
call :ActiveProcess
echo.
goto :MenuOptionen

:ActiveProcess
:: Listet betroffene Prozesse [Startzeiten]
FOR /R %RTC_FilePath% %%I in (%ProgName%_TEMP_*.cmd) do set "RunProzess=%%I"  
if "%RunProzess%" == "" (  
	echo %MessageID%;Es wurden keine laufenden Prozesse gefunden.
	echo [%ProcessID%];%MessageID%;Es wurden keine laufenden Prozesse gefunden.>>%log_file% 
	goto :eof
	)
setlocal enabledelayedexpansion
for /R %RTC_FilePath% %%I in (%ProgName%_TEMP_*.cmd) do (
	set "RunProzess=%%~nI"  
	echo %MessageID%;[!RunProzess:%ProgName%_TEMP_=!]
	echo [%ProcessID%];%MessageID%;[!RunProzess:%ProgName%_TEMP_=!]>>%log_file%
	)
setlocal disabledelayedexpansion
goto :eof


:MenuOptionen
echo.
echo ---------------
echo OPTIONS - MENUE
echo ---------------
echo.
echo Die Optionen koennen durch Eingabe von 1, 2, 3 oder 4 gewaehlt werden
echo -------------------------------------------------------------------------
echo 1. Loeschen aller Startzeiten, %ProgName% beenden (empfohlen)        [1]
echo 2. Loeschen der aktuellen Startzeit, %ProgName% beenden              [2]
echo    aktueller Prozess ist:  [%ProcessID%]
echo 3. Fortsetzen von %ProgName% - Ueberschreiben der Startzeit          [3]
echo 4. Beenden von %ProgName%                                            [4]
echo.
set /p "input="  
	if "%input%" EQU "1" set "MenuOption=1" & goto :MenuSet1  
	if "%input%" EQU "2" set "MenuOption=2" & goto :MenuSet2  
	if "%input%" EQU "3" set "MenuOption=3" & goto :MenuSet3  
	if "%input%" EQU "4" set "MenuOption=4" & goto :MenuSet4  
echo.
echo   --------mistake: [%input%]--------------------------------------------------
echo   Incorrect input                                 Select [1] [2] [3] [4]
echo.
echo [%ProcessID%];Eingabefehler - Option nicht vorhanden.>>%log_file%
goto :MenuOptionen
:MenuSet1
if not exist "%RTC_FilePath%%ProgName%_TEMP_*.cmd" (  
	echo %MessageID%;%MenuOption%;Option steht nicht zur Verpfuegung.
	echo [%ProcessID%];%MessageID%;%MenuOption%;Fehleingabe durch Benutzer.>>%log_file%
	goto :MenuOptionen
	)
setlocal enabledelayedexpansion
for /R %RTC_FilePath% %%I in (%ProgName%_TEMP_*.cmd) do (
	set "RunProcess=%%~I"  
	del %%I
	set "ShortName=!RunProcess:%RTC_FilePath%%ProgName%_TEMP_=!"  
	set "RunProcess=!ShortName:.cmd=!"  
	echo %MessageID%;%MenuOption%;[!RunProcess!] wurde geloescht.
	echo [%ProcessID%];%MessageID%;%MenuOption%;[!RunProcess!] wurde geloescht.>>%log_file%
	)
setlocal disabledelayedexpansion
echo %MessageID%;%MenuOption%;%ProgName% wird automatisch beendet.
echo %MessageID%;%MenuOption%;Eintragung der geloeschten Startzeiten in die Logdatei "%log_file%".  
echo [%ProcessID%];%MessageID%;%MenuOption%;%ProgName% wurde automatisch beendet.>>%log_file%
goto :Exit
:MenuSet2
if not exist "%RTC_ProcFile%" (  
	echo %MessageID%;%MenuOption%;Option steht nicht zur Verpfuegung.
	echo [%ProcessID%];%MessageID%;%MenuOption%;Fehleingabe durch Benutzer.>>%log_file%
	goto :MenuOptionen
	)
if exist "%RTC_ProcFile%" (  
	del %RTC_ProcFile%
	echo %MessageID%;%MenuOption%;[%ProcessID%] wurde geloescht.
	echo [%ProcessID%];%MessageID%;%MenuOption%;[%ProcessID%] wurde geloescht.>>%log_file%
	echo %MessageID%;%MenuOption%;%ProgName% wird automatisch beendet.
	echo %MessageID%;%MenuOption%;Eintragung der geloeschten Startzeit in die Logdatei "%log_file%".  
	echo [%ProcessID%];%MessageID%];%MenuOption%;%ProgName% wurde automatisch beendet.>>%log_file%
goto :Exit
	)
:MenuSet3
if not exist "%RTC_ProcFile%" (  
	echo %MessageID%;%MenuOption%;Option steht nicht zur Verpfuegung.
	echo [%ProcessID%];%MessageID%;%MenuOption%;Fehleingabe durch Benutzer.>>%log_file%
	goto :MenuOptionen
	)
if exist "%RTC_ProcFile%" (  
	echo %MessageID%;%MenuOption%;%ProgName% wird fortgesetzt und Startzeit ueberschrieben.
	echo %MessageID%;%MenuOption%;Eintragung der ueberschriebenen Startzeit in die Logdatei "%log_file%".  
	echo [%ProcessID%];%MessageID%;%MenuOption%;%ProgName% wird fortgesetzt und Startzeit ueberschrieben.>>%log_file%
	call :GetTime
	goto :WriteProcess
	)
:MenuSet4
echo %MessageID%;%MenuOption%;%ProgName% wird durch Benutzer beendet.
echo %MessageID%;%MenuOption%;Eintragung erfolgt in die Logdatei "%log_file%".  
echo [%ProcessID%];%MessageID%;%MenuOption%;%ProgName% wurde durch Benutzer beendet.>>%log_file%
goto :Exit


:Reference
echo.
echo.
echo TIP:
echo Die Batch "%~f0"  
echo wurde ohne Startarameter ausgefuehrt. Fuer die Berechnung
echo der Laufzeit wird das Skript INNERHALB der Batch verwendet.
echo -----------------------------------------------------------
echo.
echo.
goto :eof

:Help
echo.
echo.
echo.
echo  HILFE:
echo  Diese Batch "%ProgName%.cmd" berechnet die Laufzeit eines  
echo  Skriptes. Wird die Batch ohne Parameter ausgefuehrt,
echo  muss sich dieses Skript innerhalb dieser Batch befinden. Der
echo  Bereich fuer das Skript ist entsprechend gekennzeichnet.
echo  Mit gesetzten Parameter muss diese Batch aus einem externen
echo  Skript aufgerufen werden. Der Parameter "-S" speichert die  
echo  Startzeit in nachfolgender Datei.
echo  "%RTC_ProcFile%"  
echo  Die Batch wird beendet und das zu berechnende Skript laeuft
echo  ab. Mit dem Parameter "-E" wird diese Batch wiederholt   
echo  aufgerufen. Die gespeicherte Startzeit wird ausgelesen,
echo  die Laufzeit berechnet und angezeigt. Mit Startparameter wird
echo  das Ergebnis in nachfolgender Datei geloggt.
echo  "%log_file%"  
echo  Zum Abschluss wird die Datei mit der Startzeit geloescht.
echo  ANMERKUNG:
echo  Ist %ProgName% noch nicht geladen, kommt es in einigen Faellen
echo  zu unerwarteten Ergebnissen. Ein einfaches
echo   call %ProgName%.cmd^>NUL
echo  am Anfang des zu messenden Skriptes behebt diese Koriositaet.
echo.
echo.
echo  SYNTAX:
echo  [Batchname] [-Parameter] [@ProcessID]
echo  Batchname     = Name der dieser Batch
echo  Parameter: -C = Listet Prozesse und stellt ein Menue
echo             -E = Beendet Laufzeitzeitberechnung
echo                  (Startzeit muss gespeichert sein)
echo                  gilt fuer externes Skript
echo             -H = Ruft diese Hilfe auf.
echo             -S = Start der Batch (speichert nur die Startzeit)
echo                  gilt fuer externes Skript
echo  ProcessID     = Identifikator der Laufzeitberechnung, dient zur
echo                  Bezeichnung der Logs, darf keine Leerzeichen haben.
echo                  Ohne ProcessID wird kein Log geschrieben.
echo.
pause
echo.
echo  HINWEIS:
echo  Grundsaetzlich gilt:
echo  - Der Startparameter bestimmt die Verwendung der Batch
echo    (externe, interne Berechnung, Hilfe oder Kontrolle)
echo  Die ProzessID identifiziert den Prozess und regelt das Log.
echo  Die Logdatei befindet sich immer im Verzeichnis dieser Batch.
echo  Siehe hierzu die Standardeinstellung:
echo  set "log_file=%~dp0%ProgName%.log"  
echo  
echo  - Keine ID - kein Log - keine Mehrfachberechnungen
echo.
echo  Diese Batch benoetigt bei externen Aufruf und Fehl- Eingaben
echo  Schreibrechte in dem Verzeichis in dem sie ausgefuehrt wird.
echo.
echo  Startzeit:        -^> Bezeichnet den Anfang der Berechnung
echo  Endzeit:          -^> Bezeichnet das Ende der Berechnung
echo  Dauer:            -^> Differenz aus Ende-Anfang
echo.
pause
echo.
echo  MEHRFACHBERECHNUNGEN
echo  Kreuzungen von Berechnungen sind moeglich. Dabei gilt folgendes:
echo  - Jede Laufzeitberechnung die innerhalb einer aktiven Laufzeitberechnung
echo    gestartet wird, benoetigt eine eigene ProcessID.
echo  - Werden die Laufzeitberechnungen innerhalb eines Skriptes verschachtelt,
echo    addiert sich die Abweichung. Ein direkter Vergleich ist nicht mehr objektiv.
echo.
echo  Verschachtelung von Berechnungen:
echo      -----------------------------------------
echo      @echo off
echo      echo ...
echo.
echo      call %ProgName%.cmd -S @ScriptTime
echo      :: Start einer verschachtelten Berechnung
echo      echo ...
echo.
echo      call %ProgName%.cmd -S @Snippet01
echo      :: Laufzeitberechnung "@Snippet01" 
echo      echo ...
echo      call %ProgName%.cmd -E @Snippet01
echo      echo ...
echo.
echo      call %ProgName%.cmd -S @Snippet02
echo      :: vergleichbar mit "@Snippet01" 
echo      echo ...
echo      call %ProgName%.cmd -E @Snippet02
echo      echo ...
echo.
echo      :: Ende der verschachtelten Berechnung
echo      call %ProgName%.cmd -E @ScriptTime
echo      goto eof
echo      -----------------------------------------
echo.
pause
echo.
echo  BEISPIELE:
echo  call %ProgName%.cmd -S @time01
echo    Startet die Batch aus einer externen Datei mit ID "time01".  
echo    Setzt den Anfang der Berechnung, speichert "process".  
echo.
echo  call %ProgName%.cmd -E @time01
echo    Startet die Batch aus einer externen Datei mit ID "time01".  
echo    Berechnet die abgelaufene Zeit und loescht "process".  
echo.
echo  %ProgName%.cmd -C
echo    Listet alle ueber Schalter [-C] angelegten Prozesse und.
echo    stellt ein Menue zur Verfuegung. Dieser Vorgang wird
echo    grundsaetzlich geloggt
echo.
echo  %ProgName%.cmd @time01
echo    Startet die Batch von der Konsole mit ID "time01".  
echo    Berechnet die Laufzeit des IN DER BATCH liegenden Skriptes.
echo    Ohne Startparameter wird keine Startzeit gespeichert. Das Log
echo    erfolgt erst nach der Berechnung. 
echo.
echo  %ProgName%.cmd
echo    Startet die Batch von der Konsole ohne ID.
echo    Berechnet die Laufzeit des IN DER BATCH liegenden Skriptes.
echo    Fuehrt die Batch ohne Schreibprozesse aus. Die ermittelten Daten
echo    werden auf dem Bildschirm ausgegeben.
echo.
echo.
goto :Exit


:Exit
popd
endlocal
goto :eof


:StartRunTimeSkript
:: Startmarke der Laufzeitberechnung
:: ... Skriptbereich optional
::----------------------------------------------------

REM Skriptbereich zum Testen der Laufzeit

::----------------------------------------------------
:: beendet Laufzeitskript als Subroutine
:: ... Der nachfolgende Befehl darf nicht entfernt werden.
goto :eof
aktualisiert am 27.11.2012


back-to-topAnwendung

Immer wenn es nicht zügig vorangeht wird geschraubt, gestöpselt, aufgerüstet und weniger in den Code geschaut. Manchmal sind es einfach nur Zeilenumbrüche oder missratene Datenausgaben. Zum Vergleichen des Codes mit Alternativen, bedarf es Werkzeuge. Zwei davon sind ein Laufzeitrechner und eine Routine zur Berechnung der Schleifen. Beide sind im Anwendungsbeispiel enthalten.
„RunTimeCalc“ läßt mit folgenden Schritten einfach in das Testskript einbauen.
1. Einbindung in die Umgebung des Testskriptes
set "log_file=%~dp0%~n0.log"  
set „RunTimeCalc=Drive:\Path zu RunTimeCalc“
call %RunTimeCalc%>NUL
Wird die Variable %log_file% im Testskript verwendet, schreibt RunTimeCalc bei gesetztem @prozessnamen die Messergebnisse in das Logfile des Testskriptes.
„set RunTimeCalc=...“ setzt die Variable zum Aufruf des Tools. Wird der Computer neu gestartet und RunTimeCalc das erste mal ausgeführt wird manchmal die erste Messung verzögert. Innerhalb der Routine kann dieses nur mit Verlust an Performance verhindert werden. Daher ist der bessere Weg ein blinder Aufruf mit „call“
2. Starten der Messung mit Schalter „-S“
call %RunTimeCalc% -S @Name-des-Prozesses
Es sind nur Buchstaben ohne Umlaute, Zahlen und keine Leerzeichen erlaubt.
Jeder Prozess muss einen eindeutigen Namen besitzen
3. Beenden der Messung mit Schalter „-E“
call %RunTimeCalc% -E @Name-des-Prozesses
Der Prozessname muss identisch mit dem Namen bei Schalter „-S“ sein.

Hinweis
RunTimeCalc besitzt eine Fehlerroutine und ein Protokollsystem. Fluch und Segen. Der zu testende Code sollte vollständig ausführbar sein. Meldet sich RunTimeCalc mit einem Menü, liegt ein Fehler vor. Der Laufzeitrechner gibt einen Hinweis. RunTimeCalc testet nur Zeit, nicht den Code.

back-to-topAnwendungsbeispiel
Es kommt der Tag, da zählt nur das kleinste Gemeinsame zwischen Windows. Bislang ist das noch cmd.exe.

back-to-topSchreibrechte prüfen
Es sollen die Schreibrechte des aktuellen Users im Arbeitsverzeichnis rekursiv ermittelt werden. Ein hervorragendes Beispiel zum Einsatz einer Laufzeitberechnung. Diese soll helfen, performanten Code zu finden. Bei Vergleichen zwischen den Ausgaben von „icacls“ und „whoami“ spielt dieses Thema keine Rolle. Der schlichte Entwurf endet in einer Kathastrophe irgendwo zwischen Unix und Microsoft. Die Beispieldatei, beinhaltet den Entwurf und dessen Ueberarbeitung sowie die gesamte Vergleichsroutine

back-to-topPermWrite
Sucht nach Schreibberechtigung des angemeldeten Benutzers an Dateien und Verzeichnissen, gibt bei erfolgloser Suche eine Ziel-weisende Mitteilung aus und bei Versagen eine Fehlermeldung.
Ablauf
  • Speichert den angemeldeten User und seine Relationen (Zugehoerigkeit) in eine Listen-Variable
  • Gibt alle erreichbaren Verzeichnisse rekursiv und Dateien aus
  • Liest Dateiberechtigungen aus
  • Formatiert „LF“ zu „CR LF“
  • Formatiert Datenbrei
  • Filtert nach Schreibberechtigung
  • Vergleicht „icacls“- Ausgabe mit Listen-Variable
  • Trefferanzahl kann mit interaktiven Match- Counter gesteuert werden
  • Fehlermeldungen werden nach Priorität ausgegeben

Priorität wie folgt:
1. keine Berechtigung
2. keine Schreibberechtigung
3. keine Schreibberechtigung für aktuellen User

back-to-topPermFile
Ablauf
  • Gibt alle Dateien aus Verzeichnissen mit Berechtigung aus
  • Verarbeitet gefundene Dateien mit "icacls"
  • Ermittelt den angemeldeten User und seine Relationen (Zugehoerigkeit)
  • Vergleicht Ausgaben von "icacls" und "whoami"
  • Erzeugt Fehlermeldung bei fehlenden Schreibrechten

back-to-topAnwendungsbeispiel "PermWrite" Vergleich "PermFile" (Code)

:Environment
@echo off
setlocal
pushd %~dp0
setlocal enabledelayedexpansion
	set "file_path=F:\Public\Projects\WWW\testbasis\Test"  
	set "log_file=%~dp0%~n0.log"  
	set "TimeStamp=%date%;%time%"  
:Tools
	set "RunTimeCalc=F:\Public\Projects\WWW\testbasis\script-local\runtime\RunTimeCalc.cmd"  
	call %RunTimeCalc%>NUL


:Routine
call :PermWrite
call :Entwurf


:EXIT
setlocal disabledelayedexpansion
popd
endlocal
goto :eof	



:PermWrite
echo.
echo ================================================================================
echo PermWrite V01 - Schreibrechte des aktuellen Users an Verzeichnis, Datei pruefen
echo ================================================================================
call %RunTimeCalc% -S @PermWrite-V01

for /f "delims=, tokens=1,2" %%a in ('whoami /user /fo csv /nh') do (  
	set /a USERab+=1
	set ID_User=%%a,USER,%%b
	set ID_User=!ID_User:"=!  
	)
set "NamesList="  
for /f "delims=, tokens=1" %%c in ('echo !ID_User!^& whoami /groups /fo csv /nh') do (  
	set /a NAMEcd+=1
	set Names=%%c
	set Names=!Names:"=!  
	set NamesList=!NamesList!#!Names!#;
	)
echo.
echo %USERDOMAIN%\%USERNAME% - bitte warten. Die Routine arbeitet ...
echo.
:: Trefferanzahl n+1; nicht fuer normale "for %%I" 
set match=
for /f "tokens=*" %%a in ('dir %file_path% /b /s') do (  
	set /a N_a+=1
	set Match_d=
	set Warn=
	set set Prot_b=& set Prot_c=& set Prot_d=
	set Prot_a=a
	for /f "tokens=* usebackq" %%b in (`icacls "%%a"`) do (  
		set /a N_b+=1
		if "!Match_d!" LEQ "!match!" (  
			set B=%%b
			set B=!B:%%a =!
			set B=!B:^(=[!
			set B=!B:^)=]!
			if "%%b" EQU "%%a " set Warn=b  
			set Prot_b=b
			for /f "delims=:" %%c in ('echo !B!^|findstr /E /L "F] M] W]"') do (  
				set /a N_c+=1
				set Prot_c=c
				for /f "tokens=*" %%d in ('echo %NamesList%^|Findstr /I /C:"#%%c#"') do (  
					set /a N_d+=1
					set /a Match_d+=1
					::echo %%c
					set Prot_d=d
					)				
				)
			)
		)
	if "!Prot_b!" NEQ "b" (  
		echo ERRROR;Error;"icacls" Abfrage nicht moeglich mit "...\%%~nxa".  
		echo %TimeStamp%;ERRROR;Error;"icacls" Abfrage nicht moeglich mit "%%a".>>%log_file%  
		)
	if "!Warn!" EQU "b" (  
		echo NOTICE;Warn;Keine Rechte definiert fuer "...\%%~nxa".  
		echo %TimeStamp%;NOTICE;Warn;Keine Rechte definiert fuer "%%a".>>%log_file%  
		)
	if "-!Prot_b!-!Warn!-!Prot_c!-!Prot_d!-" EQU "-b----" (  
		echo NOTICE;Warn;Kein Schreibzugriff definiert auf "...\%%~nxa".  
		echo %TimeStamp%;NOTICE;Warn;Kein Schreibzugriff definiert auf "%%a".>>%log_file%  
		)
	if "-!Prot_b!-!Warn!-!Prot_c!-!Prot_d!-" EQU "-b--c--" (  
		echo NOTICE;Tip;USER "%USERNAME%" besitzt keine Schreibrechte an "...\%%~nxa".  
		echo %TimeStamp%;NOTICE;Tip;USER "%USERNAME%" besitzt keine Schreibrechte an "%%a".>>%log_file%  
		)
	)
if "!Prot_a!" EQU "" (  
	echo ERROR;Error;:PermWrite kann nicht ausgefuehrt werden.
	echo ERROR;Tip;Pruefen "icacls", "whoami" oder "%file_path%".  
	echo %TimeStamp%;ERROR;Error;:PermWrite kann nicht ausgefuehrt werden.>>%log_file%
	echo %TimeStamp%;ERROR;Tip;Pruefen "icacls", "whoami" oder "%file_path%".>>%log_file%  
	)
echo.
echo %N_a% Dateien und Verzeichnisse geprueft.

call %RunTimeCalc% -E @PermWrite-V01

for %%I in (N_a N_b N_c N_d) do (
	if "!%%I!" EQU "" set %%I=0  
	set /a Schleifenzahl+=!%%I!
	)
echo.
echo Dateien, Verzeichnisse ^= %N_a%^|Tokens Rechte ^= %N_b%^|Schreibrechte ^= %N_c%^|Uebereinstimmung ^= %N_d%
echo Schleifenzahl gesamt ^= %Schleifenzahl%
goto :eof

::###########################################

:Entwurf
echo.
echo ================================================================================
echo PermFile ENTWURF              Schreibrechte des aktuellen Users an Datei pruefen
echo Kurz, uebersichtlich, langsam und falsch
echo ================================================================================
call %RunTimeCalc% -S @Entwurf-PermFile

for /r %file_path%\ %%Z in ("*") do (  
	set /a FOR_Z+=1
	set stop=
	for /f "tokens=* usebackq" %%a in (`icacls "%%Z"`) do (  
		set /a FOR_a+=1
		for /f %%b in ('whoami /user /groups /fo table /nh') do (  
			if "!stop!" NEQ "s" (  
			set /a FOR_b+=1
			for /f "tokens=*" %%c in ('echo %%a^|findstr /e "F) M) W)"^|findstr /i "%%b"') do (  
				set /a FOR_c+=1
				set stop=s
				))
			)
		)
	if "!stop!" EQU "" echo USER "%USERNAME%" besitzt keine Schreibrechte an "...\%%~nxZ".  
	)
echo.
echo %FOR_Z% Dateien geprueft.

call %RunTimeCalc% -E @Entwurf-PermFile

for %%I in (FOR_Z FOR_a FOR_b FOR_c) do (
	if "!%%I!" EQU "" set %%I=0  
	set /a Schleifenzahl_E+=!%%I!
	)
echo.
echo Dateien ^= %FOR_Z%^|Datei Rechte ^= %FOR_a%^|Namen ^= %FOR_b%^|Uebereinstimmung ^= %FOR_c%
echo Schleifenzahl gesamt ^= %Schleifenzahl_E%
goto :eof

angenehmes Testen wünscht
Viewfinder

Content-Key: 188502

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

Printed on: April 26, 2024 at 18:04 o'clock