alme123
Goto Top

Batch verbraucht zu viel RAM

Hallo zusammen,

ich habe folgendes Problem mit diesem BatchScript:

@echo off
title Batch
:start
ping localhost -n 1 >nul
tasklist /v | findstr /c:"cmd.exe" | findstr /v /c:"Batch" >"%temp%\allcmds.tmp"  
if errorlevel 1 goto start
:: Weiterer unwichtiger Code...

Dieses soll die laufenden cmd Prozesse (außer den eigenen) finden und in eine Datei schreiben.
Dies funktioniert tadellos. Leider verbraucht das Script zu viel RAM (20-40% bei mir)

Könnte man das Script dazubringen, weniger RAM zu verspeisen?
Ein höhrerer Ping würde das Script zu sehr stoppen, es soll nämlich gestartete cmd-Prozesse schnellstmöglich weiterverarbeiten.

Vielen Dank für eure Mühe im Vorraus,

Alme123

Content-ID: 206328

Url: https://administrator.de/forum/batch-verbraucht-zu-viel-ram-206328.html

Ausgedruckt am: 25.12.2024 um 01:12 Uhr

rubberman
rubberman 12.05.2013 um 13:04:34 Uhr
Goto Top
Hallo Alme123,

in deinem anderen Thread wird WMIC dazu benutzt um von der PID der cmd.exe auf den Speicherort der Batchdatei zu schließen. Welchen Sinn macht dann eigentlich deine allcmds.tmp? Ist es nicht sinnvoller alles mit WMIC in einem Rutsch abzuwickeln?

Grüße
rubberman
Alme123
Alme123 12.05.2013 um 13:23:21 Uhr
Goto Top
@rubberman

du hast Recht,

in einem Rutsch wäre es besser. Leider kenne ich wmic erst seit heute und komm damit auch nicht klar.

Der bisherige Code:
:start
@echo off & setlocal ENABLEDELAYEDEXPANSION
title 123
ping localhost -n 2 >nul
tasklist /v | findstr /c:"cmd.exe" | findstr /v /c:"123" >"%temp%\123.tmp"  
if errorlevel 1 goto start
set "Zeile="  
set "Var="  
set "Nach=cmd.exe                       "  
set "Vor= Console"  
>"%temp%\123.vbs" echo Set a=WScript.Arguments:Set rE=New RegExp:rE.Pattern=a(1)^&"(.+)"^&a(2):For Each M In rE.Execute(a(0)):WScript.Echo M.SubMatches(0):Next  
for /f "delims=" %%i in ('findstr /rc:"%Nach%.*%Vor%" "%temp%\123.tmp"') do set "Zeile=%%i"  
if not defined Zeile goto start
for /f "delims=" %%i in ('cscript //nologo //T:15 "%temp%\123.vbs" "%Zeile%" "%Nach%" "%Vor%"') do set "Var=%%i"  
for /f "tokens=2*" %%i in ('"wmic process where ProcessId='%var%' get CommandLine"') do set "ExePath=%%~j"  
set "ExePath=%ExePath:~1%"  
set "ExePath=%ExePath:~0,-5%"  


Könntest du vlt. einen Denkansatz schreiben?

Danke im Vorraus,

Alme123
rubberman
rubberman 12.05.2013 um 13:39:37 Uhr
Goto Top
Hallo Alme123,

mein Ansatz sähe etwa so aus:
@echo off &setlocal

REM Eigene PID finden, um später diesen und die Tochterprozesse (WMIC) auszufiltern
setlocal EnableDelayedExpansion
set "uid="  
for /l %%i in (1 1 128) do (set /a "bit=!random!&1" &set "uid=!uid!!bit!")  
for /f "tokens=2 delims==" %%i in (  
  'WMIC Process WHERE "Name='cmd.exe' AND CommandLine LIKE '%%!uid!%%'" GET ParentProcessID /value'  
) do for /f %%j in ("%%i") do (endlocal &set "PID=%%j")  

REM finde alle cmd.exe Prozesse (außer diesem und dessen Tochterprozesse), hole die CommandLine Eigenschaft
for /f "tokens=1* delims==" %%i in (  
  'WMIC Process WHERE "Name='cmd.exe' AND NOT ProcessID=%PID% AND NOT ParentProcessID=%PID%" GET CommandLine /value 2^>nul'  
) do for /f "delims=" %%k in ("%%j") do (  
  set "CmdLn="  
  set "BatPath="  
  set "CmdLn=%%k"  
  REM Extrahiere den Batch Pfad
  setlocal EnableDelayedExpansion
    set "CmdLn=!CmdLn:cmd /c "=!"  
    for %%l in (!CmdLn!) do (
      if "!!"=="" endlocal  
      if not defined BatPath if /i "%%~xl"==".bat" set "BatPath=%%~l"  
    )
  setlocal EnableDelayedExpansion
    echo !BatPath!
  endlocal
)
pause

Grüße
rubberman
Alme123
Alme123 12.05.2013 um 15:08:10 Uhr
Goto Top
@rubberman

dein Denkansatz funktioniert, eine letzte Frage:
Wie kann ich das Script erweitern, sodass ich die PID des !BatPath!-Prozesses bekomme?

Vielen Dank für deine Mühe,

Alme123
rubberman
rubberman 12.05.2013 aktualisiert um 16:59:36 Uhr
Goto Top
Hallo Alme123,

ich weiß nicht wie die Ausgabe aussehen soll, aber vielleicht so:
@echo off &setlocal

REM Eigene PID finden, um später diesen und die Tochterprozesse (WMIC) auszufiltern
setlocal EnableDelayedExpansion
set "uid="  
for /l %%i in (1 1 128) do (set /a "bit=!random!&1" &set "uid=!uid!!bit!")  
for /f "tokens=2 delims==" %%i in (  
  'WMIC Process WHERE "Name='cmd.exe' AND CommandLine LIKE '%%!uid!%%'" GET ParentProcessID /value'  
) do for /f %%j in ("%%i") do (endlocal &set "PID=%%j")  

REM finde alle cmd.exe Prozesse (außer diesem und dessen Tochterprozesse), hole die CommandLine und ProcessID Eigenschaften
set "ProcessID="  
for /f "delims=" %%i in (  
  'WMIC Process WHERE "Name='cmd.exe' AND NOT ProcessID=%PID% AND NOT ParentProcessID=%PID%" GET CommandLine^,ProcessID /value 2^>nul'  
) do for /f "delims=" %%j in ("%%i") do (  
  set "%%j"  
  if defined ProcessID (
    setlocal EnableDelayedExpansion
      echo !ProcessID! !BatPath!
    endlocal
    set "ProcessID="  
    set "BatPath="  
  ) else (
    REM Extrahiere den Batch Pfad
    setlocal EnableDelayedExpansion
      set "CommandLine=!CommandLine:cmd /c "=!"  
      for %%l in (!CommandLine!) do (
        if "!!"=="" endlocal  
        if not defined BatPath if /i "%%~xl"==".bat" set "BatPath=%%~l"  
      )
  )
)
pause

Grüße
rubberman

EDIT: Zeile 22 eingefügt
Alme123
Alme123 12.05.2013 um 18:45:00 Uhr
Goto Top
@rubberman

vielen Dank für deine Mühe, dein Script funktioniert.
Die Frage ist geschlossen.

Alme123

[Theard closed]
Alme123
Alme123 13.05.2013 um 20:19:22 Uhr
Goto Top
@rubberman

eine allerletzte Frage:

Ich habe ein paar Dateien, dessen Prozesse ausgeschlossen werden sollen.
Sie sind in prozess.txt gespeichert und sollen nicht weiterverarbeitet werden, sondern "goto action" ausführen.

Mein Denkansatz war (hinter deinem Script):

findstr "%BatPath%" "prozess.txt" >nul  
if errorlevel 0 goto action

leider nimmt er aber beim wechseln zum Script (goto :start (Zeile 2: ":start)) immer nur den ersten Prozess.

Meine 2 Ideen:

1. Script(teil) in eine for-schleife programmieren, und mit Parametern weitergeben (call :weiter %ProcessID% "%BatBatch%")

2. Scriptteil neuschreiben und meinen Denkansatz einbauen


Vielen Dank im Vorraus,

Alme123
rubberman
rubberman 13.05.2013 um 21:10:58 Uhr
Goto Top
Hallo Alme123,

der ganze Spaß wird ja bereits in einer Schleife ausgeführt. Ein GOTO Label aus der Schleife heraus wird unweigerlich zum Abbruch der Schleife führen. Ein CALL :Label hingegen wird hier wohl die bessere Variante sein.
@echo off &setlocal

REM Eigene PID finden, um später diesen und die Tochterprozesse (WMIC) auszufiltern
setlocal EnableDelayedExpansion
set "uid="  
for /l %%i in (1 1 128) do (set /a "bit=!random!&1" &set "uid=!uid!!bit!")  
for /f "tokens=2 delims==" %%i in (  
  'WMIC Process WHERE "Name='cmd.exe' AND CommandLine LIKE '%%!uid!%%'" GET ParentProcessID /value'  
) do for /f %%j in ("%%i") do (endlocal &set "PID=%%j")  

REM finde alle cmd.exe Prozesse (außer diesem und dessen Tochterprozesse), hole die CommandLine und ProcessID Eigenschaften
set "ProcessID="  
set "BatPath="  
for /f "delims=" %%i in (  
  'WMIC Process WHERE "Name='cmd.exe' AND NOT ProcessID=%PID% AND NOT ParentProcessID=%PID%" GET CommandLine^,ProcessID /value 2^>nul'  
) do for /f "delims=" %%j in ("%%i") do (  
  set "%%j"  
  if defined ProcessID (
    setlocal EnableDelayedExpansion
      echo !ProcessID! !BatPath!
      findstr /ic:"!BatPath!" "prozess.txt" >nul && call :action  
    endlocal
    set "ProcessID="  
    set "BatPath="  
  ) else (
    REM Extrahiere den Batch Pfad
    setlocal EnableDelayedExpansion
      set "CommandLine=!CommandLine:cmd /c "=!"  
      for %%l in (!CommandLine!) do (
        if "!!"=="" endlocal  
        if not defined BatPath if /i "%%~xl"==".bat" set "BatPath=%%~l"  
      )
  )
)
pause
goto :eof

:action
setlocal DisableDelayedExpansion
echo ****** Mach was mit %ProcessID% und "%BatPath%"! ******  
endlocal
goto :eof
Grüße
rubberman
Alme123
Alme123 19.05.2013 um 19:55:44 Uhr
Goto Top
@rubberman

danke rubberman, leider brauche ich dein Script noch einmal. Etwas anders:
Dein Script soll (unabhängig von den anderen) alle Prozesse heraussuchen die NICHT in der "prozess.txt" (s. Zeile 21) vorhanden sind. Mein Versuch
findstr /ivc:"!BatPath!" "prozess.txt" >nul && call :action  
hat leider nicht geholfen, das Script nimmt immer den Prozess, obwohl er in der Datei steht (Parameter v).

Kannst du (oder auch ein anderer) mir bitte weiterhelfen?

Alme123
rubberman
rubberman 19.05.2013 aktualisiert um 20:33:15 Uhr
Goto Top
Hallo Alme123,


Grüße
rubberman
Alme123
Alme123 19.05.2013 um 20:49:25 Uhr
Goto Top
Halle rubberman,

vielen Dank für deine Hilfe, diese Frage ist jetzt endgültig geklärt.

Alme123