2016-11-25 81 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."); 
    } 
    }