我正在尝试通过 Windows 命令行找出一种方法来确定某个进程是否没有父进程。
我知道所有进程在技术上都有一个由操作系统或其他程序控制的父进程,但为了简单起见,它“没有父进程”。例如,如果你打开一个资源管理器窗口,它将显示在进程探索器位于其进程树的顶部。
但是,当我对进程执行 wmic 查询时,我得到了“parentProcessPID”的 PID。当我尝试使用 tasklist 查找该 PID 时,它说无法识别该 PID。我查看了几个这样的进程,它们似乎有不同的父进程,这些父进程都无法通过 tasklist 访问。如果某个进程的父进程无法通过 tasklist 访问,这是否意味着它位于其进程树的“顶部”?
我之所以问这个问题,是因为我想区分一个单独运行的程序和作为另一个程序的子进程运行的同一个程序。
例如:
假设我进入 Windows 开始菜单并打开资源管理器窗口。然后,我打开 cmd 窗口并输入:explorer.exe
。我现在有两个 explorer.exe 进程。一个是 cmd.exe 的子进程,一个是独立进程。我希望能够通过 wmic 或 tasklist 查询找出所有独立explorer.exe
进程。因此,应该返回我通过 Windows 开始菜单启动的进程,而不是 cmd.exe 启动的进程。
我遇到的问题是每个进程都有一个父进程 ID,我不知道如何区分来自程序的父进程或来自与操作系统相关的进程的父进程。如果我能做到以下几点,那就太好了:
伪代码:
wmic process where name=explorer.exe get parentProcessID,processID
tasklist /fi "PID eq <parentProcessID>" 2>&1> log.txt
if(log.txt contains "INFO: No tasks are running which match the specified criteria."){
// Parent PID is not recognized by tasklist
// Do something
}
但我不确定我的逻辑是否正确。
答案1
我不确定如何从命令行执行此操作,但我编写此代码是为了从 PowerShell 中过滤一些与操作系统相关的进程。也许它会给你一个想法。它会跳过服务、系统和 null 拥有的项目。
gwmi win32_process |select ProcessID,ParentProcessID,Name, @{l="Username";e={$_.getowner().user}}|where {$_.Username -ne "SYSTEM"} | where {$_.Username -ne "LOCAL SERVICE"} | where {$_.Username -ne "NETWORK SERVICE"} | where {$_.Username -ne $null} |Sort-Object ProcessID | ft -AutoSize
#
输出
ProcessID ParentProcessID Name Username
--------- --------------- ---- --------
2136 3460 notepad.exe KNUCKLE-DRAGGER
2504 3460 firefox.exe KNUCKLE-DRAGGER
2792 700 dllhost.exe KNUCKLE-DRAGGER
2816 4232 conhost.exe KNUCKLE-DRAGGER
2916 3460 powershell.exe KNUCKLE-DRAGGER
3128 3460 notepad.exe KNUCKLE-DRAGGER
3180 576 taskhost.exe KNUCKLE-DRAGGER
3196 4308 vmware-tray.exe KNUCKLE-DRAGGER
3460 4392 explorer.exe KNUCKLE-DRAGGER
3644 4636 vmware-vmx.exe KNUCKLE-DRAGGER
3696 3460 mplayerc.exe KNUCKLE-DRAGGER
4636 3196 vmware.exe KNUCKLE-DRAGGER
4828 3460 notepad.exe KNUCKLE-DRAGGER