2016-11-25 78 views
0

我有一些可用于COM +的组件。 在这种情况下,它会在使用时加载到dllhost.exe(COM代理)中。如何在dllhost.exe中列出/检查Managed .NET DLL的存在

由于维护的原因,我想创建一个.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) 

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

UPDATE

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

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

+0

你运行这个提升吗? – rene

回答

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."); 
    } 
    }