2015-04-01 142 views
4

過去幾天我一直在研究一個我認爲會很容易的腳本,但似乎沒有,我明白爲什麼。我的問題是如何解決它。我如何殺死所有cmd.exe,除了當前正在批量運行的cmd.exe?

批處理腳本,我需要解釋:

我在cmd.exe的,做了一堆東西,就像從一個位置移動龐大的文件量到另一個運行的腳本。讓我們叫它 movefile.cmd。這個腳本有效,但有時會停止(很少 - 不要進入爲什麼和那個腳本)。它的重要性在於此腳本始終運行,因此我的想法是創建一個批處理,該處理會退出cmd.exe,然後每小時重新打開該腳本。讓我們把這個腳本restartcmd.bat

聽起來非常容易,我能做到這一點:

@echo off 

:loop 

start c:\script\movefile.cmd 

Timeout /nobreak /t 3600 

Taskkill cmd.exe 

goto loop 

但顯然,這並不工作,因爲我的新的腳本也cmd.exe的運行,因此它會殺了這過程也是如此。

我已經試過:

所以我做了CMD.EXE的副本,並將其更名爲成dontkillthis.exe。我運行dontkillthis.exe,然後從dontkillthis.exe打開restardcmd.bat - 完美的工作!但是我需要能夠只用腳本來代替我的腳本。爲什麼?因爲它應該儘可能簡單,我希望我的restartcmd.bat位於我的啓動文件夾中。

我一直在尋找獲取cmd.exe的確切進程ID的想法,並關閉,以便我的dontkillthis.exe將保持,但我似乎無法指出它。嘗試所有寫在這裏how to kill all batch files except the one currently running,但我不能得到它的工作。

我不確定我是否感到困惑,或者實際上是否有點困難。

我真的很感謝這裏的幫助。

問候

MO

+0

骯髒的方法:創建一個'cmd'作爲'kill-me.exe',使用'start kill-me c:\ script \ movefile.cmd'然後'taskkill kill-me.exe'(這是一個快速入門。應該有更好的方法。) – anishsane 2015-04-01 11:22:53

+0

[獲取當前cmd.exe的PID](https://social.msdn.microsoft.com/Forums/vstudio/en-US/270f0842-963d-4ed9-b27d-27957628004c/what -is-the-pid-of-the-current-cmdexe),那麼'taskkill'可以選擇根據'PID!= xxx'選項來檢查'taskkill /?'。 – anishsane 2015-04-01 11:26:27

回答

6

首先,您需要當前CMD實例的PID。該主題有been discussed here。我會爲您提供我的解決方案 - getCmdPID.bat

和這裏的腳本(getCmdPID應在同一目錄下):

@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 
    ) 
) 
+1

Npocmaka,實際上(和令人驚訝的是我)工作就像一個魅力!謝啦。正是我在找什麼!發現。 :) – MadsTheMan 2015-04-07 07:45:08

0

這將是更好的讓你movefile.cmd的PID。如果你可以對它進行編輯,添加title MyMoveFileProcess,並得到它的PID與

for /f "tokens=2" %%i in ('tasklist /v ^|find "MyMoveFileProcess"') do set PID=%%i 

然後你就可以用taskkill /pid %pid%

而不是改變你的movefile.cmd,也可以只是一個標題開始它殺死它:

start "MyMoveFileProcess" c:\script\movefile.cmd 
+0

第一個代碼是一個完整的失敗 - 它列出了所有cmd.exe進程。設計從根本上是有缺陷的。 – dbenham 2015-04-01 14:29:28

+0

@dbenham是的,它確實(像我寫的)。也許我最好刪除那部分。 – Stephan 2015-04-01 14:42:22

+0

@dbenham另一方面:問題標題說「如何殺死所有cmd.exe除...」,我同意這是一個不好的方法。 – Stephan 2015-04-01 14:53:05

0

而且,只爲他人的信息。 我發現基於標題可以停止和啓動其他cmd文件,這將成爲我的問題的解決方案的另一種選擇。所以可以說movefile.cmd在腳本中有這樣一行:Title "movefile"(「」很重要)。 然後我可以在restartcmd.bat中寫taskkill /F /FI "WindowTitle eq Administrator: \"movefile"" /T :)

1

通常用下面的命令我應該可以找到PID。不幸的是,這種情況並非如此。

title exclude &tasklist /NH /v /fo csv /FI "WINDOWTITLE ne exclude*" /FI "IMAGENAME eq cmd.exe" /FI "STATUS eq running" 

因此,爲了實現我的目標,我用下面的命令: 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 

另一種方法殺死所有的進程中一行是在命令taskkill使用過濾器與過濾器應看起來像:

TASKKILL /F /FI "PID ne XXXX" /FI "IMAGENAME eq cmd.exe" /IM cmd.exe 

eq(等於)

NE(不等於)

GT(大於)

LT(較低的比)

@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 
-2

幾行會幫助你實現這一點:

TITLE exclude 
taskkill /IM cmd.exe /FI "WINDOWTITLE ne exclude*"