如何在dllhost.exe中列出/检查托管.NET DLL的存在

时间:2016-11-25 10:58:20

标签: c# .net dll

我有一些可用于COM +的组件。 在这种情况下,它将在dllhost.exe(COM代理)使用时加载。

出于维护原因,我想创建一个.EXE文件,该文件会停止dllhost.exe的所有实例以停止使用组件。

所以我做了这个:

  foreach (var process in Process.GetProcesses().Where(pr => pr.ProcessName.ToLower() == "dllhost"))
  {
    var modules = process.Modules;
    foreach (ProcessModule module in modules)
    {
      //Console.WriteLine(module.ModuleName);
      if (!module.ModuleName.ToLower().Contains("tqsoft")) continue;
      process.Kill();
    }
  }

不幸的是process.Modules只列出.dll和.exe文件的非托管代码。

到目前为止,我在MSDN,SO等方面找不到任何解决方案。 Hans Passant在这里提到MDbg - Debugger's Protocol Is Incompatible With The Debuggee关于解决方案。

我查看了第4版示例,并在我的项目中引用了mdbgeng.dllcorapi.dll

以下代码应该为我提供进程的程序集,但它会失败并出现异常。

    MDbgEngine mDbgEngine = new MDbgEngine();
    var dbgProcess = mDbgEngine.Attach(process.Id);
    foreach (CorAppDomain appDomain in dbgProcess.AppDomains)
    {
      foreach (CorAssembly assembly in appDomain.Assemblies)
      {
        Console.WriteLine(assembly.Name);
        //get assembly information
      }
    }

例外:

System.Runtime.InteropServices.COMException (0x8007012B): Only part of a ReadProcessMemory or WriteProcessMemory request
was completed. (Exception from HRESULT: 0x8007012B)
  at Microsoft.Samples.Debugging.CorDebug.ICLRMetaHost.EnumerateLoadedRuntimes(ProcessSafeHandle hndProcess)
  at Microsoft.Samples.Debugging.CorDebug.CLRMetaHost.EnumerateLoadedRuntimes(Int32 processId)
  at Microsoft.Samples.Debugging.MdbgEngine.MdbgVersionPolicy.GetDefaultAttachVersion(Int32 processId)
  at Microsoft.Samples.Debugging.MdbgEngine.MDbgEngine.Attach(Int32 processId)
  at TQsoft.Windows.Products.Sake.Kernel.StopInformer(Boolean fullstop)
  at TQsoft.Windows.Products.Sake.Program.Main(String[] args)

不要责怪我,毕竟我只是人类:)但这里有什么问题或者我错过了什么?

更新

我的错误。尝试从32位进程访问64位dllhost.exe是个例外。我修复了我只访问带有32位进程的dllhost.exe。

但我仍然没有得到附加过程的程序集列表。

1 个答案:

答案 0 :(得分:0)

解决:我深入研究Hans Passant提到的MDbgEngine,发现我做错了什么。

对于遇到同样问题的人,这是我的代码。

  // dllhost.exe com+ instances
  foreach (var process in Process.GetProcesses().Where(pr => pr.ProcessName.ToLower() == "dllhost"))
  {
    // better check if 32 bit or 64 bit, in my test I just catch the exception
    try
    {
      MDbgEngine mDbgEngine = new MDbgEngine();
      var dbgProcess = mDbgEngine.Attach(process.Id);
      dbgProcess.Go().WaitOne();
      foreach (MDbgAppDomain appDomain in dbgProcess.AppDomains)
      {
        var corAppDomain = appDomain.CorAppDomain;
        foreach (CorAssembly assembly in corAppDomain.Assemblies)
        {
          if (assembly.Name.ToLower().Contains("tqsoft"))
          {
            dbgProcess.Detach();
            process.Kill();
          }
        }
      }
    }
    catch
    {
      Console.WriteLine("64bit calls not supported from 32bit application.");
    }
  }