如何枚举CLR管理的正在运行的进程?

Posted

技术标签:

【中文标题】如何枚举CLR管理的正在运行的进程?【英文标题】:How to enumerate running processes managed by CLR? 【发布时间】:2011-04-22 17:51:35 【问题描述】:

如何枚举正在运行的进程?应用域呢?

会有任何与安全相关的问题吗?

我会只使用 .NET 4.0,只使用 Windows 7/Windows Server 2008 R2 的解决方案。

P.S.:这就是我想要做的...... ProcessExplorer.NET question

【问题讨论】:

我自己没有尝试过,您可以通过编程方式访问各种 performance counters(就像 perfmon 显示的那样),并从中使用处理 CLR 的计数器,例如 .NET CLR Loading | Current appdomains 这是我正在查看的内容:msdn.microsoft.com/en-us/library/zf749bat.aspx WMI 是否与此处相关?有没有更重构友好和类型安全的方法来做到这一点? 查看文档,我的印象是System.Diagnostics.PerformanceCounterSystem.Management.Instrumentation 都会为您提供所需的答案,但前者的 API 只是后者更丰富的 API 的一小部分. 【参考方案1】:

试试这个Examine Running Processes Using Both Managed and Unmanaged Code

【讨论】:

链接似乎过时了。它没有解决我对 Win7 安全性的担忧。【参考方案2】:

System.Diagnostics.Process.GetProcesses() 会将所有正在运行的进程列为Process 对象。

【讨论】:

【参考方案3】:

使用上面的 Process.GetProcesses 后,您可以使用 ICLRMetaHost::EnumerateLoadedRuntimes 查看进程是否正在运行 CLR 的实例,并获取其中运行的 CLR 的版本。 http://msdn.microsoft.com/en-us/library/dd233119.aspx。 API 不直接暴露给 .NET,但它是 COM,因此您可以 tlbimport mscoree.dll 并在 .NET 中使用自动生成的包装器。

【讨论】:

通过查看文档,这似乎是一条合理的路径。【参考方案4】:
using System;
using System.Diagnostics;

namespace ConsoleApplication1

   class Program
   
      static void Main(string[] args)
      
         Process[] procs = Process.GetProcesses();
         foreach (Process proc in procs)
         
            string processName = proc.ProcessName;
            int processId = proc.Id;

            try
            
               if (proc.HasDesktop40CLR())
                  Console.WriteLine("#0, 1 (has Desktop CLR 4.0+)", processId, processName);

               if (proc.HasOlderDesktopCLR())
                  Console.WriteLine("#0, 1 (has Older Desktop CLR)", processId, processName);

               if (proc.HasMscorlib())
                  Console.WriteLine("#0, 1 (has MSCORLib)", processId, processName);
            
            catch (Exception)
            
               Console.WriteLine("#0, 1 (skipped/unknown)", processId, processName);
            
         
      
   

   public static class ProcessExtensions
   
      public static bool HasDesktop40CLR(this Process proc)
      
         for (int ix = 0; ix < proc.Modules.Count; ++ix)
         
            var moduleName = proc.Modules[ix].ModuleName;

            if (string.Compare(moduleName, "mscoree.dll", ignoreCase: true) == 0)
               return true;

            if (string.Compare(moduleName, "mscoreei.dll", ignoreCase: true) == 0)
               return true;
         

         return false;
      

      public static bool HasOlderDesktopCLR(this Process proc)
      
         for (int ix = 0; ix < proc.Modules.Count; ++ix)
         
            var moduleName = proc.Modules[ix].ModuleName;

            if (string.Compare(moduleName, "mscorwks.dll", ignoreCase: true) == 0)
               return true;
         

         return false;
      

      public static bool HasMscorlib(this Process proc)
      
         for (int ix = 0; ix < proc.Modules.Count; ++ix)
         
            var moduleName = proc.Modules[ix].ModuleName;

            if (string.Compare(moduleName, "mscorlib.dll", ignoreCase: true) == 0)
               return true;

            if (string.Compare(moduleName, "mscorlib.ni.dll", ignoreCase: true) == 0)
               return true;
         

         return false;
      
   

【讨论】:

这对我有用,谢谢!我已经编辑了回复,添加了代码必须满足的几个重要条件。

以上是关于如何枚举CLR管理的正在运行的进程?的主要内容,如果未能解决你的问题,请参考以下文章

CLR 调试体系结构

Qt,ProcessState 枚举如何工作

每个 CLR 或每个进程是不是有一个托管堆?

纵谈进程枚举

没有CLR版本v4。被加载到目标进程中。 - CLR Profiler错误

如何获取正在运行的进程的进程ID,如任务管理器中所示