Как программно получить DLL-зависимости

Как я могу получить список всех DLL-зависимостей для данного DLL файла или EXE файла?

Другими словами, я хотел бы сделать то же самое, что и инструмент "Dependency walker", но программно.

Для чего нужен API Windows (в идеале .NET)?

Ответы

Ответ 1

Вы можете использовать EnumProcessModules. Управляемый API, такой как предложенный kaanbardak, не даст вам список собственных модулей.

Например, см. эту страницу в MSDN

Если вам нужно статически анализировать вашу dll, вам нужно вставить формат PE и узнать о таблицах импорта. Подробнее см. отличный учебник.

Ответ 2

ПРИМЕЧАНИЕ. Основываясь на комментариях из сообщения ниже, я полагаю, это может также пропустить неуправляемые зависимости, потому что он полагается на отражение.

Вот небольшая программа С#, написанная Джоном Скитом из bytes.com на .NET Dependency Walker

using System;
using System.Reflection;
using System.Collections;

public class DependencyReporter
{
    static void Main(string[] args)
    {
        //change this line if you only need to run the code one:
        string dllToCheck = @"";

        try
        {
            if (args.Length == 0)
            {
                if (!String.IsNullOrEmpty(dllToCheck))
                {
                    args = new string[] { dllToCheck };
                }
                else
                {
                    Console.WriteLine
                        ("Usage: DependencyReporter <assembly1> [assembly2 ...]");
                }
            }

            Hashtable alreadyLoaded = new Hashtable();
            foreach (string name in args)
            {
                Assembly assm = Assembly.LoadFrom(name);
                DumpAssembly(assm, alreadyLoaded, 0);
            }
        }
        catch (Exception e)
        {
            DumpError(e);
        }

        Console.WriteLine("\nPress any key to continue...");
        Console.ReadKey();
    }

    static void DumpAssembly(Assembly assm, Hashtable alreadyLoaded, int indent)
    {
        Console.Write(new String(' ', indent));
        AssemblyName fqn = assm.GetName();
        if (alreadyLoaded.Contains(fqn.FullName))
        {
            Console.WriteLine("[{0}:{1}]", fqn.Name, fqn.Version);
            return;
        }
        alreadyLoaded[fqn.FullName] = fqn.FullName;
        Console.WriteLine(fqn.Name + ":" + fqn.Version);

        foreach (AssemblyName name in assm.GetReferencedAssemblies())
        {
            try
            {
                Assembly referenced = Assembly.Load(name);
                DumpAssembly(referenced, alreadyLoaded, indent + 2);
            }
            catch (Exception e)
            {
                DumpError(e);
            }
        }
    }

    static void DumpError(Exception e)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine("Error: {0}", e.Message);
        Console.WriteLine();
        Console.ResetColor();
    }
}

Ответ 3

Чтобы получить зависимости родного модуля, я считаю, что это должно быть нормально, чтобы получить его из таблицы импорта файлов PE, вот 2 ссылки, которые объясняют это в глубину:

http://msdn.microsoft.com/en-us/magazine/bb985992.aspx

http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

Чтобы получить зависимости от .NET, мы можем использовать .NET API, например Assembly.Load.

Чтобы получить модуль .NET для всех зависимостей, как насчет объединения двух способов - сборки .NET - это только PE файл с метаданными.

Ответ 4

Хотя этот вопрос уже имеет принятый ответ, документация, указанная в других ответах, где не нарушена, является старой. Вместо того, чтобы читать все это только для того, чтобы найти его, он не охватывает различия между Win32 и x64 или другими отличиями, мой подход был следующим:

C:\UnxUtils\usr\local\wbin>strings.exe E:\the-directory-I-wanted-the-info-from\*.dll > E:\TEMP\dll_strings.txt

Это позволило мне использовать Notepad ++ или gvim или что-то еще, чтобы искать DLL файлы, которые все еще зависели от DLL файлов MS с 120.dll в конце имени dll, поэтому я мог найти те, которые нуждаются в обновлении.

Это может быть легко написано на вашем любимом языке.

Учитывая, что мой поиск этой информации был связан с VS 2015, и этот вопрос был лучшим результатом для поиска Google, я предоставляю этот ответ, что он может быть полезен кому-то, кто приходит с поиском того же вещь.

Ответ 5

Чтобы прочитать DLL (модули), загруженные исполняемым exe, используйте функции ToolHelp32 Инструментальная справка Документация по MSDN.

Не уверен, что он будет показывать для .NET-exe (я никогда не пробовал). Но он показывает полный путь от того, где была загружена DLL. Часто это была информация, которая мне нужна при попытке решить проблемы с DLL..Net должно было удалить необходимость использования этих функций (найдите DLL Hell для получения дополнительной информации).