web-dev-qa-db-ja.com

すべてのDLLの依存関係を見つけますか?

DLL(たとえば20)のコレクションがあります。特定のDLL(たとえばDLL A)が依存しているすべてのDLLを見つけるにはどうすればよいですか?

41
Abhijeet

プログラムを使用する場合は、 Assembly.GetReferencedAssemblies

それを再帰的に使用して、必要なすべてのアセンブリを見つけることができます。 (つまり、Xの依存関係を見つけ、次に依存関係の依存関係を見つけます。)

42
Jon Skeet

質問には「C#」というタグが付いているため、管理対象のdll(アセンブリ)について話していると思います。その場合、dependencywalkerは役に立ちません。あなたがプログラムでそれをしたいのであれば、良いものはJetBriansによるdotPeekとRedGateによるReflectorです。または、Visual Studioでオブジェクトインスペクターを使用することもできます。

しかし、それは長いプロセスであり、面倒でもあります。 Jonが述べたように、Assembly.GetReferencedAssembliesを使用する短いC#プログラム/ F#スクリプトを作成します。

代わりに、プログラム(C#コード)でネイティブDLLの依存関係を調べたい場合、PEファイル(MS dllおよびexeファイル形式)およびそのIAT(インポートアドレステーブル)を調べる必要があります。簡単ではないが、不可能ではない...

私は ここでMSDNここ を開始してPEセクションを理解し、マネージライブラリを使用してそれを読みます(Monoプロジェクトの一部を含む多くがあります(私は Cecil を考えると、ネイティブバイナリでも動作するはずです);過去には、良いJohn Goughの this one を使用しました。

13

依存関係ウォーカー http://www.dependencywalker.com を使用してこれを把握できます。ただし、x32とx64の違いに注意してください。

Dependency Walkerは、32ビットまたは64ビットのWindowsモジュール(exe、dll、ocx、sysなど)をスキャンし、すべての依存モジュールの階層ツリー図を構築する無料のユーティリティです。

8
Aniket Inge

すべての回答は、Assembly.GetReferencedAssemblies。これは、.NETアセンブリ専用に機能する、単に書き忘れるC#コンソールアプリです。 return 0チェックできたアセンブリで、成功した場合は、STDOUTに出力します。その他はすべてreturn 1および何らかのエラー出力を出力します。 Gistを取得できます こちら

using System;
using System.Reflection;
using System.IO;
namespace DotNetInspectorGadget
{
    class DotNetInspectorGadget 
    {
        static int Main(string[] args) 
        {
          if(args.GetLength(0) < 1)
          {
            Console.WriteLine("Add a single parameter that is your" +
            " path to the file you want inspected.");
            return 1;
          }
          try {
                var assemblies = Assembly.LoadFile(@args[0]).GetReferencedAssemblies();

                if (assemblies.GetLength(0) > 0)
                {
                  foreach (var Assembly in assemblies)
                  {
                    Console.WriteLine(Assembly);
                  }
                  return 0;
                }
          }
          catch(Exception e) {
            Console.WriteLine("An exception occurred: {0}", e.Message);
            return 1;
          } finally{}

            return 1;
        }
    }
}

使用法:

call %cd%\dotnet_inspector_gadget.exe C:\Windows\Microsoft.NET\Assembly\GAC_64\Microsoft.ConfigCI.Commands\v4.0_10.0.0.0__31bf3856ad364e35\Microsoft.ConfigCI.Commands.dll

出力:

mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
7

.NETアセンブリの場合、アセンブリが依存しているアセンブリを表示するためのすばらしいツールは AsmSpy です。

DLL(ファイル)が必要な場合は、_Assembly.GetReferencedAssemblies_も.Net Frameworkアセンブリを返します。

以下に、現在のディレクトリで見つけることができるdllを取得する簡単なコードスニペットを示します(他の関連ファイルも含めます)。

_private readonly string[] _extensions = { ".dll", ".exe", ".pdb", ".dll.config", ".exe.config" };

private string[] GetDependentFiles(Assembly assembly)
{
    AssemblyName[] asm = Assembly.GetReferencedAssemblies();
    List<string> paths = new List<string>(asm.Length);
    for (int t = asm.Length - 1; t >= 0; t--)
    {
        for (int e = _extensions.Length - 1; e >= 0; e--)
        {
            string path = Path.GetFullPath(asm[t].Name + _extensions[e]);
            if (File.Exists(path)) paths.Add(path);
        }
    }

    return paths.ToArray();
}
_

次のように呼び出すことができます:MessageBox.Show(string.Join("\r\n", GetDependentFiles(Assembly.GetEntryAssembly())));

0
Louis Somers