标题: [其他] [已解决]批处理怎样把名字过长的进程终止掉? [打印本页]
作者: bigcool 时间: 2012-6-26 16:26 标题: [已解决]批处理怎样把名字过长的进程终止掉?
本人是新人,以前只用过一些简单的批处理,对于 for 、if、tokens等命令从来没有接触过,现在想好好学一下。
但是看教程,实在是看不进去,看一会就瞌睡了,所以就找一些感兴趣的批处理逐行来分析含义,想通过这个方法来了解批处理!
本人基础实在是差劲,所以有些命令即使找到了相应的解说,还是不太了解!
大家看一下hanyeguxing老大的一个批处理,这个是我现在非常需要用的,虽然它解决了我的问题,但我想了解一下这个批处理的运行原理!- @echo off&setlocal enabledelayedexpansion
- for /F "tokens=1,2" %%i in ('Tasklist /nh') do (call:hanye "%%i"
- if !n! gtr 20 ntsd -c q -p %%j)
- exit
- :hanye
- set "i=%~1"&set n=0
- :guxing
- 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 编辑
那个代码看起来是老寒初学时搞出来的...博客里的?
修改如下:- @echo off
- for /F delims^=^" %%i in ('Tasklist /nh /fo csv') do (
- rem 以双引号为分隔符,解析以 csv 格式输出的进程列表
- set ProName=%%i
- rem 获取进程名,存储于变量 ProName
- setlocal enabledelayedexpansion
- rem 开启变量延迟
- if "!ProName:~20!" neq "" ntsd -c q -p "!ProName!"
- rem 如果变量 ProName 长于 20 字符,则调用 ntsd 命令结束它
- endlocal
- rem 与 setlocal 对应的命令,在此处还用于关闭变量延迟
- )
- 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 - @echo off
- setlocal enabledelayedexpansion
- set kill=0
- :loop
- for /F "tokens=1,2" %%i in ('Tasklist /nh') do (
- call :hanye "%%i"
- if !n! gtr 20 (
- ntsd -c q -p %%j
- set kill=1
- )
- )
- if !kill! equ 0 (
- ping -n 10 127.1 >nul
- goto :loop
- )
- goto :eof
-
- :hanye
- set "i=%~1"
- set n=0
-
- :guxing
- if not "!i:~%n%,1!"=="" (
- set /a n+=1
- goto :guxing
- )
复制代码
作者: forfiles 时间: 2012-6-27 14:12
回复 9# CrLf
支持版主的思路,希望楼主能够采用。因为有的进程名是包含空格的,顶楼的代码无法处理这个异常。
作者: CrLf 时间: 2012-6-28 00:29
回复 16# forfiles
除此,还有一种出错的可能是进程名过长,若使用 tasklist 默认的 table 格式查看进程列表,所得进程名将止于 25 字节长度...
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |