我有一些可用于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.dll
和corapi.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。
但我仍然没有得到附加过程的程序集列表。
答案 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.");
}
}