explorer.exe作为windows中的父进程

explorer.exe作为windows中的父进程,windows,powershell,cmd,process,child-process,Windows,Powershell,Cmd,Process,Child Process,我正在使用以下命令终止cmd中的一些任务: taskkill /f /im software* /t 它使用该IMAGENAME完成任务并终止所有任务;但是,看看它给了我什么,我看到了一些有趣的东西。请看下面: 因此,正如预期的那样,所有进程都连接到一个集中式任务PID=9068。但是,该进程也是PID=10060的子进程,它是explorer.exe的PID。此作业没有GUI。因此,我惊讶地发现它是explorer的子进程 所以,这里有一个问题:在windows的explorer.exe下会

我正在使用以下命令终止
cmd
中的一些任务:

taskkill /f /im software* /t
它使用该
IMAGENAME
完成任务并终止所有任务;但是,看看它给了我什么,我看到了一些有趣的东西。请看下面:

因此,正如预期的那样,所有进程都连接到一个集中式任务
PID=9068
。但是,该进程也是
PID=10060
的子进程,它是
explorer.exe的
PID
。此作业没有
GUI
。因此,我惊讶地发现它是
explorer
的子进程

所以,这里有一个问题:在windows的explorer.exe下会有什么样的进程

更新: 问题:如果我想避免杀死(使用
taskkill
)任何直接是explorer.exe子进程的进程,我将如何处理

这就是我目前所拥有的。首先,我们需要获取explorer.exe的
pid

然后,我正在考虑编写一个函数,该函数使用
pid
终止进程,检查其父进程,如果父进程pid是explorer.exe,则终止进程,如果不是,则终止进程。这应该发生在同一个函数中,以避免处理注释中提到的动态PID

我可以使用以下方法找到每个
pid
的父进程:

wmic process get processid,parentprocessid,executablepath|find "process id goes here")

我感谢您对编写函数的帮助。

父进程与子进程是图形、控制台还是服务应用程序无关。如果Explorer是父进程,则只表示该Explorer调用了另一个进程
CreateProcess
,或者用一个句柄替换了Explorer作为子进程的句柄


例如,如果用户双击资源管理器中的.py脚本图标,shell将查找文件关联(例如,使用接口的内部实现),并使用类似于
“C:\Windows\py.exe”“path\to\script.py”
的命令以脚本为参数执行相应的程序。如果直接执行,资源管理器将使用此命令行作为参数调用
CreateProcess
。如果是“以管理员身份运行”,Explorer将请求发送到应用程序信息服务,该服务通过
CreateProcessAsUser
创建提升的进程,并通过上述进程创建属性将Explorer设置为父进程。

父进程与子进程是否为图形无关,控制台或服务应用程序。如果Explorer是父进程,则只表示该Explorer调用了另一个进程
CreateProcess
,或者用一个句柄替换了Explorer作为子进程的句柄


例如,如果用户双击资源管理器中的.py脚本图标,shell将查找文件关联(例如,使用接口的内部实现),并使用类似于
“C:\Windows\py.exe”“path\to\script.py”
的命令以脚本为参数执行相应的程序。如果直接执行,资源管理器将使用此命令行作为参数调用
CreateProcess
。如果是“以管理员身份运行”,资源管理器将请求发送到应用程序信息服务,该服务通过
CreateProcessAsUser
创建提升的进程,通过上述进程创建属性将Explorer设置为父进程。

以下
.bat
脚本可以帮助理解父进程/子进程及其行为

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
echo "%~1%~2%~3" | findstr /I "\? \/h \-h">NUL 2>&1
if %errorlevel% EQU 0 goto :usage 

set "_explorerName=explorer.exe"
set "_NameToKill=%~1"
set "_Terminate=%~2"
set "_KillForce=%~3"

if NOT defined _NameToKill if not [%1]==[] (
  rem debugging 
  set "_NameToKill=CMD.EXE"
  rem debugging: start a child process
  start "" /MIN notepad.exe
)

for /F "tokens=1,2 delims=," %%G in ('
    TASKLIST /NH /FI "IMAGENAME eq %_explorerName%"  /FO CSV
') do (
  set "_explorerPID=%%~H"
)
ECHO checking '%_NameToKill%*' as child of %_explorerName% ^(PID=%_explorerPID%^)  
for /F "skip=1 tokens=1-3" %%G in ('
    wmic process WHERE "Name like '%_NameToKill%%%' and ParentProcessId=%_explorerPID%" get Name^,ParentProcessId^,ProcessId^,Status
') do (
  if NOT "%%H"=="" (
    echo %%G
    for /F "skip=1 tokens=1-3" %%g in ('
        2^>NUL wmic process WHERE "ParentProcessId=%%I" get Name^,ParentProcessId^,ProcessId^,Status
    ') do (
      if NOT "%%h"=="" (
        echo    ProcessId=%%i, ParentProcessId=%%h, %%g child of %%G ^(%%I^)
        if defined _Terminate (
          if /I "%%~g"=="conhost.exe" (
            rem debugging
            taskkill /PID %%i /T
          ) else (
            taskkill /PID %%i %_Terminate% %_KillForce%
          )
          echo(
        )
      )
    )
    echo    ParentProcessId=%%H, ProcessId=%%I, %%G child of %_explorerName% ^(%_explorerPID%^)
    if defined _Terminate (
      taskkill /PID %%I /T
      echo(- 
    )
  )
)
if [%1]==[] goto :usage
:endlocal
ENDLOCAL
goto :eof

:usage
  echo USAGE:
  echo %~nx0 -? ^| /? ^| /h ^| -h           this help message
  echo %~nx0                             list all childs of %_explorerName%
  echo %~nx0 ^<processName^> [/T] [/F]     list all childs of a process
  echo %~nx0 ""            [/T] [/F]     a particular test case for cmd.exe
  echo(
  echo Optional parameters /T and /F ^(or -T and -F^): see taskkill /? 
goto :endlocal
@ECHO关闭
SETLOCAL EnableExtensions DisableDelayedExpansion
回声“%1%~2%~3”| findstr/I”\?\/h \-h”>NUL 2>&1
如果%errorlevel%EQU 0转到:用法
设置“\u explorerName=explorer.exe”
设置“\u NameToKill=%~1”
设置“_Terminate=%~2”
设置“_KillForce=%~3”
如果未定义_NameToKill如果未定义[%1]=[](
rem调试
设置“\u NameToKill=CMD.EXE”
rem调试:启动子进程
启动“”/MIN notepad.exe
)
对于/F“令牌=1,2 delims=,”%%G in('
任务列表/NH/FI“IMAGENAME eq%\u explorerName%”/FO CSV
""做"(
设置“\u explorerPID=%%~H”
)
回显检查“%\u-NameToKill%*”作为%\u-explorerName%^的子项(PID=%\u-explorerPID%^)
对于/F“跳过=1令牌=1-3”%%G in('
wmic进程,其中“名称如“%\u nameTochill%%”和ParentProcessId=%\u explorerPID%”获取名称^,ParentProcessId^,ProcessId^,状态
""做"(
如果不是“%%H”==”“(
回声%%G
对于/F“跳过=1令牌=1-3”%%g in('
2^>NUL wmic进程,其中“ParentProcessId=%%I”获取名称^,ParentProcessId^,ProcessId^,状态
""做"(
如果不是“%%h”==”“(
echo ProcessId=%i,ParentProcessId=%h,%%g^(%%i^)的%%g子级
如果已定义,则终止(
如果/I“%%~g”==“conhost.exe”(
rem调试
taskkill/PID%%i/T
)否则(
taskkill/PID%%i%\u终止%\u KillForce%
)
回音(
)
)
)
echo ParentProcessId=%%H,ProcessId=%%I,%%G%\u explorerName%^(%%\u explorerId%^)的子级
如果已定义,则终止(
taskkill/PID%%I/T
回声(-)
)
)
)
如果[%1]=[]转到:用法
:endlocal
端部
后藤:eof
:用法
回声使用:
回显%nx0-?^ |/?^ |/h^ |-h此帮助消息
echo%~nx0列出%\u explorerName%的所有子项
echo%~nx0^[/T][/F]列出进程的所有子进程
echo%~nx0”“[/T][/F]cmd.exe的特定测试用例
回音(
echo可选参数/T和/F^(或-T和-F^):请参阅taskkill/?
后藤:endlocal

以下
.bat
脚本可以帮助理解父/子进程及其行为

@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
echo "%~1%~2%~3" | findstr /I "\? \/h \-h">NUL 2>&1
if %errorlevel% EQU 0 goto :usage 

set "_explorerName=explorer.exe"
set "_NameToKill=%~1"
set "_Terminate=%~2"
set "_KillForce=%~3"

if NOT defined _NameToKill if not [%1]==[] (
  rem debugging 
  set "_NameToKill=CMD.EXE"
  rem debugging: start a child process
  start "" /MIN notepad.exe
)

for /F "tokens=1,2 delims=," %%G in ('
    TASKLIST /NH /FI "IMAGENAME eq %_explorerName%"  /FO CSV
') do (
  set "_explorerPID=%%~H"
)
ECHO checking '%_NameToKill%*' as child of %_explorerName% ^(PID=%_explorerPID%^)  
for /F "skip=1 tokens=1-3" %%G in ('
    wmic process WHERE "Name like '%_NameToKill%%%' and ParentProcessId=%_explorerPID%" get Name^,ParentProcessId^,ProcessId^,Status
') do (
  if NOT "%%H"=="" (
    echo %%G
    for /F "skip=1 tokens=1-3" %%g in ('
        2^>NUL wmic process WHERE "ParentProcessId=%%I" get Name^,ParentProcessId^,ProcessId^,Status
    ') do (
      if NOT "%%h"=="" (
        echo    ProcessId=%%i, ParentProcessId=%%h, %%g child of %%G ^(%%I^)
        if defined _Terminate (
          if /I "%%~g"=="conhost.exe" (
            rem debugging
            taskkill /PID %%i /T
          ) else (
            taskkill /PID %%i %_Terminate% %_KillForce%
          )
          echo(
        )
      )
    )
    echo    ParentProcessId=%%H, ProcessId=%%I, %%G child of %_explorerName% ^(%_explorerPID%^)
    if defined _Terminate (
      taskkill /PID %%I /T
      echo(- 
    )
  )
)
if [%1]==[] goto :usage
:endlocal
ENDLOCAL
goto :eof

:usage
  echo USAGE:
  echo %~nx0 -? ^| /? ^| /h ^| -h           this help message
  echo %~nx0                             list all childs of %_explorerName%
  echo %~nx0 ^<processName^> [/T] [/F]     list all childs of a process
  echo %~nx0 ""            [/T] [/F]     a particular test case for cmd.exe
  echo(
  echo Optional parameters /T and /F ^(or -T and -F^): see taskkill /? 
goto :endlocal
@ECHO关闭
SETLOCAL EnableExtensions DisableDelayedExpansion
回声“%1%~2%~3”| findstr/I”\?\/h \-h”>NUL 2>&1
如果%errorlevel%EQU 0转到:用法
设置“\u explorerName=explorer.exe”
设置“\u NameToKill=%~1”
设置“_Terminate=%~2”
设置“_KillForce=%~3”
如果未定义_NameToKill如果未定义[%1]=[](
rem调试
设置“\u NameToK”
@ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
echo "%~1%~2%~3" | findstr /I "\? \/h \-h">NUL 2>&1
if %errorlevel% EQU 0 goto :usage 

set "_explorerName=explorer.exe"
set "_NameToKill=%~1"
set "_Terminate=%~2"
set "_KillForce=%~3"

if NOT defined _NameToKill if not [%1]==[] (
  rem debugging 
  set "_NameToKill=CMD.EXE"
  rem debugging: start a child process
  start "" /MIN notepad.exe
)

for /F "tokens=1,2 delims=," %%G in ('
    TASKLIST /NH /FI "IMAGENAME eq %_explorerName%"  /FO CSV
') do (
  set "_explorerPID=%%~H"
)
ECHO checking '%_NameToKill%*' as child of %_explorerName% ^(PID=%_explorerPID%^)  
for /F "skip=1 tokens=1-3" %%G in ('
    wmic process WHERE "Name like '%_NameToKill%%%' and ParentProcessId=%_explorerPID%" get Name^,ParentProcessId^,ProcessId^,Status
') do (
  if NOT "%%H"=="" (
    echo %%G
    for /F "skip=1 tokens=1-3" %%g in ('
        2^>NUL wmic process WHERE "ParentProcessId=%%I" get Name^,ParentProcessId^,ProcessId^,Status
    ') do (
      if NOT "%%h"=="" (
        echo    ProcessId=%%i, ParentProcessId=%%h, %%g child of %%G ^(%%I^)
        if defined _Terminate (
          if /I "%%~g"=="conhost.exe" (
            rem debugging
            taskkill /PID %%i /T
          ) else (
            taskkill /PID %%i %_Terminate% %_KillForce%
          )
          echo(
        )
      )
    )
    echo    ParentProcessId=%%H, ProcessId=%%I, %%G child of %_explorerName% ^(%_explorerPID%^)
    if defined _Terminate (
      taskkill /PID %%I /T
      echo(- 
    )
  )
)
if [%1]==[] goto :usage
:endlocal
ENDLOCAL
goto :eof

:usage
  echo USAGE:
  echo %~nx0 -? ^| /? ^| /h ^| -h           this help message
  echo %~nx0                             list all childs of %_explorerName%
  echo %~nx0 ^<processName^> [/T] [/F]     list all childs of a process
  echo %~nx0 ""            [/T] [/F]     a particular test case for cmd.exe
  echo(
  echo Optional parameters /T and /F ^(or -T and -F^): see taskkill /? 
goto :endlocal