CMD TaskKill Explorer.exe slows down opening File Explorer - windows

I'm Running Windows 8.1 and am having issues restarting Explore.exe with CMD. The code work in regards to killing explorer.exe and starting it up again,but once these 2 codes run I can't use windows explorer at all. To fix this issues I have to restart Explorer.exe in Task Manager by right clicking and selecting restart. I can also end the process and go up to 'run new task' and entering explorer.exe. If I don't I can't open any folder,copy, or move any files. I can modify my script, open Firefox, and open chrome. Excel runs my macro's at the same speed.
Why does after running these 2 codes (either one) make file explorer slow to open and operate in?
My Code:
REM ---------------------
REM TaskKill EXPLORER.EXE
REM ---------------------
FOR /F "tokens=1,2" %%A IN (
'TaskList /FI "IMAGENAME eq EXPLORER.EXE"'
) DO (
IF /I "%%A" == "EXPLORER.EXE" (
TaskKill /F /IM %%A >nul
)
)
REM ------------------
REM START EXPLORER.EXE
REM ------------------
START EXPLORER.EXE >NUL
The Same problem happens if I run this code
REM ---------------------
REM TaskKill EXPLORER.EXE
REM ---------------------
Taskkill /F /IM EXPLORER.EXE >nul
REM ------------------
REM START EXPLORER.EXE
REM ------------------
START EXPLORER.EXE >NUL
PS I HAVE THE REGISTRY SEPARATE PROCESS AS 1 TO DISTINGUISH BETWEEN EXPLORER.EXE THE SHELL AND THE FILE EXPLORER

SET /A RunningCount=0
rem ----------------------------------------------------------
rem FIGURE OUT HOW MANY WIN EXPLORER.EXE'S THAT ARE RUNNING
rem ----------------------------------------------------------
FOR /F "tokens=1,2,5,6" %%A IN (
'TASKLIST /FI "IMAGENAME eq EXPLORER.EXE"'
) DO (
IF /I "%%A" == "EXPLORER.EXE" (
SET /A RunningCount=!RunningCount!+1
SET "WinExplorerMemory!RunningCount!=%%C"
SET "WinExplorerPID!RunningCount!=%%B"
)
)
rem ----------------------------------------------------------
rem THIS REMOVES THE COMMA'S IN THE STRING
rem ----------------------------------------------------------
IF "%WinExplorerMemory1%" NEQ "" SET WinExplorerMemory1=%WinExplorerMemory1:,=%
IF "%WinExplorerMemory2%" NEQ "" SET WinExplorerMemory2=%WinExplorerMemory2:,=%
rem ----------------------------------------------------------
rem FIGURES OUT WHICH PID IS USING THE MOST MEMORY
rem ----------------------------------------------------------
IF "%RunningCount%" EQU "1" (
SET WinExplorerShellPID=%WinExplorerPID1%
) ELSE (
IF [%WinExplorerMemory1%] GTR [%WinExplorerMemory2%] (
SET WinExplorerShellPID=%WinExplorerPID1%
TASKKILL /F /PID %WinExplorerPID2% >NUL
)
IF [%WinExplorerMemory2%] GTR [%WinExplorerMemory1%] (
SET WinExplorerShellPID=%WinExplorerPID2%
TASKKILL /F /PID %WinExplorerPID1% >NUL
)
)

Related

Windows batch user input variable is not set within an if

I have a program which has following flow. Problem is the windows batch file doesn't properly checks errorlevel and doesn't set KILLSTS value. Could you please let me know what's wrong with this program and how to fix this?
Ask user to open an exe
if Yes
check exe is running or not
if running, ask user whether to close that exe
if yes close exe
run the exe
else
exit
Here is the sample batch file.
#ECHO OFF
#REM SETLOCAL ENABLEEXTENSIONS
SET /P AREYOUSURE="Open Spring STS [y/n]>"
set AREYOUSURE=%AREYOUSURE:~0,1%
ECHO AREYOUSURE=%AREYOUSURE:~0,1%
IF /I %AREYOUSURE% == N (
SET /A errno^|=%ERROR_OTHERCOMMAND_FAILED%
echo Existing Batch
EXIT /B %errno%
)
SETLOCAL
#REM SET KILLSTS=Y
tasklist /fi "IMAGENAME eq STS.exe" |find ":" > nul
ECHO Error %errorlevel%
IF %errorlevel% neq 0 (
SETLOCAL
SET /P KILLSTS="Spring STS is running. Kill STS Process [y/n]>"
echo KILLSTS %KILLSTS%
set KILLSTS=%KILLSTS:~0,1%
echo KILLSTS AFTER SUBSTR %KILLSTS%
IF /I %KILLSTS% == Y TASKKILL /f /im "STS.exe"
ENDLOCAL
)
START "" "C:\sts-bundle\sts-3.8.3.RELEASE\STS.exe"
I am getting below error
You need to learn how to properly format if statements.
You are formatting them as:
IF /I %KILLSTS% == Y TASKKILL /f /im "STS.exe"
When they should be formatted as:
if /i "%KILLSTS%"=="Y" (TASKKILL /f /im STS.exe)
The formatting doesn't really matter as such in simple batch files, but it's best to use the correct syntax which can handle special characters such as SPACES, AMPERSANDS, QUOTES, PIPE for when more complex variables are involved.
Updated script:
#ECHO OFF
#REM SETLOCAL ENABLEEXTENSIONS
SET /P "AREYOUSURE=Open Spring STS [y/n]>"
set "AREYOUSURE=%AREYOUSURE:~0,1% "
echo "AREYOUSURE=%AREYOUSURE:~0,1%"
IF /I "%AREYOUSURE%"=="N" (
SET /A errno^|=%ERROR_OTHERCOMMAND_FAILED%
echo Existing Batch
EXIT /B %errno%
)
SETLOCAL
#REM SET KILLSTS=Y
tasklist /fi "IMAGENAME eq STS.exe" | find ":" > nul
ECHO Error %errorlevel%
IF "%errorlevel%" neq "0" (
call :escapeexpansion
)
START "" "C:\sts-bundle\sts-3.8.3.RELEASE\STS.exe"
exit /b
:escapeexpansion
SETLOCAL
SET /P "KILLSTS=Spring STS is running. Kill STS Process [y/n]>"
echo KILLSTS %KILLSTS%
set "KILLSTS=%KILLSTS:~0,1%"
echo KILLSTS AFTER SUBSTR %KILLSTS%
IF /I "%KILLSTS%"=="Y" TASKKILL /f /im "STS.exe"
ENDLOCAL
goto :EOF
The entire structure seems wrong to me; as well as pointlessly using SET /P instead of CHOICE.
#ECHO OFF
TASKLIST /FI "IMAGENAME eq STS.exe"|FIND ":">NUL 2>&1&&GOTO ASKIF
CHOICE /M "Spring STS is running. Kill STS Process"
IF ERRORLEVEL 2 GOTO ENDIT
TASKKILL /F /IM "STS.exe"
TIMEOUT 3 /NOBREAK>NUL
:ASKIF
CHOICE /M "Open Spring STS"
IF ERRORLEVEL 2 GOTO ENDIT
START "" "C:\sts-bundle\sts-3.8.3.RELEASE\STS.exe"
:ENDIT
Echo=Exiting Batch
TIMEOUT 3 /NOBREAK>NUL

Get commandline of process and taskkill

I need some help here.
I am currently trying to kill any process that isn't in a whitelist (command line) like so, however it is not working.:
#echo off
setlocal
set "whitelist=DcomLaunch RPCSS LocalServiceNetworkRestricted netsvcs LocalService LocalSystemNetworkRestricted NetworkService LocalServiceAndNoImpersonation taskhostex cmd dwm conhost services smss SearchIndexer Isass Explorer csrss conhost cftmon"
for /f "tokens=2 delims=," %%I in (
'wmic process get executablepath^,status /format:csv ^| find "\"'
) do (
set "proc=%%~I"
setlocal enabledelayedexpansion
set /p "=%%~I: "<NUL
wmic path win32_process get CommandLine | findstr /i "%whitelist%" >NUL && (
echo OK
) || (
echo UNACCEPTABLE!
taskkill /im "%%~nxI" /f
)
endlocal
)
wmic path win32_process get CommandLine | findstr /i "%whitelist%"
In above command, findstr would look for a match in entire wmic output so it will find a match always. For instance, at least cmd would match because wmic runs in a cmd window. Next commented code snippet should work however it gives different results if elevated (run as administrator).
set "whitelist=DcomLaunch RPCSS LocalServiceNetworkRestricted netsvcs LocalService LocalSystemNetworkRestricted NetworkService LocalServiceAndNoImpersonation taskhostex cmd dwm conhost services smss SearchIndexer Isass Explorer csrss conhost cftmon"
rem add windows VITAL processes !!! incomplete !!!
set "whitelist=svchost ctfmon lsass winlogon %whitelist%"
for /f "tokens=2,3 delims=," %%I in (
'wmic process get executablepath^,ProcessID^,status^,WindowsVersion /format:csv ^| find "\"'
) do (
set "proc=%%~I"
set "procID=%%~J"
setlocal enabledelayedexpansion
rem debugging: set /p "=%%~I: "<NUL
rem debug try: wmic path win32_process where "ProcessID=%%J" get Name 2>NUL | findstr /i "%whitelist%">NUL 2>&1 && (
rem debug try: wmic path win32_process get executablepath 2>NUL | findstr /i "!proc:/=//!">NUL 2>&1 && (
wmic path win32_process where "ProcessID=%%J" get CommandLine 2>NUL | findstr /i "%whitelist%">NUL 2>&1 && (
rem suppress "No Instance(s) Available" report in above line: 2>NUL
echo OK %%J "%%~I"
) || (
rem UNWANTED: here come inactive processes "cmd", "wmic", "find"
rem and maybe more ones that were active in FOR %%I execution time
rem (but loop continues); let's filter them here:
tasklist /FI "PID eq %%J" /NH | find "%%J" >NUL 2>&1 && (
echo NO %%J "%%~I"
rem taskkill /PID "%%~J" /f
) || (
echo XX %%J "%%~I"
rem inactive at the moment
)
)
endlocal
)
Essential Processes needed to run Windows (next list may be a bit out of date):
… here is a list of the essential processes that Windows needs to run
correctly.
System Idle Process
explorer.exe
taskmgr.exe
spoolsv.exe
lsass.exe
csrss.exe
smss.exe
winlogon.exe
svchost.exe – (There will be a few of these)
services.exe
By shutting down anything other than these processes, stand alone
Windows should operate fine, however if any of these processes are
shutdown, Windows will start to become unstable or unusable.

how do I kill all cmd.exe except the one currently running from batch?

The past few days I have been working on a script that I thought would be rather easy but it seems not, and I do understand why. My problem is how to get around it.
The batch script I need explained:
I have a script that runs in cmd.exe that does a bunch of things like moving a huge amount of files from a location to another. Lets call it
movefile.cmd. This script works, but happens to stop sometimes (very rarely - lets not go into why and that script). Its important that this script always runs, so my idea here was to create a batch that exits cmd.exe and then re-opens the script each hour or so. Lets call this script restartcmd.bat
Sounds perfectly easy as I could do this:
#echo off
:loop
start c:\script\movefile.cmd
Timeout /nobreak /t 3600
Taskkill cmd.exe
goto loop
But obviously this doesn't work because my new script also runs in cmd.exe, so it would kill this process as well.
What I've tried:
So I made a copy of cmd.exe and renamed it into dontkillthis.exe. I run dontkillthis.exe and then open the restardcmd.bat from dontkillthis.exe - this works perfectly! But I need to be able to just dobbleclick my script instead of doing that. Why? Because its supposed to be as easy as possible and I want my restartcmd.bat to be in my startup folder.
I've been looking at the ideas of getting the exact process ID of cmd.exe and shutting that so that my dontkillthis.exe will remain, but I can't seem to nail it. Tried all thats written in here how to kill all batch files except the one currently running , but I can't get it to work.
I'm not sure if I'm being confused or if it actually is a bit hard to do this.
I'd really appreciate some help here.
Best Regards
MO
first you'll need the PID of the current CMD instance. The topic has been discussed here . I will offer you my solution - getCmdPID.bat
and here's the script (getCmdPID should in the same directory ):
#echo off
call getCmdPID
set "current_pid=%errorlevel%"
for /f "skip=3 tokens=2 delims= " %%a in ('tasklist /fi "imagename eq cmd.exe"') do (
if "%%a" neq "%current_pid%" (
TASKKILL /PID %%a /f >nul 2>nul
)
)
Normally with the following command I should be able to find the PID. Unfortunately this is not the case.
title exclude &tasklist /NH /v /fo csv /FI "WINDOWTITLE ne exclude*" /FI "IMAGENAME eq cmd.exe" /FI "STATUS eq running"
So to achieve my goal, I used the following command:
FIND /I "exclude" 1>NUL
#echo off
TITLE exclude
(for /f "usebackq tokens=*" %%a in (`tasklist /NH /v /fo csv /FI "IMAGENAME eq cmd.exe" /FI "STATUS eq running"`) do (
(
echo %%a | FIND /I "exclude" 1>NUL
) || (
for /f "usebackq tokens=2 delims=," %%i in (`echo %%a`) do (
echo TASKKILL /PID %%~i /f
)
)
)
)>_output-taskill.txt
TYPE _output-taskill.txt
Another approach to kill all the processes in a single line is to use filters on the command taskkill with filters should look like:
TASKKILL /F /FI "PID ne XXXX" /FI "IMAGENAME eq cmd.exe" /IM cmd.exe
eq (equal)
ne (not equal)
gt (greater than)
lt (lesser than)
#echo off
TITLE exclude
(for /f "usebackq tokens=2 delims=," %%a in (`tasklist /NH /v /fo csv /FI "IMAGENAME eq cmd.exe" /FI "STATUS eq running" ^| FIND /I "exclude"`) do (
echo TASKKILL /F /FI "PID ne %%~a" /FI "IMAGENAME eq cmd.exe" /IM cmd.exe
)
)>_output-taskill.txt
TYPE _output-taskill.txt
I have found a solution that utilizes text files to keep track of all previous PIDs the bat file has had. It attempts to kill them silently and then adds the current PID to the list after.
If you don't want it to kill the old, already existing process, simply replace the line that has "taskkill" with whatever you were wanting to do with it.
(might require you to run as admin in order to have permissions to kill the duplicate process. see permission elevation code below for optional implementation if you don't want to have to run as admin every time.)
#echo off
set WorkingDir=%cd%
if exist MostRecentPID.txt ( del "PIDinfo.txt" /f /q ) > nul
cd ..\..\..\..\..\..\..
title mycmd
tasklist /v /fo csv | findstr /i "mycmd" > %WorkingDir%\PIDinfo.txt
set /p PIDinfo=<%WorkingDir%\PIDinfo.txt
REM below, the 11 means get substring starting a position 11 with length of 5 characters. The tasklist command gives a long and verbose value so this will get just the PID part of the string.
set PID5chars=%PIDinfo:~11,5%
set PID4chars=%PIDinfo:~11,4%
if exist PreviousPIDs.txt (
for /F "tokens=*" %%A in (PreviousPIDs.txt) do taskkill.exe /F /T /PID %%A > nul 2>&1
goto CheckIfFourCharPID
)
:CheckIfFourCharPID
if %PID4chars% gtr 8100 (
for /F "tokens=*" %%A in (PreviousPIDs.txt) do taskkill.exe /F /T /PID %%A > nul 2>&1
echo %PID4chars% >> "PreviousPIDs.txt"
) else (
echo %PID5chars% >> "PreviousPIDs.txt"
)
Explanation: (warning: very technical)
-This solution gets a substring of the tasklist command to get just the PID. There will not be a PID for cmd.exe that is greater than 18100 so check if PID4chars is greater than 8100 so we know if it's a 4 digit or 5 digit number
case 1: a 5 digit PID like 17504 has a PID5chars val 17504 and a PID4chars val of 1750, so we add PID5chars to the text files of PIDs to kill
case 2: a 4 digit PID like 8205 has a PID5chars val of 8205" and a PID4chars val of 8205, so we add PID4chars to the text files of PIDs to kill
case 3: a 4 digit PID like 4352 has a PID5chars val of 4352" and a PID4chars val of 4352, so we add PID4chars to the text files of PIDs to kill
OPTIONAL PERMISSION ELEVATION CODE
(put this at the top of your bat file and it will auto-run it as admin.)
#echo off
setlocal DisableDelayedExpansion
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
cd ..\..\..\..\..\..\..\..
if exist %cd%\Temp (
set temp=%cd%\Temp
goto vbsGetPrivileges
)
if exist %cd%\Windows\Temp (
set temp=%cd%\Windows\Temp
goto vbsGetPrivileges
)
set temp=%cd%
:vbsGetPrivileges
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:CheckIfRunningAsAdmin
net session >nul 2>&1
if %ERRORLEVEL% == 0 (
goto gotPrivileges
) else ( goto ElevatePermissions )
:ElevatePermissions
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " " >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
"%SystemRoot%\System32\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & pushd .
cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul & shift /1)
net session >nul 2>&1
if %ERRORLEVEL% == 0 (
goto Continue
) else (
REM unable to elevate permissions so tell user to run file as admin manually
echo Please re-run this file as administrator. Press any key to exit...
pause > nul
goto Exit
)
:Continue
<insert rest of code here>
It would be much better to get the PID of your movefile.cmd. If you can edit it, add a title MyMoveFileProcess and get it's PID with
for /f "tokens=2" %%i in ('tasklist /v ^|find "MyMoveFileProcess"') do set PID=%%i
Then you can kill it with taskkill /pid %pid%
Instead of changing your movefile.cmd, you can also just start it with an title:
start "MyMoveFileProcess" c:\script\movefile.cmd
A couple of lines will help you achieve this:
TITLE exclude
taskkill /IM cmd.exe /FI "WINDOWTITLE ne exclude*"

Bat File that will read the server file and then restart based on output of server file

So far I've been trying to make a continuous .bat file that will start the server file, read every line that comes down and if the response "Server has become unresponsive" then the bat will close the file and re-open(this needs to be done every hour or so and I'm not always at the computer)
I do believe this is the correct code but I need to double check with some tech-savy minds to see if it's correct.
#echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%A in (`"findstr rust_server/n ^^ "`) do (
set "myVar=%%A"
call :processLine myVar
)
goto :eof
:processLine
SETLOCAL EnableDelayedExpansion
set "line=!%1!"
set "line=!line:*:=!"
echo(!line!
Find /I /V "Unresponsive for 10"
taskkill /fi "WindowTitle eq rust_server*"
start /d "C:\Rust Server" rust_server.exe
ENDLOCAL
goto :eof
Any ideas/suggestions would be greatly appreciated.
#Echo off
Title SERVER RESTARTER (place with your rust_server exe)
color 1f
SET n=0
:Loop
SET /A n=n+1
echo Server Restarter
echo -----Restart Server Batch VERSION-----
taskkill /IM rust_server.exe
echo Opening rust_server.exe server again
rust_server.exe
if %n% EQU 60 (
exit
) Else if %n% LEQ 24 (
Goto Loop

from a batch file, how can I wait for a process to exit, after calling taskkill.exe?

I want to write a batch file that updates a DLL that is in use by a running process, a regular application.
To do this, the plan is to stop the process, copy the DLL to the required location, then restart the process.
I know I can try to kill a process with taskkill. How can I make sure the process has fallen over and died, after I shoot it?
Here's what I used. It's a subroutine in a batch file.
set tasklist=%windir%\System32\tasklist.exe
set taskkill=%windir%\System32\taskkill.exe
-------------------------------------------------------
:STOPPROC
set wasStopped=0
set procFound=0
set notFound_result=ERROR:
set procName=%1
for /f "usebackq" %%A in (`%taskkill% /IM %procName%`) do (
if NOT %%A==%notFound_result% (set procFound=1)
)
if %procFound%==0 (
echo The process was not running.
goto :EOF
)
set wasStopped=1
set ignore_result=INFO:
:CHECKDEAD
"%windir%\system32\timeout.exe" 3 /NOBREAK
for /f "usebackq" %%A in (`%tasklist% /nh /fi "imagename eq %procName%"`) do (
if not %%A==%ignore_result% (goto :CHECKDEAD)
)
goto :EOF
-------------------------------------------------------
To use it from within a batch file, do like this:
call :STOPPROC notepad.exe
Full example:
set tasklist=%windir%\System32\tasklist.exe
set taskkill=%windir%\System32\taskkill.exe
-------------------------------------------------------
:STOPPROC
set wasStopped=0
set procFound=0
set notFound_result=ERROR:
set procName=%1
for /f "usebackq" %%A in (`%taskkill% /IM %procName%`) do (
if NOT %%A==%notFound_result% (set procFound=1)
)
if %procFound%==0 (
echo The process was not running.
goto :EOF
)
set wasStopped=1
set ignore_result=INFO:
:CHECKDEAD
"%windir%\system32\timeout.exe" 3 /NOBREAK
for /f "usebackq" %%A in (`%tasklist% /nh /fi "imagename eq %procName%"`) do (
if not %%A==%ignore_result% (goto :CHECKDEAD)
)
goto :EOF
-------------------------------------------------------
:MAIN
call :STOPPROC notepad.exe
call :STOPPROC Skype.exe
You'll notice lines that have all dashes - that's not a legal syntax for a batch file of course. But, those lines are never reached, because of the use of GOTO statements, so the syntax is never evaluated. Therefore those lines aren't a problem.

Resources