C# Windows服务:获取所有用户的进程,包括MainWindowHandle

C# Windows服务:获取所有用户的进程,包括MainWindowHandle,c#,windows,powershell,service,process,C#,Windows,Powershell,Service,Process,我已经在PowerShell中编写了一个Windows服务。它工作得很好,但有一个主要的限制,我需要找到一个解决方案。我需要列出所有带有窗口的应用程序的进程-这用于被动应用程序计数(即每个登录用户打开和使用的应用程序) 该服务作为本地系统运行。我可以看到所有进程,但由于服务位于非交互式桌面(会话ID 0)中,我看不到MainWindowTitle或MainWindowhandle,标题均为null,句柄均为0 我尝试过使用获取进程、获取CIMInstance Win32_进程和[System.D

我已经在PowerShell中编写了一个Windows服务。它工作得很好,但有一个主要的限制,我需要找到一个解决方案。我需要列出所有带有窗口的应用程序的进程-这用于被动应用程序计数(即每个登录用户打开和使用的应用程序)

该服务作为本地系统运行。我可以看到所有进程,但由于服务位于非交互式桌面(会话ID 0)中,我看不到MainWindowTitle或MainWindowhandle,标题均为null,句柄均为0

我尝试过使用
获取进程
获取CIMInstance Win32_进程
[System.Diagnostics.Process]::getprocesss()
。所有这些都不起作用(我得到了所有进程,但数据都经过了编辑)

我决定创建一个C#控制台应用程序,PowerShell服务将执行该应用程序并从中收集响应。这起作用,但仍然排除了“敏感”信息,因此关键属性
MainWindowhandle
始终为0

这里是C#控制台应用程序(这是一项仅需测试的快速工作):

使用Newtonsoft.Json;
使用制度;
使用System.Collections.Generic;
使用系统组件模型;
使用系统诊断;
使用System.Linq;
使用System.Security.Permissions;
命名空间进程管理器
{
公共类进程记录
{
//自动初始化属性
公共字符串名称{get;set;}
公共int MainWindowHandle{get;set;}
公共字符串WindowTitle{get;set;}
public int SessionId{get;set;}
公共日期时间开始时间{get;set;}
}
班级计划
{
[PermissionSetAttribute(SecurityAction.LinkDemand,Name=“FullTrust”)]
[主机保护属性(SecurityAction.LinkDemand,SharedState=true,Synchronization=true,ExternalProcessMgmt=true,SelfAffectingProcessMgmt=true)]
[PermissionSetAttribute(SecurityAction.InheritanceDemand,Name=“FullTrust”)]
静态void Main(字符串[]参数)
{
listprocess();
}
公共静态void listprocess()
{
列表进程列表=新列表{};
Process.getprocesss().ToList().ForEach(p=>
{
尝试
{
ProcessList.Add(新的ProcessRecord
{
Name=p.ProcessName,
MainWindowHandle=(int)p.MainWindowHandle,
WindowTitle=p.MainWindowTitle,
SessionId=p.SessionId,
StartTime=p.StartTime
});
}
捕获(Win32Exception)
{
//忽略这一点可以避免低级别系统进程的访问被拒绝异常
}
});
WriteLine(JsonConvert.SerializeObject(processesList));
}
}
}
我尝试以本地管理员组中的本地用户身份运行该服务。出于绝望,我还尝试启用“允许服务与桌面交互”

我不需要知道MainWindowHandle,我只需要列出MainWindowHandle不是0的进程。不幸的是,我需要知道会话ID

我应该如何进行?答案是简单的“这是不可能的”
,还是有一个顽皮的解决办法,比如模仿

也许有一种更简单的方法可以列出用户打开的应用程序,而不必依赖于
MainWindowHandle!=0


谢谢你的指点

如果需要带窗口应用程序的进程,可以按属性过滤进程
mainwindowhandle

Get-Process | Where-Object {$_.mainwindowhandle -ne 0} | select ProcessName | ft -HideTableHeaders

谢谢@vad,但问题是我在非交互式桌面上以服务的形式运行它
Get process
将所有进程的
mainwindowhandle
返回为0,出于安全原因,返回为“不可读”中的属性。因此,您正在尝试查找所有非交互式进程,而不是专门针对您的工具?如果只是为了你的工具,在创建过程中,陷阱里的信息。机器上的任何进程都应该有“StartInfo”我只能想象,我感谢你的指导!谢谢@vad,这是我第一次尝试。问题是我在非交互式桌面上以服务的形式运行它。Get process将所有进程的mainwindowhandle返回为0,因为出于安全原因,该属性位于unreadable中。我在问题中确实讲清楚了吗?
Get-Process | Where-Object {$_.mainwindowhandle -ne 0} | select ProcessName | ft -HideTableHeaders