Como determino as dependencies de um aplicativo .NET?

Como determino as dependencies de um aplicativo .NET? O Dependency Walker funciona com aplicativos gerenciados? Eu baixei o mais recente e tentei criar o perfil do aplicativo, mas ele sai sem muita explicação. Se não funcionar com o .NET, existe alguma outra ferramenta que me ajude a depurar um problema de carregamento de DLL em tempo de execução?

O walker de dependência funciona em binários win32 normais. Todos os dll’s e exe’s do .NET têm uma pequena parte do header stub que faz com que pareçam com binários normais, mas tudo o que basicamente diz é “load the CLR” – de modo que é tudo que o walker de dependência irá lhe dizer.

Para ver quais coisas seu aplicativo .NET realmente depende, você pode usar o excelente refletor .NET do Red Gate. (EDIT: Note que o .NET Reflector é agora um produto pago. ILSpy é gratuito e de código aberto e muito semelhante.)

Carregue sua DLL nela, clique com o botão direito do mouse e escolha ‘Analisar’ – você verá um item “Depende de” que mostrará todos os outros DLLs (e methods dentro desses DLLs) de que ele precisa.

Às vezes, pode ser mais complicado, pois seu aplicativo depende de X dll, e X dll está presente, mas por qualquer motivo não pode ser carregado ou localizado em tempo de execução.

Para solucionar esses tipos de problemas, a Microsoft tem um Visualizador de Log de Ligação de Montagem que pode mostrar o que está acontecendo em tempo de execução

Eu acho o pequeno utilitário AsmSpy uma ferramenta inestimável para resolver problemas com o carregamento de assemblies. Ele lista todas as referências de assembly de conjuntos gerenciados, incluindo versões de assembly.

Execute-o em um prompt de comando no diretório do .dll com os seguintes argumentos:

 asmspy . all 

captura de tela asmspy

Instale-o rapidamente com Chocolatey:

 choco install asmspy 

Abra o arquivo de assembly no ILDASM e olhe para @ the .assembly extern no MANIFEST

Para navegar pelas dependencies do código .NET, você pode usar os resources da ferramenta NDepend. A ferramenta propõe:

  • um gráfico de dependência
  • uma matriz de dependência ,
  • e também algumas consultas C # LINQ podem ser editadas (ou geradas) para procurar dependencies.

Por exemplo, tal consulta pode ser semelhante a:

 from m in Methods let depth = m.DepthOfIsUsing("NHibernate.NHibernateUtil.Entity(Type)") where depth >= 0 && m.IsUsing("System.IDisposable") orderby depth select new { m, depth } 

E o resultado é: (observe a profundidade da métrica de código, 1 é para chamadores diretos, 2 para chamadores de chamadores diretos …) (observe também o botão Exportar para Gráfico para exportar o resultado da consulta para um Gráfico de Chamada )

NDepend dependências navegando através de consulta LINQ C #

O gráfico de dependência se parece com:

NDepend Gráfico de Dependência

A matriz de dependência se parece com:

NDepend Matriz de Dependência

A matriz de dependência é, de fato, menos intuitiva do que o gráfico, mas é mais adequada para procurar seções complexas de código como:

NDepend Matrix vs Graph

Disclaimer: Eu trabalho para NDepend

Você não precisa baixar e instalar aplicativos ou ferramentas de shareware. Você pode fazer isso de forma programática do .NET usando Assembly.GetReferencedAssemblies()

 Assembly.LoadFile(@"app").GetReferencedAssemblies() 

Se você estiver usando o conjunto de ferramentas Mono, poderá usar o utilitário monodis com o argumento --assemblyref para listar as dependencies de um assembly .NET. Isso funcionará nos arquivos .exe e .dll .

Exemplo de uso:

 monodis --assemblyref somefile.exe 

Exemplo de saída (.exe):

 $ monodis --assemblyref monop.exe AssemblyRef Table 1: Version=4.0.0.0 Name=System Flags=0x00000000 Public Key: 0x00000000: B7 7A 5C 56 19 34 E0 89 2: Version=4.0.0.0 Name=mscorlib Flags=0x00000000 Public Key: 0x00000000: B7 7A 5C 56 19 34 E0 89 

Exemplo de saída (.dll):

 $ monodis --assemblyref Mono.CSharp.dll AssemblyRef Table 1: Version=4.0.0.0 Name=mscorlib Flags=0x00000000 Public Key: 0x00000000: B7 7A 5C 56 19 34 E0 89 2: Version=4.0.0.0 Name=System.Core Flags=0x00000000 Public Key: 0x00000000: B7 7A 5C 56 19 34 E0 89 3: Version=4.0.0.0 Name=System Flags=0x00000000 Public Key: 0x00000000: B7 7A 5C 56 19 34 E0 89 4: Version=4.0.0.0 Name=System.Xml Flags=0x00000000 Public Key: 0x00000000: B7 7A 5C 56 19 34 E0 89 

Habilitar o log de binding de assembly defina o valor do Registro EnableLog em HKLM \ Software \ Microsoft \ Fusion para 1. Observe que você precisa reiniciar o aplicativo (use iisreset) para que as alterações tenham algum efeito.

Dica: Lembre-se de desativar o log de fusão quando terminar, pois há uma penalidade de desempenho para ativá-lo.

É engraçado eu ter um problema semelhante e não encontrei nada adequado e estava ciente do bom e velho Dependency Walker, então no final eu mesmo escrevi um.

Isso lida especificamente com o .NET e mostrará quais referências um conjunto tem (e está faltando) recursivamente. Também mostrará dependencies de bibliotecas nativas.

É grátis (para uso pessoal) e está disponível aqui para qualquer pessoa interessada: http://www.netdepends.com

www.netdepends.com

Comentários bem-vindos.

http://www.amberfish.net/

O ChkAsm mostrará todas as dependencies de um assembly em particular de uma só vez, incluindo as versões, e permitirá facilmente que você procure por assemblies na lista. Funciona muito melhor para esse propósito do que o ILSpy ( http://ilspy.net/ ), que é o que eu costumava usar para essa tarefa.

Outro útil suplemento do Reflector que eu uso é a Matriz de Estrutura de Dependência . É muito bom ver que classs usam o quê. Além disso, é grátis.

Tente compilar seu assembly .NET com a opção --staticlink:"Namespace.Assembly" . Isso força o compilador a extrair todas as dependencies em tempo de compilation. Se se deparar com uma dependência que não é referenciada, ela fornecerá uma mensagem de aviso ou erro, geralmente com o nome dessa assembly.

Namespace.Assembly é o assembly que você suspeita ter o problema de dependência. Normalmente, apenas vincular estaticamente esse assembly fará referência a todas as dependencies de forma transitiva.

Melhor aplicativo que eu vejo e uso, mostra dlls perdidos / problemáticos: http://www.dependencywalker.com/