Windows 服务:获取所有用户的进程,包括 MainWindowHandle
Posted
技术标签:
【中文标题】Windows 服务:获取所有用户的进程,包括 MainWindowHandle【英文标题】:Windows Service: Get processes for all users, including MainWindowHandle 【发布时间】:2020-06-18 04:15:51 【问题描述】:我在 PowerShell 中编写了一个 Windows 服务。它运作良好,但我需要找到一个解决方案来解决一个主要限制。我需要列出所有带有 Windowed 应用程序的进程 - 这是用于被动应用程序计量(即每个登录用户打开和使用的应用程序)。
服务以Local System
运行。我可以看到所有进程,但由于服务位于非交互式桌面(会话 ID 0)中,我看不到 MainWindowTitle 或 MainWindowhandle,标题全为 null,句柄全为 0。
我尝试过使用Get-Process
、Get-CIMInstance Win32_Process
和[System.Diagnostics.Process]::GetProcesses()
。这些都不起作用(我得到了所有进程,但数据已被编辑)。
我决定创建一个 C# 控制台应用程序,PowerShell 服务将执行该应用程序并从中收集响应。这有效,但仍然排除了“敏感”信息,因此关键属性 MainWindowhandle
始终为 0。
这里是 C# 控制台应用程序(它只是一个快速的测试工作):
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Security.Permissions;
namespace ProcessManager
public class ProcessRecord
// Auto-Initialized properties
public string Name get; set;
public int MainWindowHandle get; set;
public string WindowTitle get; set;
public int SessionId get; set;
public DateTime StartTime get; set;
class Program
[PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
[HostProtectionAttribute(SecurityAction.LinkDemand, SharedState = true, Synchronization = true, ExternalProcessMgmt = true, SelfAffectingProcessMgmt = true)]
[PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
static void Main(string[] args)
listProcesses();
public static void listProcesses()
List<ProcessRecord> processesList = new List<ProcessRecord>;
Process.GetProcesses().ToList().ForEach(p =>
try
processesList.Add(new ProcessRecord
Name = p.ProcessName,
MainWindowHandle = (int) p.MainWindowHandle,
WindowTitle = p.MainWindowTitle,
SessionId = p.SessionId,
StartTime = p.StartTime
);
catch (Win32Exception)
// Just ignoring this to avoid the Access Denied exception for low-level system processes
);
Console.WriteLine(JsonConvert.SerializeObject(processesList));
我尝试在本地管理员组中以本地用户身份运行该服务。出于绝望,我还尝试启用“允许服务与桌面交互”。
我不需要知道 MainWindowHandle,我只需要列出 MainWindowhandle 不为 0 的进程。不幸的是,我需要知道会话 ID。
我应该如何进行?答案是简单的“无法完成”,还是有一个顽皮的解决方法,例如冒充?
也许有一种更简单的方法可以列出用户打开的应用程序,而不必依赖MainWindowHandle != 0
?
感谢您的指点!
【问题讨论】:
感谢@vad,但问题是我在非交互式桌面中将其作为服务运行。Get-process
将为所有进程返回 mainwindowhandle
为 0,因为出于安全原因,该属性不可读。
那么,您正在尝试查找所有非交互式进程,而不是专门针对您的工具?如果它只是为了你的工具,在创建过程中,捕获那里的信息。机器上的任何进程仍然应该有“StartInfo”。 --- docs.microsoft.com/en-us/dotnet/api/… --- docs.microsoft.com/en-us/windows/win32/api/winuser/…
我只能想象,感谢指导!
【参考方案1】:
如果您需要带有窗口应用程序的进程,您可以按属性过滤进程mainwindowhandle
Get-Process | Where-Object $_.mainwindowhandle -ne 0 | select ProcessName | ft -HideTableHeaders
【讨论】:
谢谢@vad,这是我尝试的第一件事。问题是我在非交互式桌面中将其作为服务运行。 Get-process 将所有进程的 mainwindowhandle 返回为 0,因为出于安全原因,该属性不可读。我确实在问题中明确了这一点?以上是关于Windows 服务:获取所有用户的进程,包括 MainWindowHandle的主要内容,如果未能解决你的问题,请参考以下文章