Board logo

标题: [其他] [已解决]批处理怎样把名字过长的进程终止掉? [打印本页]

作者: bigcool    时间: 2012-6-26 16:26     标题: [已解决]批处理怎样把名字过长的进程终止掉?

本人是新人,以前只用过一些简单的批处理,对于 for 、if、tokens等命令从来没有接触过,现在想好好学一下。
但是看教程,实在是看不进去,看一会就瞌睡了,所以就找一些感兴趣的批处理逐行来分析含义,想通过这个方法来了解批处理!
本人基础实在是差劲,所以有些命令即使找到了相应的解说,还是不太了解!

大家看一下hanyeguxing老大的一个批处理,这个是我现在非常需要用的,虽然它解决了我的问题,但我想了解一下这个批处理的运行原理!
  1. @echo off&setlocal enabledelayedexpansion
  2. for /F "tokens=1,2" %%i in ('Tasklist /nh') do (call:hanye "%%i"
  3. if !n! gtr 20 ntsd -c q -p %%j)
  4. exit
  5. :hanye
  6. set "i=%~1"&set n=0
  7. :guxing
  8. if not "!i:~%n%,1!"=="" set/a n+=1&goto:guxing
复制代码
前四行我基本上已经理解了,但后面set "i=%~1"&set n=0和if not "!i:~%n%,1!"=="" set/a n+=1实在是不能理解透,希望论坛上的老大们可以帮助我,给我一详细的解释,谢谢了!!



我找到的关于上面用到的一些命令的解释,帮我看看是不是正确!
Tasklist               显示进程
Tasklist /nh         显示进程,但不显示标题
tokens=1,2        提取第一列和第二列
call:hanye          调用hanye的命令
set                     设置的意思
gtr                     大于
ntsd -c q -p       利用进程的PID来结束进程
%%                  批处理变量引导符(命令符下需要一个,批处理中需要两个)
:hanye              批处理标签引导符(这行开始时hanye的批处理内容)
&                      符号允许在一行中使用2个以上不同的命令,当第一个命令执行失败将不影响第2个命令的执行。
&&                   符号也是允许在一行中使用2个以上不同的命令,当第一个命令执行失败后后续的命令将不会再被执行。
%%i                第一个变量
%%j                第二个变量
if                     如果的意思
"=="               用if检测字符串是否相等的时候,后面用的不是“=”,而是“==”
作者: poter    时间: 2012-6-26 18:36

这个批处理貌似不完整。按照字面的意思就是把名字过长的进程终止掉

但其中:guxing标签根本就没有调用过

应该改成这样

@echo off&setlocal enabledelayedexpansion
for /F "tokens=1,2" %%i in ('Tasklist /nh') do (call:hanye "%%i"
call:guxing
if !n! gtr 20 ntsd -c q -p %%j
set n=0)
exit
:hanye
set "i=%~1"
:guxing
if not "!i:~%n%,1!"=="" set/a n+=1&goto:guxing
作者: weichenxiehou    时间: 2012-6-26 18:41

解释还是基本都对,如果真想学批处理,还是不建议采用这样的方式,有些命令和一些基础的批处理概念还是需要系统性学习的。
作者: weichenxiehou    时间: 2012-6-26 18:43

回复 2# poter
这样的修改是不必要的,call调用程序段只有直到文件尾或明确的goto :eof才会返回。
作者: poter    时间: 2012-6-26 18:46

回复 4# weichenxiehou


    你不说,我以前还真没注意到这个问题,谢谢啊!
作者: bigcool    时间: 2012-6-26 18:54

本帖最后由 bigcool 于 2012-6-26 18:57 编辑

谢谢各位大大的回复,我也知道这样的学习方法有很大的弊端,但是我基础很差又急需这个批处理,所以才采取这样的方法!
这个批处理虽然解决了结束长文件名程序的问题,但是还缺少个监测长文件名程序是否运行的功能,我理想中的批处理是:开机调用该批处理,监测进程中是否存在长文件名程序,如果发现就结束它,没有发现就继续监测,直到发现并结束该进程后再退出!
我主要就是想理解长文件名进程这个变量,然后自己做个监测程序,看来还有好长的路要走啊!!
作者: bigcool    时间: 2012-6-26 18:59

我要结束的那个程序不会二次启动,所以只要能结束它就好了,恩,这是一个垃圾广告进程,还是必须运行其父程序的,所以只能结束它。
作者: cutebe    时间: 2012-6-26 21:00

http://bbs.bathome.net/viewthread.php?tid=14852
其中第三点:3.调用一个内部函数(标签)
应该会对你有帮助。
作者: CrLf    时间: 2012-6-26 21:38

本帖最后由 CrLf 于 2012-6-26 21:39 编辑

那个代码看起来是老寒初学时搞出来的...博客里的?
修改如下:
  1. @echo off
  2. for /F delims^=^" %%i in ('Tasklist /nh /fo csv') do (
  3.   rem 以双引号为分隔符,解析以 csv 格式输出的进程列表
  4.   set ProName=%%i
  5.   rem 获取进程名,存储于变量 ProName
  6.   setlocal enabledelayedexpansion
  7.   rem 开启变量延迟
  8.   if "!ProName:~20!" neq "" ntsd -c q -p "!ProName!"
  9.   rem 如果变量 ProName 长于 20 字符,则调用 ntsd 命令结束它
  10.   endlocal
  11.   rem 与 setlocal 对应的命令,在此处还用于关闭变量延迟
  12. )
  13. pause
复制代码

作者: bigcool    时间: 2012-6-26 21:44

本帖最后由 bigcool 于 2012-6-27 10:33 编辑

是2010年论坛里的,我翻出来了!现在依然很好用!
作者: apang    时间: 2012-6-26 22:16

回复 9# CrLf

用进程名的话,应该是ntsd -c q -pn "process.exe" 吧?
作者: bigcool    时间: 2012-6-26 23:23

那个代码看起来是老寒初学时搞出来的...博客里的?
修改如下:
CrLf 发表于 2012-6-26 21:38



单独运行没有问题,如果进程里有长文件名的进程,一运行会死机!或出现

这个应该是语法错了吧,定位到PID上了,而不是程序名称?
作者: bigcool    时间: 2012-6-27 10:35

回复  CrLf

用进程名的话,应该是ntsd -c q -pn "process.exe" 吧?
apang 发表于 2012-6-26 22:16



   
我改成你这个,成功运行了!!
作者: bigcool    时间: 2012-6-27 11:28

本帖最后由 bigcool 于 2012-6-27 11:29 编辑

这个能做成个循环检测吗?我尝试者弄了一下,弄不成,看来还得从基础循序渐进得学!!可我现在急用了,哪位大大帮我做个循环检测,没发现就一直检测或者检测多长时间,发现了就结束进程并关闭批处理!
作者: forfiles    时间: 2012-6-27 14:06

回复 14# bigcool
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set kill=0
  4. :loop
  5. for /F "tokens=1,2" %%i in ('Tasklist /nh') do (
  6.     call :hanye "%%i"
  7.     if !n! gtr 20 (
  8.         ntsd -c q -p %%j
  9.         set kill=1
  10.     )
  11. )
  12. if !kill! equ 0 (
  13.     ping -n 10 127.1 >nul
  14.     goto :loop
  15. )
  16. goto :eof
  17. :hanye
  18. set "i=%~1"
  19. set n=0
  20. :guxing
  21. if not "!i:~%n%,1!"=="" (
  22.     set /a n+=1
  23.     goto :guxing
  24. )
复制代码

作者: forfiles    时间: 2012-6-27 14:12

回复 9# CrLf


    支持版主的思路,希望楼主能够采用。因为有的进程名是包含空格的,顶楼的代码无法处理这个异常。
作者: CrLf    时间: 2012-6-28 00:29

回复 16# forfiles


    除此,还有一种出错的可能是进程名过长,若使用 tasklist 默认的 table 格式查看进程列表,所得进程名将止于 25 字节长度...




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2