我正在尝试编写小型IIS进程监视器(CPU和内存使用情况),这应该尽可能地为系统提供支持。我需要的只是IIS应用程序池名称,当前内存使用情况和当前CPU使用率。
我使用这两个命令设法做到了没有更大的问题:
using (var srvman = new ServerManager())
{
workerProcesses = srvman.WorkerProcesses;
}
和
processes = Process.GetProcesses().Where(processItem => processItem.ProcessName.Contains("w3wp") || processItem.ProcessName.Contains("php-cgi"))
第一个返回正在运行的具有进程ID的应用程序池,第二个返回来自系统的进程信息(所以这里是我获得CPU和内存使用的地方)。加入这两个信息几乎给了我想要的东西。唯一的例外是在IIS上运行的PHP应用程序。
对于PHP应用程序,正在生成php-cgi.exe
进程,我需要将其关联到IIS App Pool工作进程。您是否知道如何将php-cgi.exe
进程与其w3wp.exe
父母联系起来?
以下是我想要生成的输出示例:
1x w3wp.exe for site.com is using 15MB memory
4x php-cgi.exe is using 4x 15MB = 60MB memory
我计划总结这些信息(在这种情况下,site.com的内存使用量为75 MB)。
答案 0 :(得分:1)
您可以使用一点P / Invoke as described by Simon Mourier来获取父进程PID。这样做是一种低成本操作,并将所有php-cgi
进程的列表与其创建者联系起来。
using (var srvman = new ServerManager())
{
var procs = from worker in srvman.WorkerProcesses
let workerProcess = Process.GetProcessById(worker.ProcessId)
join cgi in Process.GetProcessesByName("php-cgi")
on workerProcess.Id equals ParentProcessUtilities.GetParentProcess(cgi.Handle).Id
into childProcesses
select new
{
Worker = worker,
WorkerProcess = workerProcess,
Children = childProcesses,
TotalMemoryUse = workerProcess.PrivateMemorySize64
+ childProcesses.Sum(p => p.PrivateMemorySize64)
};
foreach (var proc in procs)
{
Console.WriteLine("Worker {0}:{1} using {2} total bytes", proc.Worker.AppPoolName,
proc.Worker.ProcessId, proc.TotalMemoryUse);
foreach (var child in proc.Children)
{
Console.WriteLine("\tphp-cgi process {0} using {1} bytes", child.Id, child.PrivateMemorySize64);
}
}
}
输出
C:\drop> phpProcessTest.exe Worker DefaultAppPool:4396 using 61530112 total bytes php-cgi process 3540 using 7024640 bytes php-cgi process 3144 using 6389760 bytes