I'm writing a bash script that should restart a running process. I'm able to kill a process using the process name (pcm.exe). How ever, when i want to start the process, i want it to get the pcm.exe location from the earlier running process. This is because i don't know exactly where the program is located on different systems.
I have the following script:
wmic process where "name='pcm.exe'" get ExecutablePath /FORMAT:LIST
#taskkill /f /im pcm.exe >nul
#timeout /t 10 /nobreak >nul
#start h:/pandora/pcm.exe >nul
wmic successfully gets the PCM location:
ExecutablePath=H:\Pandora\PCM.exe
But how can i pass the response to a string and run #start (the path)?
TL;DR -
Use the set command
Details:
setlocal EnableDelayedExpansion
set "zTargetImage=notepad.exe"
set "zBinLocation=0"
for /f "skip=2 tokens=2 delims=," %%A in ('wmic process where "name='!zTargetImage!'" get ExecutablePath^,ThreadCount /format:csv 2^>^&1') do (
set "zBinLocation=%%A"
)
taskkill /f /im !zTargetImage! >nul 2>&1
timeout /t 2 /nobreak >nul
if not "!zBinLocation!"=="0" (
start "" "!zBinLocation!" >nul
)
Related
I am writing a windows batch script that will Install a service. If its already running, then I am stopping and deleting the service and then installing the service again.
I am facing a peculiar behavior. When the service is already running, and when I am running the below batch file, the service gets installed again, but it fails to start. When I reboot the system, and start the service, it gets started.
How to solve this start service issue without rebooting computer. I also added taskkill /f /PID to kill the process libertyserver.exe.
This is my code : test.bat. I am running test.bat from command line.
test.bat:
#echo off
setlocal
#echo off
set JAVA_SERVICE_EXE=libertyserver.exe
...
....
set SERVICE_DISPLAY_NAME="%LIBERTY_SERVICE_NAME%"
set SERVICE_DESCRIPTION="%LIBERTY_SERVICE_NAME%"
echo Stopping and Deleting existing services
for /F "tokens=3 delims=: " %%H in ('sc query %SERVICE_NAME% ^| findstr "STATE" ') do (
if /I "%%H" EQU "RUNNING" (
sc stop %SERVICE_NAME% >nul 2>&1
timeout /t 30 /nobreak >nul 2>&1
)
sc delete %SERVICE_NAME% >nul 2>&1
timeout /t 30 /nobreak >nul 2>&1
)
for /f "tokens=2" %%a in ('tasklist^|find /i "libertyserver.exe"') do (taskkill.exe /f /pid %%a >nul 2>&1)
echo Installing liberty profile %SERVICE_NAME%
set INSTALL_SERVICE_COMMAND=%DAEMON_EXEC% //IS//%SERVICE_NAME% --Startup=manual --DisplayName=%SERVICE_DISPLAY_NAME% --Description=%SERVICE_DESCRIPTION% ++DependsOn=Tcpip --LogPath=%LOG_PATH% --StdOutput=auto --StdError=auto --StartMode=exe --StartPath=%SERVER_START_COMMAND_PATH% --StartImage=%SERVER_START_COMMAND% --StartParams=start#SIServer --StopMode=exe --StopPath=%SERVER_STOP_COMMAND_PATH% --StopImage=%SERVER_STOP_COMMAND% --StopParams=stop#SIServer
%INSTALL_SERVICE_COMMAND%
echo Installed liberty profile %SERVICE_NAME%
i have to find a processid for a specific jar file and kill it using the same batch file.
C:\Users\k9>ps -ef|grep java
10892 5648 0 Mar 08 con 0:02 "C:\Program Files\Java\jdk1.7.0_51\bin\java" com.mkwebappserver.MainClass -app CATMkWebAppServerConsole\apps_list.html -autobui
13060 7828 0 09:42:28 con 49:05 java -Djsse.enableSNIExtension=false -Djava.util.logging.config.file=..\config\log.properties -classpath "../extlib/*";..\extlib\mysql-connector-
here i want to find pid of config\log.properties file and kill it using the batch file.
This is how I "find" and kill Adobe Acrobat
::Close acrobat and any opened PDF
taskkill /im acrobat.exe /t /f
timeout 2
/im for imagename, or program you're targeting
/t terminates the specified process and any child process which were started by it
/f Forcefully terminate the process
The most flexible way to detect a pid by its command line (where your jar should be included) is with wmic. To process the wmic result and assign it to a variable you'll need FOR /F :
#echo off
for /f "useback tokens=* delims=" %%# in (
`wmic process where "CommandLine like '%%my_jar.jar%%' and not CommandLine like '%%wmic%%' " get ProcessId /Format:Value`
) do (
for /f "tokens=* delims=" %%a in ("%%#") do set "%%a"
)
echo %processId%
echo taskkill /pid %processId% /f
Where you should change '%%my_jar.jar%%' with your jar name.To kill the process you'll have to delete the echo word in the last line. It is echoed in order to check if the correct process id is handled.
For more info:
WMIC
FOR /F
WQL
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.
I am trying to get a song to play in the background of Windows, after a little looking I found this:
#echo off
set file=RRLJ.mp3
( echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "%file%"
echo Sound.Controls.play
echo do while Sound.currentmedia.duration = 0
echo wscript.sleep 100
echo loop
echo wscript.sleep (int(Sound.currentmedia.duration^)+1^)*1000) >sound.vbs
start /min sound.vbs
This works well for starting the song but I have no way of stopping it from a .bat file. The only way I found to cut it short is to open task manager and close it from the processes.
I have tried:
taskkill /im wscript.exe
But I keep getting something in the window saying:
Success: Sent termination sidnal to the process "wscript.exe" with PID 185448
but the music continues to play until I manually end it with task manager
I'd use /T switch (Tree kill): terminates the specified process and any child processes which were started by it.
Here is a script to find ProcessID to terminate exactly needed process only using PID:
#ECHO OFF >NUL
for /F "usebackq tokens=*" %%G in (
`wmic process where "CommandLine like '%%sound.vbs%%' AND Caption like '%%script.exe%%'" get ProcessID/value ^|find /I "="`
) do (
rem echo %%G
for /F "tokens=2 delims==" %%H in ("%%~G") do echo taskkill /T /F /PID %%H
)
Note taskkill command is echoed merely... Remove echo when debugged.
This work for me, and is only one line.
Taskkill /IM "wscript.exe" /F>nul 2>&1
In Windows batch scripting there is start command which starts a new process.
Is it possible to get PID of the process just started?
This is an old post but I think that it worth to share the following 'easy to use' solution which works fine nowadays on Windows.
Start multiple processes in parallel:
start "<window title>" <command will be executed>
Example:
start "service1" mvn clean spring-boot:run
start "service2" mvn clean spring-boot:run
Obtain the PID of the processes (optional):
tasklist /V /FI "WindowTitle eq service1*"
tasklist /V /FI "WindowTitle eq service2*"
Kill the processes:
taskkill /FI "WindowTitle eq service1*" /T /F
taskkill /FI "WindowTitle eq service2*" /T /F
You can in batch but not directly per say. You need to either parse the output of tasklist.exe or use wmic.exe. Both require you to know what you just started which of course you will.
Using tasklist.exe:
for /F "TOKENS=1,2,*" %a in ('tasklist /FI "IMAGENAME eq powershell.exe"') do set MyPID=%b
echo %MyPID%
To use this in a batch script double up the percent signs.
Using wmic.exe:
for /f "TOKENS=1" %a in ('wmic PROCESS where "Name='powershell.exe'" get ProcessID ^| findstr [0-9]') do set MyPID=%a
echo %MyPID%
If there are processes already running with the same name, you first need to get a list of the current pids, than start your local process(es) and then check the pids again. Here is a sample code that starts 3 process and kills them at the end (specifically the ones started locally):
#echo off
set PROCESSNAME=notepad.exe
::First save current pids with the wanted process name
setlocal EnableExtensions EnableDelayedExpansion
set "RETPIDS="
set "OLDPIDS=p"
for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='%PROCESSNAME%'" get ProcessID ^| findstr [0-9]') do (set "OLDPIDS=!OLDPIDS!%%ap")
::Spawn new process(es)
start %PROCESSNAME%
start %PROCESSNAME%
start %PROCESSNAME%
::Check and find processes missing in the old pid list
for /f "TOKENS=1" %%a in ('wmic PROCESS where "Name='%PROCESSNAME%'" get ProcessID ^| findstr [0-9]') do (
if "!OLDPIDS:p%%ap=zz!"=="%OLDPIDS%" (set "RETPIDS=/PID %%a !RETPIDS!")
)
::Kill the new threads (but no other)
taskkill %RETPIDS% /T > NUL 2>&1
endlocal
you can try with
wmic process call create "notepad"
which will return the pid of the created process.
Processing this with FOR
setlocal
set "ReturnValue="
set "ProcessId="
for /f "eol=} skip=5 tokens=1,2 delims=;= " %%a in ('wmic process call create "notepad"') do (
set "%%a=%%b"
)
echo %ReturnValue%
echo %ProcessId%
endlocal
PowerShell can be used for this:
powershell -executionPolicy bypass -command "& {$process = start-process $args[0] -passthru -argumentlist $args[1..($args.length-1)]; exit $process.id}" notepad test.txt
echo Process ID of new process: %errorlevel%
This is the code that i use to get a PID
for /f "tokens=2 delims=," %%a in ('tasklist /FO CSV ^| findstr /I /C:"entertheprocess.here"') do (
echo PID:%%a
)
#ECHO OFF
SETLOCAL EnableDelayedExpansion EnableExtensions
::
::weil es mehrere Sessions für UltraCompare gleichzeitig geben kann, es wird hier die
::neueste Instanz (soeben gestartet) ermittelt, um später mit ProcessId diese Instanz
::aktivieren zu können...
::
set "CreationDate="
set /A "ProcessIdUltraCompare=0"
::
set /A "lineno=0"
FOR /F %%T IN ('Wmic process where^(Name^="uc.exe"^) get CreationDate^|sort /r') DO (
set /A lineno+=1
rem echo %%T
rem echo !lineno!
if !lineno! equ 2 (
rem ECHO %%T
set CreationDate=%%T
rem echo !CreationDate!
set /A "lineno=0"
FOR /F %%P IN ('Wmic process where^(CreationDate^="!CreationDate!"^) get ProcessId') DO (
set /A lineno+=1
rem echo %%P
if !lineno! equ 2 (
set "ProcessIdUltraCompare=%%P"
rem echo ProcessIdUltraCompare=!ProcessIdUltraCompare!
goto :l_pid_uc_got
)
)
)
)
:l_pid_uc_got
echo ProcessIdUltraCompare=!ProcessIdUltraCompare!
PAUSE