Come si determinano le dipendenze di un'applicazione .NET?


106

Come si determinano le dipendenze di un'applicazione .NET? Fa Dependency Walker lavoro con le applicazioni gestite? Ho scaricato l'ultima e ho provato a profilare l'app, ma si chiude senza troppe spiegazioni. Se non funziona con .NET, esiste qualche altro strumento che potrebbe aiutarmi a eseguire il debug di un problema di caricamento della DLL in fase di esecuzione?

Risposte:


94

Dependency walker funziona sui normali binari win32. Tutte le DLL e gli exe .NET hanno una piccola parte di intestazione stub che li fa sembrare normali binari, ma tutto ciò che fondamentalmente dice è "carica il CLR" - quindi questo è tutto ciò che il walker delle dipendenze ti dirà.

Per vedere su quali cose si basa effettivamente la tua app .NET, puoi utilizzare l'eccellente riflettore .NET di Red Gate. (EDIT: nota che .NET Reflector è ora un prodotto a pagamento. ILSpy è gratuito, open source e molto simile.)

Carica la tua DLL al suo interno, fai clic con il pulsante destro del mouse e scegli "Analizza": vedrai quindi un elemento "Dipende da" che ti mostrerà tutte le altre DLL (ei metodi all'interno di quelle DLL) di cui ha bisogno.

A volte può diventare più complicato, in quanto la tua app dipende da X dll e X dll è presente, ma per qualsiasi motivo non può essere caricato o individuato in fase di esecuzione.

Per risolvere questi tipi di problemi, Microsoft dispone di un visualizzatore di log di binding di assembly che può mostrarti cosa sta succedendo in fase di esecuzione


Penso che ti sia perso un po 'di quell'URL: il .aspx è stato inserito nel testo del link. Sono riuscito a trovarlo però.
Brian Stewart,

oh ... sì il controllo markdown mangia parentesi negli URL, e sfortunatamente MSDN inserisce (VS80) in tutti gli URL :-(
Orion Edwards

44
Si noti che dall'inizio del 2011 .NET Reflector non è più gratuito. Il progetto ILSpy open source è molto simile.
yo

1
La vista del registro dell'assembly binding v4.0.30319.1 è completamente inutilizzabile. Le voci di registro non vengono visualizzate in ordine cronologico e non è possibile ordinarle. Mostra percorsi che non si adattano al visualizzatore e non è possibile ridimensionarlo. È una completa perdita di tempo.
Neutrino

dependencywalker.com Dovresti includere gli URL delle cose che menzioni, specialmente. se funzionano.
Toddmo

54

Trovo che la piccola utility AsmSpy sia uno strumento inestimabile per la risoluzione dei problemi con il caricamento degli assembly. Elenca tutti i riferimenti agli assembly degli assembly gestiti, comprese le versioni degli assembly.

Eseguilo in un prompt dei comandi nella directory del .dllcon i seguenti argomenti:

asmspy . all

screenshot dell'output di asmspy

Installalo rapidamente con Chocolatey:

choco install asmspy

Può funzionare anche sui file C # o sulle visualizzazioni Razor? Sto creando un sottoprogetto esportando alcune viste e un controller da un progetto mvc in fase di esecuzione. E voglio sapere quali dipendenze sono richieste da queste viste e dal controller in modo da poter copiare queste dipendenze anche in fase di esecuzione per rendere il sottoprogetto pubblicabile come progetto web separato su IIS.
Rupendra

25

Aprire il file di assieme in ILDASM e guardare @ il file .assembly extern nel MANIFEST


1
Posso vedere anche la versione degli assembly dipendenti in questo modo? Vedo solo il nome della dipendenza, non anche la sua versione.
Michael R

In realtà, sì, posso vedere anche la versione degli assembly dipendenti in questo modo, facendo clic su "MANIFES T"
Michael R

1
Preferisco questo - non è necessario scaricare alcuna utilità aggiuntiva se lavori in un ambiente di sviluppo
Dan Field,

Durante il debug di un arresto anomalo di un'app di terze parti, come installare solo ildasm sul cliente di?
realtebo

18

Per esplorare le dipendenze del codice .NET, è possibile utilizzare le funzionalità dello strumento NDepend. Lo strumento propone:

Ad esempio, tale query può essere simile 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 il suo risultato è il seguente: (notare la profondità della metrica del codice , 1 è per i chiamanti diretti, 2 per i chiamanti dei chiamanti diretti ...) (si noti anche il pulsante Esporta in grafico per esportare il risultato della query in un grafico delle chiamate )

Dipendenze che esplorano le dipendenze C # LINQ

Il grafico delle dipendenze ha il seguente aspetto:

Grafico delle dipendenze ND

La matrice delle dipendenze ha il seguente aspetto:

Matrice delle dipendenze ND

La matrice delle dipendenze è di fatto meno intuitiva del grafico, ma è più adatta per esplorare sezioni di codice complesse come:

Matrice NDepend vs Grafico

Disclaimer: lavoro per NDepend


2
Probabilmente Patrick avrebbe dovuto menzionare che è l'autore di quel fantastico strumento;). Vale davvero la pena dare un'occhiata. +1 per averlo scritto!
Mitch Wheat

1
Ehi, l'ho notato anch'io. Mi piace leggere i suoi post sul blog - dovrò provare NDepend!
Brian Stewart

2
@ MitchWheat - il nome controlla ahah, "Patrick del team NDepend"
kayleeFrye_onDeck

Posso usare con VStudio? Per eseguire il debug degli arresti anomali delle app di app di terze parti su un PC diverso dal mio
realtebo

16

Non è necessario scaricare e installare app o strumenti shareware. Puoi farlo in modo programmatico da .NET usandoAssembly.GetReferencedAssemblies()

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

9
A scopo di debug, è più conveniente per farlo tramite PowerShell: [Reflection.Assembly]::LoadFile('C:\absolute\path\to\my.dll').GetReferencedAssemblies(). Ha il bel vantaggio di non scaricare o cercare posizioni oscure di Windows per gli strumenti. +1
jpmc26

3
correggimi se sbaglio ma questo ti darà lo stesso errore che dà la tua applicazione con una dipendenza mancante, quindi non è molto utile
jk.

Funziona solo quando l'assembly viene caricato in un AppDomain. Gli assembly caricati per Reflection restituiscono un set null.
David A. Gray

7

Se stai usando la toolchain Mono, puoi usare l' monodisutilità con l' --assemblyrefargomento per elencare le dipendenze di un assembly .NET. Questo funzionerà su entrambi .exee sui .dllfile.

Utilizzo di esempio:

monodis --assemblyref somefile.exe

Output di esempio (.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

Output di esempio (.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

5

Abilita registrazione binding assembly impostare il valore di registro EnableLog in HKLM \ Software \ Microsoft \ Fusion su 1. Notare che è necessario riavviare l'applicazione (utilizzare iisreset) affinché le modifiche abbiano effetto.

Suggerimento: ricordarsi di disattivare la registrazione della fusione quando si è terminato poiché è previsto un calo delle prestazioni per averlo attivato.


5

È divertente che abbia avuto un problema simile e non ho trovato nulla di adatto ed ero a conoscenza del buon vecchio Dependency Walker, quindi alla fine ne ho scritto uno io stesso.

Questo si occupa specificamente di .NET e mostrerà quali riferimenti ha un assembly (e manca) in modo ricorsivo. Mostrerà anche le dipendenze della libreria nativa.

È gratuito (per uso personale) e disponibile qui per chiunque sia interessato: www.netdepends.com

www.netdepends.com

Feedback benvenuti.


Aggiungere il supporto per il trascinamento della selezione per l'apertura degli assiemi. Sarebbe anche bello se fosse disponibile la distribuzione XCOPY, così come il codice sorgente.
gigaplex

Ho appena notato che il sito web non ha collegamenti evidenti alla sezione in cui ci sono due edizioni e quella gratuita è per uso non commerciale. Mi sono imbattuto accidentalmente in questo trovando l'opzione "Aggiorna a Professional" nel menu Aiuto. Dovrebbe esserci un avviso sulla pagina di download che dice che non è gratuito per uso commerciale.
gigaplex

@gigaplex prenderò nota di entrambi questi ringraziamenti, vedrò cosa posso fare.
Lloyd

1
Fare clic su Maiusc per aprire un albero e anche tutti gli elementi secondari sarebbero utili.
TS

1
Come informarmi su quali sono le dipendenze mancanti?
realtebo

2

http://www.amberfish.net/

ChkAsm ti mostrerà tutte le dipendenze di un particolare assembly contemporaneamente, comprese le versioni, e ti consentirà di cercare facilmente gli assembly nell'elenco. Funziona molto meglio per questo scopo di ILSpy ( http://ilspy.net/ ), che è quello che usavo per questo compito.


1
A partire dal 2019 quel sito sembra essere una sorta di blog dall'aspetto abbozzato ...
McGuireV10

@ McGuireV10 Così è. È un peccato. E un rapido google non trova più risultati per quell'app.
mhenry1384

0

Un altro utile componente aggiuntivo di Reflector che utilizzo è la matrice della struttura delle dipendenze . È davvero fantastico vedere quali classi usano cosa. Inoltre è gratuito.


Non mostra i numeri di versione, sfortunatamente, almeno la versione che si installa come componente aggiuntivo di Visual Studio non lo fa.
mhenry1384

0

Prova a compilare il tuo assembly .NET con l'opzione --staticlink:"Namespace.Assembly". Ciò costringe il compilatore a inserire tutte le dipendenze in fase di compilazione. Se rileva una dipendenza a cui non viene fatto riferimento, verrà visualizzato un messaggio di avviso o di errore in genere con il nome di tale assembly.

Namespace.Assemblyè l'assembly che si sospetta abbia il problema di dipendenza. In genere solo il collegamento statico di questo assembly farà riferimento a tutte le dipendenze in modo transitorio.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.