【问题标题】:List of DLLs loaded by specific process by its name由特定进程按其名称加载的 DLL 列表
【发布时间】:2016-01-20 14:07:54
【问题描述】:

我正在尝试使用以下代码列出加载以进行处理的 dll:

Process[] ObjModulesList = Process.GetProcessesByName("iexplore");

foreach (Process prc in ObjModulesList)
{
    ProcessModuleCollection ObjModules = prc.Modules;
    foreach (ProcessModule objModule in ObjModules)
    {
        string strModulePath = objModule.FileName.ToString();
        Console.WriteLine(strModulePath);
    }
}

我遇到了错误

32 位进程无法访问 64 位进程的模块。

我尝试以管理员身份运行我的进程,并以 64 位和 32 位运行 iexplore。这些都没有工作。

顺便说一句,我必须将我的程序编译为 32 位。

有什么想法吗?

【问题讨论】:

  • 如果你将你的应用编译为 64 位,你会得到相反的错误吗?
  • 没有。还是一样:“32位进程不能访问64位进程的模块。”
  • 您是如何将您的应用程序编译为 64 位的?您是否在任务管理器中检查了您的应用程序实际上以 64 位运行?你甚至在运行正确的 exe 吗?
  • 检查 corflags.exe 作为这样做的一种潜在方法
  • 最重要的建议相关 question 似乎有大部分答案(它不是 .NET,但由于它从根本上说“你无法在本地获取此信息”,因此没有理由期待 . NET 来改变这里的数学)

标签: c# process 32bit-64bit


【解决方案1】:

您必须使用 x64 目标编译您的应用程序。

否则您可以咨询: http://www.codeproject.com/Articles/301/Display-Loaded-Modules-v

【讨论】:

    【解决方案2】:

    你可以使用WMI,这是一段获取所有进程和相关模块的代码:

    var wmiQueryString = string.Format("select * from CIM_ProcessExecutable");
    Dictionary<int, ProcInfo> procsMods = new Dictionary<int, ProcInfo>();
    using (var searcher = new ManagementObjectSearcher(string.Format(wmiQueryString)))
    using (var results = searcher.Get())
    {
        foreach (var item in resMg.Cast<ManagementObject>())
        {
            try
            {
                var antecedent = new ManagementObject((string)item["Antecedent"]);
                var dependent = new ManagementObject((string)item["Dependent"]);
                int procHandleInt = Convert.ToInt32(dependent["Handle"]);
                ProcInfo pI = new ProcInfo { Handle = procHandleInt, FileProc = new FileInfo((string)dependent["Name"]) };
                if (!procsMods.ContainsKey(procHandleInt))
                {
                    procsMods.Add(procHandleInt, pI);
                }
                procsMods[procHandleInt].Modules.Add(new ModInfo { FileMod = new FileInfo((string)antecedent["Name"]) });
            }
            catch (System.Management.ManagementException ex)
            {
                // Process does not exist anymore
            }
        }
    }
    

    procsMods 中我们存储了进程和模块,现在我们打印它们:

    foreach (var item in procsMods)
    {
        Console.WriteLine(string.Format("{0} ({1}):", item.Value.FileProc.Name, item.Key));
        foreach (var mod in item.Value.Modules)
        {
            Console.WriteLine("\t{0}", mod.FileMod.Name);
        }
    }
    

    这些是ProcInfoModInfo 类:

    class ProcInfo
    {
        public FileInfo FileProc { get; set; }
        public int Handle { get; set; }
        public List<ModInfo> Modules { get; set; }
    
        public ProcInfo()
        {
            Modules = new List<ModInfo>();
        }
    }
    
    class ModInfo
    {
        public FileInfo FileMod { get; set; }
    }
    

    【讨论】:

    • 加载整个 WMI CIM_ProcessExecutable 会对性能造成显着影响,必须有一种方法可以仅按进程查询,而无需在 c# 中迭代​​整个表。
    • @Wobbles 我们可以尝试像REFERENCES OF {Win32_Process.Handle=&lt;YOUR_PROCESS_ID&gt;} Where ResultClass = CIM_ProcessExecutable这样的查询
    • 一直在尝试这样的声明,但收到System.Management.ManagementException: 'Invalid object path'。我的 ? :stackoverflow.com/questions/44264224/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 1970-01-01
    • 1970-01-01
    • 2022-12-17
    • 2012-04-21
    • 2014-12-04
    • 2011-02-27
    相关资源
    最近更新 更多