找到哪个explorer.exe正在控制任务栏?

时间:2018-02-17 23:59:35

标签: powershell windows-10

我倾向于让我的电脑一次打开几个星期。我唯一的问题是任务栏在几天之后就会消失。通常这采取不在开始菜单中呈现图标的形式。它可以直接在开始菜单中不渲染任何东西。重新启动Explorer进程可以很好地在Windows 10中解决此问题。

我不想手动尝试找出哪个explorer.exe任务正在处理任务栏并重新启动它,而是想写一个执行此操作的PowerShell脚本。

我如何以编程方式确定哪个explorer.exe实例当前负责任务栏?

3 个答案:

答案 0 :(得分:4)

请注意,文件夹选项'启动文件夹窗口在单独的过程中'似乎是导致生成多个资源管理器进程的设置。如果没有设置,看起来只有一个Explorer.exe进程。

在我看来,每个衍生出来的浏览器窗口都超出了第一个窗口,其命令行包括' / factory'参数,而拥有'的过程。任务栏没有:

Get-WmiObject -Class Win32_process -Filter "name='Explorer.exe'" |
    Select-Object ProcessID,CommandLine 
ProcessID CommandLine                                                 

--------- -----------                                                                       
     3140 C:\WINDOWS\explorer.exe /factory,{ceff45ee-c862-41de-aee2-a022c81eda92} -Embedding
     2068 C:\WINDOWS\explorer.exe /factory,{682159d9-c321-47ca-b3f1-30e36b2ec8b9} -Embedding
    12164 "C:\WINDOWS\explorer.exe"

我通过停止具有任务栏的进程进行测试,然后从现有的窗口中生成更多的资源管理器窗口。具有/ factory参数的新资源管理器进程没有重新创建任务栏。

尝试查找其命令行不包含/factory

的资源管理器进程
Get-WmiObject -Class Win32_process -Filter "name='Explorer.exe'" |
    Select-Object ProcessID,CommandLine |
    Where-Object Commandline -NotLike "*/factory*"

没有保证,但它是你的探索之路。

答案 1 :(得分:4)

veefu's helpful answer的替代更简洁

注意:同样,不保证: 该方法依赖于拥有任务栏的文件资源管理器实例的.MainWindowTitle属性,该实例反映了任务栏的窗口标题,该标题恰好是为空,与实际文件资源管理器窗口的标题不同 - 至少在Windows 10和Windows 7上似乎是这种情况(还没有尝试过其他人):

Get-Process explorer | ? MainWindowTitle -eq '' # returns taskbar-owning Explorer instance

如果其他用户可以登录,并且您必须将检查过程限制为当前用户,请从 提升控制台运行以下命令

Get-Process -IncludeUserName explorer | ? MainWindowTitle -eq '' | ? UserName -eq (whoami)

强大但更复杂的方法

使用Add-Member -MemberDefinition,您可以定义帮助程序类型和方法,找到拥有任务栏窗口的进程的PID,利用P / Invoke签名调用Windows API函数:

# Define the helper type and method.
Add-Type -Namespace same2u.net -Name Util -MemberDefinition  @'
  [DllImport("user32.dll", SetLastError=true)]
  static extern IntPtr FindWindow(string lpszClass, string lpszWindow);

  // Return value is the *thread* ID
  [DllImport("user32.dll", SetLastError=true)]
  static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

  static IntPtr GetTaskbarHwnd() {
    return FindWindow("Shell_TrayWnd", null);
  }

  // The only public method.
  public static uint GetTaskbarProcessId() {
    uint pid;
    GetWindowThreadProcessId(GetTaskbarHwnd(), out pid);
    return pid;
  }
'@

# Call the helper method.
# Return value is the shell Explorer process' PID.
# Pass it to `Get-Process -ID` to get a process object, if needed.
[same2u.net.Util]::GetTaskbarProcessID()

多个文件资源管理器进程可能存在时(基于反复试验 - 请告诉我是否出错):

  • 如果 多个用户以交互方式登录(无论是否远程登录),每个此类用户可能拥有一个或多个资源管理器流程正在运行,如下所述。

  • 交互式登录用户至少一个资源管理器进程拥有任务栏和桌面 - 它可能或者可能没有打开实际的文件资源管理器窗口我们称之为 资源管理器shell进程

  • 如果文件资源管理器的 Launch folder windows in a separate process 视图选项为:

    • 关闭(默认设置):您创建的所有窗口交互式都归Explorer shell进程所有 - 没有新进程是创建

    • 开启 第一个窗口您以交互方式创建 生成 一个新的资源管理器流程,然后所有后续打开的窗口都由相同的新流程拥有。

    • 换句话说:如果您只是以交互式方式打开文件资源管理器窗口 ,您可以一个Launch folder windows in a separate process OFF)或最多< em>两个(Launch folder windows in a separate process ON)资源管理器进程 从编程上讲,这是一个不同的故事。

  • 无论Launch folder windows in a separate process视图设置如何,都可以以编程方式创建新的资源管理器进程

    • 例如,explorer /e,c:\之类的命令每次都会创建一个新的Explorer进程。

答案 2 :(得分:2)

运行explorer.exe时,如果任务栏未运行,则explorer.exe的该实例会运行该用户的任务栏。从逻辑上可以得出结论,运行任务栏的最可能的进程是最早的explorer.exe进程:

$CurrentProcessUser = Get-Process -PID $PID -IncludeUserName |
    Select-Object -ExpandProperty UserName

$TaskBarProcess = Get-Process -Name explorer -IncludeUserName | 
    Where-Object UserName -eq $CurrentProcessUser | 
    Sort-Object -Property StartTime | 
    Select-Object -First 1

这有保证吗?可能不是。可能有一些情况并非如此。但它通常可能是正确的。