tasklist.exe 中的过滤器不使用通配符?

Posted

技术标签:

【中文标题】tasklist.exe 中的过滤器不使用通配符?【英文标题】:filter in tasklist.exe does not take wildcards? 【发布时间】:2012-07-29 13:43:31 【问题描述】:

操作系统:Windows XP、Windows 7 64 位。

我们有一些相当庞大的 cmd 脚本用于一些日常构建过程。这些脚本产生了许多其他(窗口)进程。有一个控制 cmd 脚本,一个小的简单脚本,它启动主 cmd 脚本。小控制脚本的目的是在主脚本或其任何子脚本失败的情况下进行清理。这很容易完成:主脚本及其所有子脚本都有以唯一标识符开头的窗口标题。当控制脚本确定主脚本及其所有子脚本应该已完成时,它使用任务列表查找任何挂起的进程的窗口,通过:

tasklist.exe /FI "WINDOWTITLE eq UniqueIdentifier*"

这一切在 XP 中运行良好。现在进入Windows7 64位。在这里,如果主 .cmd 脚本或任何其他 .cmd shell 窗口尝试通过

title UniqueIdentifier Followed By Descriptive Text

Windows7 64 位在标题前添加其他文本(特别是“管理员:”或类似内容)。不能依赖前面的文本。所以现在我们要使用

tasklist.exe /FI "WINDOWTITLE eq *UniqueIdentifier*"

失败并显示错误消息“无法识别搜索过滤器”。使用我们的 UniqueIdentifier 作为后缀是行不通的:命令

tasklist.exe /FI "WINDOWTITLE eq *UniqueIdentifier"

也会导致相同的错误消息。似乎微软在过滤器中的“通配符”概念并没有超出将“*”作为终端字符的范围。哎哟。

有人有解决办法吗? Pslist 似乎不允许使用窗口标题进行过滤。

【问题讨论】:

【参考方案1】:

您可以使用 /V 选项在输出中包含窗口标题,然后将结果通过管道传递给 FIND(或 FINDSTR)以过滤结果。

tasklist /v | find "UniqueIdentifier"
tasklist /v | findstr /c:"UniqueIdentifier"

如果使用 FINDSTR,那么我建议使用 /C 选项,以便您可以在搜索字符串中包含空格。

如果您需要进行不区分大小写的搜索,您可能需要使用/I 选项。

【讨论】:

是的,这会起作用,谢谢(我可能会使用 grep 而不是 find 或 findstr,因为这样我就可以使用正则表达式)。但是,我没有说的是,下一步是使用taskkill杀死有问题的任务,而这里我也遇到了同样的问题。作为一个丑陋的解决方法,我可以解析来自tasklist /v | grep ... 的输出,然后反馈给taskkill,但这很丑陋。我希望有一些未记录的“这就是让过滤器正常工作的方式”。叹。不过谢谢,你的想法会奏效的。 FINDSTR 对正则表达式的支持有限,但 grep 更强大、更可靠。 非常同意。奇怪的是,在这种情况下, grep 会找到“行”,但似乎删除了行首的大部分内容,这使其无用,因此 findstr 胜出。我想知道任务列表是否在行中间放了一些奇怪的字符???? (顺便说一句,在我之前的评论中,“如何让过滤器工作”指的是任务列表中的 /FI 过滤 - 使用 grep 或 findstr 过滤是微不足道的。) 丢弃信息的不是“grep”。 tasklist 向 stderr 发送奇怪的字符。管道 2>nul 如(tasklist -v 2>nul)|grep ... 工作正常。感谢 wmz 在另一个问题中的观察。【参考方案2】:

我认为这适用于 Windows 10。这是我的 sn-p

set PROCNAME="Foobar"
tasklist /FI "IMAGENAME eq %PROCNAME%*" 2>NUL | find /I /N %PROCNAME%>NUL
if "%ERRORLEVEL%"=="0" (
    echo it is running
)

注意过滤器中的星号。

【讨论】:

【参考方案3】:

根据我的实验,taskkill 的通配符似乎只在字符串的末尾起作用,而不是在任何其他位置。我无法以一种或另一种方式从 Microsoft 找到任何关于此的文档。但是文档中的所有示例都遵循这种格式

Successful:  notepad*
Fails: notepad*.exe
Fails *notepad*

正如另一个答案中提到的,最好解析 tasklist 的输出以获得您想要的内容,而不是依赖 taskkill 相当破碎的行为。

【讨论】:

【参考方案4】:

是的,如果 * 位于所搜索的进程名称的末尾,它可以正常工作, 正如 five 所指出的那样。 以下是如何运行命令的示例:

tasklist /FI "IMAGENAME eq no*"

【讨论】:

【参考方案5】:

使用 powershell。获取进程。如果你能处理这种力量,那就更有用了。试试

get-process | where MainWindowTitle -like "*UniqueIdentifier*" | select *

【讨论】:

以上是关于tasklist.exe 中的过滤器不使用通配符?的主要内容,如果未能解决你的问题,请参考以下文章

linux中等效的Tasklist.exe

在taskkill windowtitle中的通配符

OData:通配符(startswith)过滤 url 请求中的数字(ID)字段

如何使用通配符编写vba过滤器

查询中的通配符在 Access * 和 Ansi % 之间随机切换

MQTT通配符